diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 6a504ba..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,12 +0,0 @@
-   
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index c38e7d7..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-Apache Cordova
-Copyright 2012 The Apache Software Foundation
-
-This product includes software developed by
-The Apache Software Foundation (http://www.apache.org)
\ No newline at end of file
diff --git a/README.md b/README.md
index f1da509..dc69fba 100644
--- a/README.md
+++ b/README.md
@@ -1,53 +1 @@
-###Project has been merged into the [cordova-wp8](https://github.com/apache/cordova-wp8) repository for now.
-
-
-Apache Cordova for Windows Phone 7
-===
-
-Apache Cordova WP7 is a .net application library that lets you create Apache Cordova applications targeting Windows Phone 7 devices.
-Apache Cordova based applications are, at the core, an application written with web technology: HTML, CSS and JavaScript.
-
-Requires
----
-
-- Windows Phone SDK 7.1 [http://create.msdn.com/en-us/home/getting_started]
-
-
-Getting Started
----
-
-- copy the file templates/CordovaStarter-x.x.x.zip to the folder : \My Documents\Visual Studio 2010\Templates\ProjectTemplates\
- - if you have just installed VisualStudio, you should launch it once to create this folder
- - if you prefer, you may add the project instead to the "Silverlight for Windows Phone" subfolder of "Visual C#".  This is up to you, and only affects where the project template is shown when creating a new project. Also, You may need to create this folder.
-- Launch Visual Studio 2010 and select to create a new project
- - CordovaStarter should be listed as an option, give your new project a name
-  - Note: The description will let you know the version of Cordova you are targeting, if you have multiple templates.
- - If you do not see it, you may have to select the top level 'Visual C#' to see it
-- Build and Run it!
-
-Important!!!
----
-
-When you add or remove files/folders in the www folder you will need to do the following :
-
-- ensure the new item is included in the project ( Content ) This includes ALL images/css/html/js/* and anything that you want available at runtime.
-- Do not modify the CordovaSourceDictionary.xml file which is included in the project, it is auto-generated for you when you build.
-
-Known Problem Areas
----
-
-Many of the Media APIs will not function as expected when debugging while connect to the device with the Zune software.
-To get around this, you need to use the Windows Phone Connect tool. For details, please check out this [MSDN blog article](http://blogs.msdn.com/b/jaimer/archive/2010/11/03/tips-for-debugging-wp7-media-apps-with-wpconnect.aspx).
-
-
-BUGS?
------
-File them at Apache Incubator
-https://issues.apache.org/jira/browse/CB
-
-
-Further Reading
----
-
-- [http://docs.cordova.io](http://docs.cordova.io)
-- [http://wiki.cordova.io](http://wiki.cordova.io)
+###Project has now been merged into the [cordova-wp8](https://github.com/apache/cordova-wp8) repository.
\ No newline at end of file
diff --git a/VERSION b/VERSION
deleted file mode 100644
index c8e38b6..0000000
--- a/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-2.9.0
diff --git a/bin/check_reqs b/bin/check_reqs
deleted file mode 100755
index d1b9bc0..0000000
--- a/bin/check_reqs
+++ /dev/null
@@ -1,24 +0,0 @@
-#! /bin/sh
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-echo "ERROR: Cordova tooling for Windows Phone requires a Windows OS with the 'msbuild' command "
-echo " in the PATH environment variable as well as having .NET Framework 4.0 (from WP SDK's)"
-exit 1
\ No newline at end of file
diff --git a/bin/check_reqs.bat b/bin/check_reqs.bat
deleted file mode 100644
index 26e7393..0000000
--- a/bin/check_reqs.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%check_reqs.js (
-        cscript "%full_path%check_reqs.js" %* //nologo
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find 'check_reqs.js' in 'bin' folder, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/bin/check_reqs.js b/bin/check_reqs.js
deleted file mode 100644
index 3dc1496..0000000
--- a/bin/check_reqs.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-var args = WScript.Arguments;
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-
-var REQUIRE_GIT = false;
-
-function Usage() {
-    Log("Usage: [ check_reqs | cscript check_reqs.js ]");
-    Log("examples:");
-    Log("    cscript C:\\Users\\anonymous\\cordova-wp7\\bin\\check_reqs.js");
-    Log("    CordovaWindowsPhone\\bin\\check_reqs");
-
-}
-
-// log to stdout or stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// gets the output from a command, failing with the given error message
-function check_command(cmd, fail_msg) {
-    var out = wscript_shell.Exec(cmd);
-    while (out.Status == 0) {
-        WScript.Sleep(100);
-    }
-
-    //Check that command executed 
-    if (!out.StdErr.AtEndOfStream) {
-        var line = out.StdErr.ReadLine();
-        Log(fail_msg, true);
-        Log('Output : ' + line, true);
-        WScript.Quit(1);
-    }
-
-    if (!out.StdOut.AtEndOfStream) {
-        var line = out.StdOut.ReadAll();
-        return line;
-    }
-    else {
-         Log('Unable to get output from command "' + cmd + '"', true);
-         WScript.Quit(1);
-    }
-}
-
-/* The tooling for cordova windows phone requires these commands
- *  in the environment PATH variable.
- * - msbuild (C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319)
- * - git? (for dynamic cli loading of projects?)
- */
-function SystemRequiermentsMet() {
-    var cmd = 'msbuild -version'
-    var fail_msg = 'The command `msbuild` failed. Make sure you have the latest Windows Phone SDKs installed, and the `msbuild.exe` command (inside C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319) is added to your path.'
-    var output = check_command(cmd, fail_msg);
-    var msversion = output.match(/\.NET\sFramework\,\sversion\s4\.0/);
-    if (!msversion) {
-        Log('Please install the .NET Framwork v4.0.30319 (in the latest windows phone SDK\'s).', true);
-        Log('Make sure the "msbuild" command in your path is pointing to  v4.0.30319 of msbuild as well (inside C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319).', true);
-        WScript.Quit(1);
-    }
-
-    if(REQUIRE_GIT) {
-        cmd = 'git --version';
-        fail_msg = 'The command `git` failed. Make sure you have git installed as well ad in your PATH environment so the tool can use it';
-        output = check_command(cmd, fail_msg);
-        var gitVersion = output.match(/git\sversion\s1\./);
-        if (!gitVersion) {
-            Log('Please ensure you have at least git v1 installed and added to you PATH so this tool can use it to get the latest codova.');
-        }
-    }
-}
-
-
-if (args.Count() > 0) {
-    // support help flags
-    if (args(0) == "--help" || args(0) == "/?" ||
-            args(0) == "help" || args(0) == "-help" || args(0) == "/help" || args(0) == "-h") {
-        Usage();
-        WScript.Quit(1);
-    }
-    else {
-        Log('Error : Did not recognize argument ' + args(0), true)
-        Usage();
-        WScript.Quit(1);
-    }
-}
-
-SystemRequiermentsMet();
\ No newline at end of file
diff --git a/bin/create.bat b/bin/create.bat
deleted file mode 100644
index 329048e..0000000
--- a/bin/create.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%create.js (
-        cscript "%full_path%create.js" %* //nologo
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find 'create.js' in 'bin' folder, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/bin/create.js b/bin/create.js
deleted file mode 100644
index 93236f8..0000000
--- a/bin/create.js
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-/*
- * create a cordova/wp7 project
- *
- * USAGE
- *  ./create [path package activity]
-
-    ./bin/create.bat C:\Users\Me\MyTestProj "test.proj" "TestProject"
- */
-
-
-var fso=WScript.CreateObject("Scripting.FileSystemObject");
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\bin\\create.js').join('');
-
-var args = WScript.Arguments,
-    FRAMEWORK_PATH = '\\framework',
-    TOOLING_PATH = '\\tooling',
-    TEMPLATES_PATH = '\\templates',
-    // sub folder for standalone project
-    STANDALONE_PATH = TEMPLATES_PATH + '\\standalone',
-    // default template to use when creating the project
-    CREATE_TEMPLATE = STANDALONE_PATH,
-    USE_DLL = false,
-    PROJECT_PATH, 
-    PACKAGE, 
-    NAME;
-
-    // get version number
-var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
-var BASE_VERSION = VERSION.split('rc', 1) + ".0";
-
-function Usage() {
-    Log("Usage: create PathTONewProject [ PackageName AppName ]");
-    Log("    PathTONewProject : The path to where you wish to create the project");
-    Log("    PackageName      : The namespace for the project (default is Cordova.Example)")
-    Log("    AppName          : The name of the application (default is CordovaAppProj)");
-    Log("examples:");
-    Log("    create C:\\Users\\anonymous\\Desktop\\MyProject");
-    Log("    create C:\\Users\\anonymous\\Desktop\\MyProject io.Cordova.Example AnApp");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-var ForReading = 1, ForWriting = 2, ForAppending = 8;
-var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
-
-function read(filename) {
-    var f=fso.OpenTextFile(filename, 1,2);
-    var s=f.ReadAll();
-    f.Close();
-    return s;
-}
-
-function write(filename, contents) {
-    var f=fso.OpenTextFile(filename, ForWriting, TristateTrue);
-    f.Write(contents);
-    f.Close();
-}
-
-function replaceInFile(filename, regexp, replacement) {
-    write(filename,read(filename).replace(regexp,replacement));
-}
-
-
-// executes a commmand in the shell
-function exec(command) {
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status == 0) {
-        WScript.sleep(100);
-    }
-}
-
-// executes a commmand in the shell
-function exec_verbose(command) {
-    //Log("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status == 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if (!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadLine();
-            Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if (!oShell.StdErr.AtEndOfStream) {
-        var line = oShell.StdErr.ReadAll();
-        Log(line, true);
-        WScript.Quit(1);
-    }
-}
-
-//generate guid for the project
-function genGuid() {
-    var TypeLib = WScript.CreateObject("Scriptlet.TypeLib");
-    strGuid = TypeLib.Guid.split("}")[0]; // there is extra crap after the } that is causing file streams to break, probably an EOF ... 
-    strGuid = strGuid.replace(/[\{\}]/g,""); 
-    return strGuid;
-}
-
-// builds the new cordova dll from the framework
-function build_dll(path) {
-    if (fso.FolderExists(path + FRAMEWORK_PATH + '\\Bin')) {
-        fso.DeleteFolder(path + FRAMEWORK_PATH + '\\Bin');
-    }
-    if (fso.FolderExists(path + FRAMEWORK_PATH + '\\obj')) {
-        fso.DeleteFolder(path + FRAMEWORK_PATH + '\\obj');
-    }
-    // move to framework directory
-    wscript_shell.CurrentDirectory = path + FRAMEWORK_PATH;
-    // build .dll in Release
-    exec_verbose('msbuild /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Release;VersionNumber=' + VERSION + ';BaseVersionNumber=' + BASE_VERSION);
-    //Check if file dll was created
-    if (!fso.FileExists(path + FRAMEWORK_PATH + '\\Bin\\Release\\WPCordovaClassLib.dll')) {
-        Log('ERROR: MSBuild failed to create .dll when building WPCordovaClassLib.dll', true);
-        WScript.Quit(1);
-    }
-    Log("SUCCESS BUILDING DLL");
-}
-
-// creates new project in path, with the given package and app name
-function create(path, namespace, name) {
-    Log("Creating Cordova-WP7 Project:");
-    Log("\tApp Name : " + name);
-    Log("\tNamespace : " + namespace);
-    Log("\tPath : " + path);
-
-    // Copy the template source files to the new destination
-    fso.CopyFolder(ROOT + CREATE_TEMPLATE, path);
-
-    var newProjGuid = genGuid();
-    // replace the guid in the AppManifest
-    replaceInFile(path + "\\Properties\\WMAppManifest.xml","$guid1$",newProjGuid);
-    // replace safe-project-name in AppManifest
-    replaceInFile(path + "\\Properties\\WMAppManifest.xml",/\$safeprojectname\$/g,name);
-    replaceInFile(path + "\\Properties\\WMAppManifest.xml",/\$projectname\$/g,name);
-
-
-    replaceInFile(path + "\\App.xaml",/\$safeprojectname\$/g,namespace);
-    replaceInFile(path + "\\App.xaml.cs",/\$safeprojectname\$/g,namespace);
-
-    replaceInFile(path + "\\MainPage.xaml",/\$safeprojectname\$/g,namespace);
-    replaceInFile(path + "\\MainPage.xaml.cs",/\$safeprojectname\$/g,namespace);
-    replaceInFile(path + "\\CordovaAppProj.csproj",/\$safeprojectname\$/g,namespace);
-    if (name != "CordovaAppProj") {
-        var valid_name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
-        replaceInFile(path + "\\CordovaSolution.sln", /CordovaAppProj/g, valid_name);
-        // rename project and solution
-        exec('%comspec% /c ren ' + path + "\\CordovaSolution.sln " + valid_name + '.sln');
-        exec('%comspec% /c ren ' + path + "\\CordovaAppProj.csproj " + valid_name + '.csproj');
-    }
-
-    //copy .dll if necessary
-    if (USE_DLL) {
-        var dllPath = ROOT + FRAMEWORK_PATH + '\\Bin\\Release\\WPCordovaClassLib.dll';
-        if (fso.FileExists(dllPath)) {
-            Log("WPCordovaClassLib.dll Found,  creating project");
-        }
-        else {
-            Log("WPCordovaClassLib.dll was not Found in " + dllPath);
-            Log('BUILDING: WPCordovaClassLib.dll');
-            build_dll(ROOT);
-        }
-
-        if (!fso.FolderExists(path + '\\CordovaLib')) {
-            fso.CreateFolder(path + '\\CordovaLib');
-        }
-        exec('%comspec% /c xcopy ' + ROOT + FRAMEWORK_PATH + '\\Bin\\Release\\WPCordovaClassLib.dll ' + path + '\\CordovaLib');
-        if (!fso.FileExists(path + '\\CordovaLib\\WPCordovaClassLib.dll')) {
-            Log('ERROR: Failed to copy WPCordovaClassLib.dll to project from', true);
-            Log('\t' + ROOT + FRAMEWORK_PATH + '\\Bin\\Release\\WPCordovaClassLib.dll', true);
-            Log('\tto', true);
-            Log('\t' + path + '\\CordovaLib', true)
-            WScript.Quit(1);
-        }
-    }
-
-    //clean up any Bin/obj or other generated files
-    exec('cscript ' + path + '\\cordova\\lib\\clean.js //nologo');
-
-    // delete any .user and .sou files if any
-    if (fso.FolderExists(path)) {
-        var proj_folder = fso.GetFolder(path);
-        var proj_files = new Enumerator(proj_folder.Files);
-        for (;!proj_files.atEnd(); proj_files.moveNext()) {
-            if (fso.GetExtensionName(proj_files.item()) == 'user') {
-                fso.DeleteFile(proj_files.item());
-            } else if (fso.GetExtensionName(proj_files.item()) == 'sou') {
-                fso.DeleteFile(proj_files.item());
-            }
-        }
-    }
-
-    Log("CREATE SUCCESS : " + path);
-
-    // TODO:
-    // index.html title set to project name?
-}
-
-
-
-if (args.Count() > 0) {
-    // support help flags
-    if (args(0) == "--help" || args(0) == "/?" ||
-            args(0) == "help" || args(0) == "-help" || args(0) == "/help" || args(0) == "-h") {
-        Usage();
-        WScript.Quit(1);
-    }
-
-    PROJECT_PATH = args(0);
-    if (fso.FolderExists(PROJECT_PATH)) {
-        Log("Project directory already exists:", true);
-        Log("\t" + PROJECT_PATH, true);
-        Log("CREATE FAILED.", true);
-        WScript.Quit(1);
-    }
-
-    if (args.Count() > 1) {
-        PACKAGE = args(1);
-    }
-    else {
-        PACKAGE = "Cordova.Example";
-    }
-
-    if (args.Count() > 2) {
-        NAME = args(2);
-    }
-    else {
-        NAME = "CordovaAppProj";
-    }
-
-    create(PROJECT_PATH, PACKAGE, NAME);
-}
-else {
-    Usage();
-    WScript.Quit(1);
-}
-
diff --git a/bin/update.bat b/bin/update.bat
deleted file mode 100644
index 9da7e3c..0000000
--- a/bin/update.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%update.js (
-        cscript "%full_path%update.js" %* //nologo
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find 'update.js' in 'bin' folder, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/bin/update.js b/bin/update.js
deleted file mode 100644
index 8ea38a8..0000000
--- a/bin/update.js
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var fso           = WScript.CreateObject("Scripting.FileSystemObject");
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-var shell         = WScript.CreateObject("shell.application");
-var args          = WScript.Arguments;
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\bin\\update.js').join('');
-//Get version number
-var VERSION = read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
-var plugins_folder = "\\Plugins";
-var template_folder = "\\templates\\standalone";
-// anything thats missing to the project
-var overwrite = false;
-var replace = false;
-
-// usage function
-function Usage() {
-    Log("WARNING : Make sure to back up your project before updating!")
-    Log("Usage: update Path-To-Project ");//[ -f | -r ] ");
-    Log("    Path-To-Old-Project : The path the project you would like to update.");
-    //Log("                     -f : Will forcefully overwrite and add all core components of the application.");
-    //Log("                     -r : Will create an updated project, only keeping the www assets. *NOTE: no native code will be preserved*");
-    Log("examples:");
-    Log("    update C:\\Users\\anonymous\\Desktop\\MyProject");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// executes a commmand in the shell
-function exec(command) {
-    //Log("Command : " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        WScript.sleep(100);
-    }
-}
-
-// executes a commmand in the shell
-function exec_verbose(command) {
-    Log("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status == 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if (!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadAll();
-            Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if (!oShell.StdErr.AtEndOfStream) {
-        var line = oShell.StdErr.ReadAll();
-        Log(line, true);
-        WScript.Quit(2);
-    }
-}
-
-var ForReading = 1, ForWriting = 2, ForAppending = 8;
-var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
-
-// returns the contents of a file
-function read(filename) {
-    if (fso.FileExists(filename)) {
-        var f=fso.OpenTextFile(filename, 1, 2);
-        var s=f.ReadAll();
-        f.Close();
-        return s;
-    }
-    else {
-        Log('Cannot read non-existant file : ' + filename, true);
-        WScript.Quit(2);
-    }
-    return null;
-}
-
-// writes the contents to the specified file
-function write(filename, contents) {
-    var f=fso.OpenTextFile(filename, ForWriting, TristateTrue);
-    f.Write(contents);
-    f.Close();
-}
-
-// replaces the matches of regexp with replacement
-function replaceInFile(filename, regexp, replacement) {
-    var text = read(filename).replace(regexp,replacement);
-    write(filename,text);
-}
-
-// returns true if the given path is the root of a cordova windows phone project
-// currently returns true if the folder contains a .csproj file.
-function is_windows_phone_project(path) {
-    if (fso.FolderExists(path)) {
-        var proj_folder = fso.GetFolder(path);
-        var proj_files = new Enumerator(proj_folder.Files);
-        for (;!proj_files.atEnd(); proj_files.moveNext()) {
-            if (fso.GetExtensionName(proj_files.item()) == 'csproj') {
-                return true;  
-            }
-        }
-    }
-    return false;
-}
-
-// returns the name of the application
-function get_app_name(path) {
-    var WMAppManifest = read(path + '\\Properties\\WMAppManifest.xml').split('\n');
-    for (line in WMAppManifest) {
-        if (WMAppManifest[line].match(/Title\=\"/)) {
-            return WMAppManifest[line].split('Title="')[1].split('"')[0];
-        }
-    }
-    Log("Error : unable to find applicaiton name in the project.", true);
-    Log(" Path : " + path, true);
-    WScript.Quit(2);
-}
-
-// returns the name of the application package
-function get_package_name(path) {
-    var WMAppManifest = read(path + '\\Properties\\WMAppManifest.xml').split('\n');
-    for (line in WMAppManifest) {
-        if (WMAppManifest[line].match(/Title\=\"/)) {
-            return WMAppManifest[line].split('Title="')[1].split('"')[0];
-        }
-    }
-    Log("Error : unable to find applicaiton name in the project.", true);
-    Log(" Path : " + path, true);
-    WScript.Quit(2);
-}
-
-// returns the GUID ame of the application
-function get_app_GUID(path) {
-    var AppXAML = read(path + '\\App.xaml').split('\n');
-    for (line in AppXAML) {
-        if (AppXAML[line].match(/x\:Class\=\"/)) {
-            return AppXAML[line].split('Class="')[1].split('"')[0];
-        }
-    }
-    Log("Error : unable to find package name in the project.", true);
-    Log(" Path : " + path, true);
-    WScript.Quit(2);
-}
-
-// updates the cordova.js and all references in the given project with this repositories version
-function update_cordova_js(path) {
-    // remove old cordova.js
-    var www_contents = shell.NameSpace(path + '\\www').Items();
-    for(i = 0; i < www_contents.Count; i++)
-    {
-        if(www_contents.Item(i).Name.match(/cordova\-(\d+)[.](\d+)[.](\d+)(rc\d)?[.]js/))
-        {
-            fso.DeleteFile(path + '\\www\\' + www_contents.Item(i).Name);
-        }
-    }
-    // update version file
-    copy_to(ROOT + "\\VERSION",  path + "\\VERSION");
-    // copy over new cordova.js
-    copy_to(ROOT + template_folder + "\\www\\cordova.js", path + "\\www\\cordova.js");
-
-    // update corodva references
-    var cordova_regex = /cordova-(\d+)[.](\d+)[.](\d+)(rc\d)?/g; //Matches *first* cordova-x.x.x[rcx] (just ad g at end to make global)
-    // update references in index.html
-    replaceInFile(path + '\\www\\index.html', cordova_regex,  "cordova");
-    version_regex = /return\s*\"(\d+)[.](\d+)[.](\d+)(rc\d)?/; //Matches return "x.x.x[rcx]
-    // update references in Device.cs
-    replaceInFile(path + '\\Plugins\\Device.cs', version_regex,  "return \"" + VERSION);
-}
-
-// Copies assets that need to be saved from source to desination.
-// TODO : Add all critical assets here
-function save_restore(source, destination) {
-    fso.CreateFolder(destination + '\\www');
-    copy_to(source + '\\www', destination + '\\www');
-    copy_to(source + '\\SplashScreenImage.jpg', destination + '\\SplashScreenImage.jpg');
-    copy_to(source + '\\Background.png', destination + '\\Background.png');
-    copy_to(source + '\\ApplicationIcon.png', destination + '\\ApplicationIcon.png');
-    copy_to(source + '\\config.xml', destination + '\\config.xml');
-}
-
-// deletes the path element if it exists
-function delete_if_exists(path) {
-    if (fso.FolderExists(path)) {
-        fso.DeleteFolder(path);
-    }
-    else if (fso.FileExists(path)) {
-        fso.DeleteFile(path);
-    }
-}
-
-// copies a folder or file from source to destination
-function copy_to(source, destination) {
-    // check that source exists
-    if (!fso.FolderExists(source)) {
-        if (!fso.FileExists(source)) {
-            Log("Error : Could not copy file/folder because it doesn't exist.", true);
-            Log("      File/Folder : " + source, true);
-            WScript.Quit(2);
-        }
-    }
-    // if source is a folder, then copy all folder contents
-    if (fso.FolderExists(source)) {
-        fso.CopyFolder(source, destination, true);
-    } 
-    // if it's a file, just copy it.
-    else { 
-        exec('%comspec% /c copy /Y /V ' + source + ' ' + destination);
-    }
-}
-
-// updates the cordova.js in project along with the cordova tooling.
-function update_project(path) {
-    // update cordova folder
-    delete_if_exists(path + '\\cordova');
-    fso.CreateFolder(path + '\\cordova');
-    copy_to(ROOT + template_folder + '\\cordova', path + '\\cordova');
-    // clean project (all generated files)
-    exec(path + '\\cordova\\clean.bat');
-
-    // update core cordovalib
-    delete_if_exists(path + '\\cordovalib');
-    fso.CreateFolder(path + '\\cordovalib');
-    copy_to(ROOT + template_folder + '\\cordovalib', path + '\\cordovalib');
-
-    // update core plugins
-    // TODO : Remove for 3.0.0
-    delete_if_exists(path + '\\Plugins');
-    fso.CreateFolder(path + '\\Plugins');
-    copy_to(ROOT + template_folder + '\\Plugins', path + '\\Plugins');
-
-    // update cordova.js
-    update_cordova_js(path);
-}
-
-// Replaces the current project with a newly created project, keeping important assets to preserve the app.
-// TODO: Things that need to be kept other then www
-// - WMAppManifest (capabilities etc...)
-// - GUID (for marketplace apps etc...)
-// - Splashscreen and other images etc...
-// - Find more things that should be kept
-function replace_project(path) {
-    //create new project and move www assets into it.
-    Log("WARNING : Upgrading your app with the \'-r\' flag will delete all native and plugin");
-    Log(" components of your application and replace them with the updated core components given");
-    Log(" by this platforms \'bin\\create\' script.  It is *HIGHLY RECOMMENDED* to back up your app");
-    Log(" before continuing. The name and package name along with all of the www assets will be");
-    Log(" preserved. Are you sure you wish to continue? (Y/N)");
-    var response;
-    while (response != 'Y') {
-        response = WScript.StdIn.ReadLine();
-        if (response == 'N') {
-            WScript.Quit(2);
-        } else if (response != "Y") {
-            Log("Error :  did not recognize '" + response + "'");
-            Log("Are you sure you wish to continue? (Y/N)");
-        }
-    }
-    // place all assets to be preserved in a temperary folder
-    delete_if_exists(ROOT + '\\temp');
-    fso.CreateFolder(ROOT + '\\temp');
-    save_restore(path, ROOT + '\\temp');
-
-    // get app name from WMAppManifest
-    var app_name = get_app_name(path);
-    // get package name from App.xaml
-    var package_name = get_package_name(path);
-    // get the GUID so that app stays the same
-    var app_GUID = get_app_GUID(path);
-    // delete previous project
-    delete_if_exists(path);
-    // create the new project from the current repository
-    exec(ROOT + '\\bin\\create.bat ' + path + ' ' + app_name + ' ' + package_name);
-    // remove default www assets
-    delete_if_exists(path + '\\www');
-    // move www assets back to project folder
-    save_restore(ROOT + '\\temp', path);
-    // cleanup temp folder
-    delete_if_exists(ROOT + '\\temp');
-}
-
-
-
-if (args.Count() > 0) {
-    if(args.Count() > 2) {
-        Log("Error : too many arguments provided.", true);
-        WScript.Quit(1);
-    }
-
-    if (args(0).indexOf("--help") > -1 ||
-          args(0).indexOf("/?") > -1 ) {
-        Usage();
-        WScript.Quit(1);
-    }
-    else if (fso.FolderExists(args(0)) && is_windows_phone_project(args(0))) {
-        if(args.Count() > 1) {
-            /*if(args(1) == '-f' || args(1) == '--force') {
-                //TODO: do something for this
-                Log("ERROR : NOT IMPLEMENTED", true);
-                WScript.Quit(2);
-            }
-            else if(args(1) == '-r' || args(1) == '--replace') {
-                replace_project(args(0));
-            }
-            else {
-                Log('Error : \'' + args(1) + '\' is not regognized as an update option', true);
-            }*/
-            Usage();
-            Log('Error : too many arguments', true);
-        } else if (args.Count() == 1) {
-            update_project(args(0));
-        }
-    }
-    else if (fso.FolderExists(args(0))) {
-        Log("The path provided is not a path to a cordova windows phone project.", true);
-        Log(" Please provide the path to the root folder of your cordova windows phone project.", true);
-        WScript.Quit(2);
-    }
-    else {
-        Log("The given path to the project does not exist.", true);
-        Log(" Please provide a path to the project you would like to update.", true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
-else {
-    Usage();
-    WScript.Quit(1);
-}
\ No newline at end of file
diff --git a/framework/Images/appbar.back.rest.png b/framework/Images/appbar.back.rest.png
deleted file mode 100644
index 4bc2b92..0000000
--- a/framework/Images/appbar.back.rest.png
+++ /dev/null
Binary files differ
diff --git a/framework/Images/appbar.close.rest.png b/framework/Images/appbar.close.rest.png
deleted file mode 100644
index 8166a1c..0000000
--- a/framework/Images/appbar.close.rest.png
+++ /dev/null
Binary files differ
diff --git a/framework/Images/appbar.feature.video.rest.png b/framework/Images/appbar.feature.video.rest.png
deleted file mode 100644
index baff565..0000000
--- a/framework/Images/appbar.feature.video.rest.png
+++ /dev/null
Binary files differ
diff --git a/framework/Images/appbar.next.rest.png b/framework/Images/appbar.next.rest.png
deleted file mode 100644
index ed577d7..0000000
--- a/framework/Images/appbar.next.rest.png
+++ /dev/null
Binary files differ
diff --git a/framework/Images/appbar.save.rest.png b/framework/Images/appbar.save.rest.png
deleted file mode 100644
index d49940e..0000000
--- a/framework/Images/appbar.save.rest.png
+++ /dev/null
Binary files differ
diff --git a/framework/Images/appbar.stop.rest.png b/framework/Images/appbar.stop.rest.png
deleted file mode 100644
index 4dd724f..0000000
--- a/framework/Images/appbar.stop.rest.png
+++ /dev/null
Binary files differ
diff --git a/framework/Properties/AssemblyInfo.cs b/framework/Properties/AssemblyInfo.cs
deleted file mode 100644
index 84143db..0000000
--- a/framework/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-﻿using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("WPCordovaClassLib")]
-[assembly: AssemblyDescription("2.9.0")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Apache Cordova")]
-[assembly: AssemblyProduct("WPCordovaClassLib")]
-[assembly: AssemblyCopyright("")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("633ee7ad-9a75-4b68-96e9-281528c50275")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers 
-// by using the '*' as shown below:
-
-[assembly: AssemblyVersion("2.9.0.0")]
-[assembly: AssemblyFileVersion("2.6.0rc1")]
-
diff --git a/framework/WPCordovaClassLib.csproj b/framework/WPCordovaClassLib.csproj
deleted file mode 100644
index b8f76ae..0000000
--- a/framework/WPCordovaClassLib.csproj
+++ /dev/null
@@ -1,297 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
--->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.20506</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{FC6A1A70-892D-46AD-9E4A-9793F72AF780}</ProjectGuid>
-    <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>WPCordovaClassLib</RootNamespace>
-    <AssemblyName>WPCordovaClassLib</AssemblyName>
-    <AssemblyVersion>$(BaseVersionNumber)</AssemblyVersion>
-    <AssemblyFileVersion>$(VersionNumber)</AssemblyFileVersion>
-    <AssemblyDescription>$(VersionNumber)</AssemblyDescription>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
-    <TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>
-    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
-    <SilverlightApplication>false</SilverlightApplication>
-    <ValidateXaml>true</ValidateXaml>
-    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>Bin\Debug</OutputPath>
-    <DefineConstants>TRACE;DEBUG;SILVERLIGHT;WINDOWS_PHONE;CORDOVA_CLASSLIB</DefineConstants>
-    <NoStdLib>true</NoStdLib>
-    <NoConfig>true</NoConfig>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>Bin\Release</OutputPath>
-    <DefineConstants>TRACE;DEBUG;SILVERLIGHT;WINDOWS_PHONE;CORDOVA_CLASSLIB</DefineConstants>
-    <NoStdLib>true</NoStdLib>
-    <NoConfig>true</NoConfig>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <DocumentationFile>
-    </DocumentationFile>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Microsoft.Devices.Sensors" />
-    <Reference Include="Microsoft.Phone" />
-    <Reference Include="Microsoft.Phone.Interop" />
-    <Reference Include="Microsoft.Xna.Framework" />
-    <Reference Include="System.Device" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Servicemodel" />
-    <Reference Include="System.Servicemodel.Web" />
-    <Reference Include="System.Windows" />
-    <Reference Include="system" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Net" />
-    <Reference Include="System.Xml.Linq" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\templates\standalone\cordovalib\BaseCommand.cs">
-      <Link>CordovaLib\BaseCommand.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\BrowserMouseHelper.cs">
-      <Link>CordovaLib\BrowserMouseHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CommandFactory.cs">
-      <Link>CordovaLib\CommandFactory.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ConfigHandler.cs">
-      <Link>CordovaLib\ConfigHandler.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CordovaCommandCall.cs">
-      <Link>CordovaLib\CordovaCommandCall.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CordovaView.xaml.cs">
-      <Link>CordovaLib\CordovaView.xaml.cs</Link>
-      <DependentUpon>CordovaView.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\DOMStorageHelper.cs">
-      <Link>CordovaLib\DOMStorageHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ImageExifHelper.cs">
-      <Link>CordovaLib\ImageExifHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\JSON\JsonHelper.cs">
-      <Link>CordovaLib\JSON\JsonHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\NativeExecution.cs">
-      <Link>CordovaLib\NativeExecution.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\OrientationHelper.cs">
-      <Link>CordovaLib\OrientationHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\PluginResult.cs">
-      <Link>CordovaLib\PluginResult.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ScriptCallback.cs">
-      <Link>CordovaLib\ScriptCallback.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Accelerometer.cs">
-      <Link>CordovaLib\Plugins\Accelerometer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\AudioFormatsHelper.cs">
-      <Link>CordovaLib\Plugins\AudioFormatsHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\AudioPlayer.cs">
-      <Link>CordovaLib\Plugins\AudioPlayer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Battery.cs">
-      <Link>CordovaLib\Plugins\Battery.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Camera.cs">
-      <Link>CordovaLib\Plugins\Camera.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Capture.cs">
-      <Link>CordovaLib\Plugins\Capture.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Compass.cs">
-      <Link>CordovaLib\Plugins\Compass.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Contacts.cs">
-      <Link>CordovaLib\Plugins\Contacts.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\DebugConsole.cs">
-      <Link>CordovaLib\Plugins\DebugConsole.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Device.cs">
-      <Link>CordovaLib\Plugins\Device.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\File.cs">
-      <Link>CordovaLib\Plugins\File.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\FileTransfer.cs">
-      <Link>CordovaLib\Plugins\FileTransfer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\GeoLocation.cs">
-      <Link>CordovaLib\Plugins\GeoLocation.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Globalization.cs">
-      <Link>CordovaLib\Plugins\Globalization.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\InAppBrowser.cs">
-      <Link>CordovaLib\Plugins\InAppBrowser.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Media.cs">
-      <Link>CordovaLib\Plugins\Media.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\MimeTypeMapper.cs">
-      <Link>CordovaLib\Plugins\MimeTypeMapper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\NetworkStatus.cs">
-      <Link>CordovaLib\Plugins\NetworkStatus.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Notification.cs">
-      <Link>CordovaLib\Plugins\Notification.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\AudioCaptureTask.cs">
-      <Link>CordovaLib\Plugins\UI\AudioCaptureTask.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\AudioRecorder.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\AudioRecorder.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\ImageCapture.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\ImageCapture.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\NotificationBox.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\NotificationBox.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\VideoCaptureTask.cs">
-      <Link>CordovaLib\Plugins\UI\VideoCaptureTask.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\VideoRecorder.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\VideoRecorder.xaml.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="..\templates\standalone\cordovalib\resources\notification-beep.wav">
-      <Link>CordovaLib\resources\notification-beep.wav</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.back.rest.png">
-      <Link>CordovaLib\Images\appbar.back.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.close.rest.png">
-      <Link>CordovaLib\Images\appbar.close.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.feature.video.rest.png">
-      <Link>CordovaLib\Images\appbar.feature.video.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.next.rest.png">
-      <Link>CordovaLib\Images\appbar.next.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.save.rest.png">
-      <Link>CordovaLib\Images\appbar.save.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.stop.rest.png">
-      <Link>CordovaLib\Images\appbar.stop.rest.png</Link>
-    </Content>
-    <Content Include="Images\appbar.back.rest.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Images\appbar.close.rest.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Images\appbar.feature.video.rest.png">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Images\appbar.next.rest.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Images\appbar.stop.rest.png">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Images\appbar.save.rest.png">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </Content>
-  </ItemGroup>
-  <ItemGroup>
-    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Resource Include="resources\notification-beep.wav" />
-  </ItemGroup>
-  <ItemGroup>
-    <Page Include="..\templates\standalone\cordovalib\CordovaView.xaml">
-      <Link>CordovaLib\CordovaView.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\AudioRecorder.xaml">
-      <Link>CordovaLib\Plugins\UI\AudioRecorder.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\ImageCapture.xaml">
-      <Link>CordovaLib\Plugins\UI\ImageCapture.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\NotificationBox.xaml">
-      <Link>CordovaLib\Plugins\UI\NotificationBox.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\VideoRecorder.xaml">
-      <Link>CordovaLib\Plugins\UI\VideoRecorder.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-  </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
-  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
-  <ProjectExtensions />
-  <PropertyGroup>
-    <PreBuildEvent>
-    </PreBuildEvent>
-  </PropertyGroup>
-  <PropertyGroup>
-    <PostBuildEvent>
-    </PostBuildEvent>
-  </PropertyGroup>
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-    <AssemblyInfo
-      AssemblyVersion="$(BaseVersion)"
-      AssemblyFileVersion="$(BaseVersion)"
-      AssemblyDescription="$(VersionNumber)"
-    >
-    </AssemblyInfo>
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>-->
-</Project>
\ No newline at end of file
diff --git a/framework/WPCordovaClassLib.sln b/framework/WPCordovaClassLib.sln
deleted file mode 100644
index 2d5e088..0000000
--- a/framework/WPCordovaClassLib.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-﻿
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPCordovaClassLib", "WPCordovaClassLib.csproj", "{FC6A1A70-892D-46AD-9E4A-9793F72AF780}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{FC6A1A70-892D-46AD-9E4A-9793F72AF780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{FC6A1A70-892D-46AD-9E4A-9793F72AF780}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{FC6A1A70-892D-46AD-9E4A-9793F72AF780}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{FC6A1A70-892D-46AD-9E4A-9793F72AF780}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/framework/resources/notification-beep.wav b/framework/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
--- a/framework/resources/notification-beep.wav
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/App.xaml b/templates/standalone/App.xaml
deleted file mode 100644
index 18072fe..0000000
--- a/templates/standalone/App.xaml
+++ /dev/null
@@ -1,37 +0,0 @@
-﻿<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
--->
-<Application 
-    x:Class="$safeprojectname$.App"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
-    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">
-
-    <!--Application Resources-->
-    <Application.Resources>
-    </Application.Resources>
-
-    <Application.ApplicationLifetimeObjects>
-        <!--Required object that handles lifetime events for the application-->
-        <shell:PhoneApplicationService 
-            Launching="Application_Launching" Closing="Application_Closing" 
-            Activated="Application_Activated" Deactivated="Application_Deactivated"/>
-    </Application.ApplicationLifetimeObjects>
-
-</Application>
diff --git a/templates/standalone/App.xaml.cs b/templates/standalone/App.xaml.cs
deleted file mode 100644
index 2b7306d..0000000
--- a/templates/standalone/App.xaml.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-﻿/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-
-namespace $safeprojectname$
-{
-    public partial class App : Application
-    {
-        /// <summary>
-        /// Provides easy access to the root frame of the Phone Application.
-        /// </summary>
-        /// <returns>The root frame of the Phone Application.</returns>
-        public PhoneApplicationFrame RootFrame { get; private set; }
-
-        /// <summary>
-        /// Constructor for the Application object.
-        /// </summary>
-        public App()
-        {
-            // Global handler for uncaught exceptions. 
-            UnhandledException += Application_UnhandledException;
-
-            // Show graphics profiling information while debugging.
-            if (System.Diagnostics.Debugger.IsAttached)
-            {
-                // Display the current frame rate counters.
-                //Application.Current.Host.Settings.EnableFrameRateCounter = true;
-
-                // Show the areas of the app that are being redrawn in each frame.
-                //Application.Current.Host.Settings.EnableRedrawRegions = true;
-
-                // Enable non-production analysis visualization mode, 
-                // which shows areas of a page that are being GPU accelerated with a colored overlay.
-                //Application.Current.Host.Settings.EnableCacheVisualization = true;
-            }
-
-            // Standard Silverlight initialization
-            InitializeComponent();
-
-            // Phone-specific initialization
-            InitializePhoneApplication();
-        }
-
-        // Code to execute when the application is launching (eg, from Start)
-        // This code will not execute when the application is reactivated
-        private void Application_Launching(object sender, LaunchingEventArgs e)
-        {
-        }
-
-        // Code to execute when the application is activated (brought to foreground)
-        // This code will not execute when the application is first launched
-        private void Application_Activated(object sender, ActivatedEventArgs e)
-        {
-        }
-
-        // Code to execute when the application is deactivated (sent to background)
-        // This code will not execute when the application is closing
-        private void Application_Deactivated(object sender, DeactivatedEventArgs e)
-        {
-        }
-
-        // Code to execute when the application is closing (eg, user hit Back)
-        // This code will not execute when the application is deactivated
-        private void Application_Closing(object sender, ClosingEventArgs e)
-        {
-        }
-
-        // Code to execute if a navigation fails
-        private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
-        {
-            if (System.Diagnostics.Debugger.IsAttached)
-            {
-                // A navigation has failed; break into the debugger
-                System.Diagnostics.Debugger.Break();
-            }
-        }
-
-        // Code to execute on Unhandled Exceptions
-        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
-        {
-            if (System.Diagnostics.Debugger.IsAttached)
-            {
-                // An unhandled exception has occurred; break into the debugger
-                System.Diagnostics.Debugger.Break();
-            }
-        }
-
-        #region Phone application initialization
-
-        // Avoid double-initialization
-        private bool phoneApplicationInitialized = false;
-
-        // Do not add any additional code to this method
-        private void InitializePhoneApplication()
-        {
-            if (phoneApplicationInitialized)
-                return;
-
-            // Create the frame but don't set it as RootVisual yet; this allows the splash
-            // screen to remain active until the application is ready to render.
-            RootFrame = new PhoneApplicationFrame();
-            RootFrame.Navigated += CompleteInitializePhoneApplication;
-
-            // Handle navigation failures
-            RootFrame.NavigationFailed += RootFrame_NavigationFailed;
-
-            // Ensure we don't initialize again
-            phoneApplicationInitialized = true;
-        }
-
-        // Do not add any additional code to this method
-        private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
-        {
-            // Set the root visual to allow the application to render
-            if (RootVisual != RootFrame)
-                RootVisual = RootFrame;
-
-            // Remove this handler since it is no longer needed
-            RootFrame.Navigated -= CompleteInitializePhoneApplication;
-        }
-
-        #endregion
-    }
-}
diff --git a/templates/standalone/ApplicationIcon.png b/templates/standalone/ApplicationIcon.png
deleted file mode 100644
index 6b69046..0000000
--- a/templates/standalone/ApplicationIcon.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/Background.png b/templates/standalone/Background.png
deleted file mode 100644
index 2667df4..0000000
--- a/templates/standalone/Background.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/BuildManifestProcessor.js b/templates/standalone/BuildManifestProcessor.js
deleted file mode 100644
index ab2ac9d..0000000
--- a/templates/standalone/BuildManifestProcessor.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
-*/
-var objArgs = WScript.Arguments;
-for (i = 0; i < objArgs.length; i++) {
-    WScript.Echo("Arg :: " + objArgs(i));
-}
-
-var projectFilePath = null;
-if (objArgs && objArgs.length > 0) {
-    projectFilePath = objArgs(0);
-}
-
-
-var fso = WScript.CreateObject("Scripting.FileSystemObject");
-var outFile = fso.CreateTextFile("..\\..\\CordovaSourceDictionary.xml", true);
-
-outFile.WriteLine('<?xml version="1.0" encoding="utf-8"?>');
-outFile.WriteLine('<!-- This file is auto-generated, do not edit! -jm -->');
-outFile.WriteLine('<CordovaSourceDictionary>');
-
-
-function getDirectoryListing(path) {
-    var retList = [];
-    var fso = new ActiveXObject("Scripting.FileSystemObject");
-    var folder = fso.GetFolder(path);
-    // iterate over the files in the folder
-    for (var files = new Enumerator(folder.files) ; !files.atEnd() ; files.moveNext()) {
-        retList.push(path + files.item().name);
-    }
-    // iterate over the child folders in the folder
-    for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
-        var subDirList = getDirectoryListing(path + subFlds.item().name + "\\");
-        retList = retList.concat(subDirList);
-    }
-    return retList;
-}
-
-
-// We need to get any Linked files from the project
-
-WScript.Echo("Adding Source Files ...");
-if (projectFilePath != null) {
-    var projXml = WScript.CreateObject("Microsoft.XMLDOM");
-
-    projXml.async = false;
-    if (projXml.load(projectFilePath)) {
-
-        // add linked content ( windows shortcuts )
-        var nodes = projXml.selectNodes("/Project/ItemGroup/Content/Link");
-        WScript.Echo("/Project/ItemGroup/Content/Link nodes.length" + nodes.length);
-        for (var n = 0; n < nodes.length; n++) {
-            outFile.WriteLine('    <FilePath Value="' + nodes[n].text + '"/>');
-        }
-
-        // add files of type Resource
-        nodes = projXml.selectNodes("/Project/ItemGroup/Resource/Link");
-        WScript.Echo("/Project/ItemGroup/Resource/Link nodes.length" + nodes.length);
-        for (n = 0; n < nodes.length; n++) {
-            outFile.WriteLine('    <FilePath Value="' + nodes[n].text + '"/>');
-        }
-
-        // add Content files from www folder
-        nodes = projXml.selectNodes("/Project/ItemGroup/Content[@Include]");
-        WScript.Echo("/Project/ItemGroup/Content nodes.length" + nodes.length);
-        for (n = 0; n < nodes.length; n++) {
-            for (var i = 0; i < nodes[n].attributes.length; i++) {
-
-                if (nodes[n].attributes[i].name == "Include") {
-                    var val = nodes[n].attributes[i].value;
-                    if (val.indexOf("www\\**") == 0 ){
-                        WScript.echo("adding wildcard files");
-                        var fileList = getDirectoryListing("..\\..\\www\\");
-                        for (var index = 0 ; index < fileList.length; index++)
-                        {
-                            outFile.WriteLine('    <FilePath Value="' + fileList[index].replace(/..\\..\\www/g,"www") + '"/>');
-                        }
-                    }
-                    else if (val.indexOf("www") == 0) {
-                        WScript.Echo("adding value :: " + val);
-                        outFile.WriteLine('    <FilePath Value="' + val + '"/>');
-                    }
-                }
-            }
-            
-        }
-    }
-}
-
-outFile.WriteLine('</CordovaSourceDictionary>');
-
diff --git a/templates/standalone/CordovaAppProj.csproj b/templates/standalone/CordovaAppProj.csproj
deleted file mode 100644
index 8434a77..0000000
--- a/templates/standalone/CordovaAppProj.csproj
+++ /dev/null
@@ -1,238 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
--->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.20506</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}</ProjectGuid>
-    <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>$safeprojectname$</RootNamespace>
-    <AssemblyName>$safeprojectname$</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
-    <TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>
-    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
-    <SilverlightApplication>true</SilverlightApplication>
-    <SupportedCultures>
-    </SupportedCultures>
-    <XapOutputs>true</XapOutputs>
-    <GenerateSilverlightManifest>true</GenerateSilverlightManifest>
-    <XapFilename>$safeprojectname$.xap</XapFilename>
-    <SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate>
-    <SilverlightAppEntry>$safeprojectname$.App</SilverlightAppEntry>
-    <ValidateXaml>true</ValidateXaml>
-    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>Bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
-    <NoStdLib>true</NoStdLib>
-    <NoConfig>true</NoConfig>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>Bin\Release</OutputPath>
-    <DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
-    <NoStdLib>true</NoStdLib>
-    <NoConfig>true</NoConfig>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Microsoft.Devices.Sensors" />
-    <Reference Include="Microsoft.Phone" />
-    <Reference Include="Microsoft.Phone.Interop" />
-    <Reference Include="Microsoft.Xna.Framework" />
-    <Reference Include="System.Device" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Servicemodel.Web" />
-    <Reference Include="System.Windows" />
-    <Reference Include="system" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Net" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Xml.Linq" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="App.xaml.cs">
-      <DependentUpon>App.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="cordovalib\BaseCommand.cs" />
-    <Compile Include="cordovalib\BrowserMouseHelper.cs" />
-    <Compile Include="cordovalib\CommandFactory.cs" />
-    <Compile Include="cordovalib\ConfigHandler.cs" />
-    <Compile Include="cordovalib\CordovaCommandCall.cs" />
-    <Compile Include="cordovalib\CordovaView.xaml.cs">
-      <DependentUpon>CordovaView.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="cordovalib\DOMStorageHelper.cs" />
-    <Compile Include="cordovalib\ImageExifHelper.cs" />
-    <Compile Include="cordovalib\JSON\JsonHelper.cs" />
-    <Compile Include="cordovalib\NativeExecution.cs" />
-    <Compile Include="cordovalib\OrientationHelper.cs" />
-    <Compile Include="cordovalib\PluginResult.cs" />
-    <Compile Include="cordovalib\ScriptCallback.cs" />
-    <Compile Include="MainPage.xaml.cs">
-      <DependentUpon>MainPage.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ApplicationDefinition Include="App.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </ApplicationDefinition>
-    <Page Include="MainPage.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </Page>
-    <Page Include="cordovalib\CordovaView.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="cordova\lib\build.js" />
-    <None Include="cordova\lib\clean.js" />
-    <None Include="cordova\lib\deploy.js" />
-    <None Include="cordova\lib\log.js" />
-    <None Include="cordova\lib\target-list.js" />
-    <Content Include="www\**" />
-    <Content Include="config.xml" />
-    <Content Include="Images\**" />
-    <Content Include="resources\notification-beep.wav" />
-    <None Include="cordova\build.bat" />
-    <None Include="cordova\clean.bat" />
-    <None Include="cordova\lib\install-device.bat" />
-    <None Include="cordova\lib\install-emulator.bat" />
-    <None Include="cordova\lib\list-devices.bat" />
-    <None Include="cordova\lib\list-emulator-images.bat" />
-    <None Include="cordova\lib\list-started-emulators.bat" />
-    <None Include="cordova\lib\start-emulator.bat" />
-    <None Include="cordova\log.bat" />
-    <None Include="cordova\run.bat" />
-    <None Include="cordova\version.bat" />
-    <None Include="VERSION" />
-    <Content Include="CordovaSourceDictionary.xml">
-      <SubType>Designer</SubType>
-    </Content>
-    <None Include="BuildManifestProcessor.js" />
-    <None Include="Properties\AppManifest.xml">
-      <SubType>Designer</SubType>
-    </None>
-    <None Include="Properties\WMAppManifest.xml">
-      <SubType>Designer</SubType>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="ApplicationIcon.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Background.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="SplashScreenImage.jpg" />
-  </ItemGroup>
-  <ItemGroup>
-    <WCFMetadata Include="Service References\" />
-  </ItemGroup>
-  <ItemGroup>
-    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Plugins\Accelerometer.cs" />
-    <Compile Include="Plugins\AudioFormatsHelper.cs" />
-    <Compile Include="Plugins\AudioPlayer.cs" />
-    <Compile Include="Plugins\Battery.cs" />
-    <Compile Include="Plugins\Camera.cs" />
-    <Compile Include="Plugins\Compass.cs" />
-    <Compile Include="Plugins\Contacts.cs" />
-    <Compile Include="Plugins\DebugConsole.cs" />
-    <Compile Include="Plugins\Device.cs" />
-    <Compile Include="Plugins\File.cs" />
-    <Compile Include="Plugins\FileTransfer.cs" />
-    <Compile Include="Plugins\GeoLocation.cs" />
-    <Compile Include="Plugins\Globalization.cs" />
-    <Compile Include="Plugins\InAppBrowser.cs" />
-    <Compile Include="Plugins\Media.cs" />
-    <Compile Include="Plugins\MimeTypeMapper.cs" />
-    <Compile Include="Plugins\NetworkStatus.cs" />
-    <Compile Include="Plugins\Notification.cs" />
-    <Compile Include="Plugins\UI\AudioCaptureTask.cs" />
-    <Compile Include="Plugins\UI\AudioRecorder.xaml.cs">
-      <DependentUpon>AudioRecorder.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\ImageCapture.xaml.cs">
-      <DependentUpon>ImageCapture.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\NotificationBox.xaml.cs">
-      <DependentUpon>NotificationBox.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\VideoCaptureTask.cs" />
-    <Compile Include="Plugins\UI\VideoRecorder.xaml.cs">
-      <DependentUpon>VideoRecorder.xaml</DependentUpon>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <Page Include="Plugins\UI\AudioRecorder.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\ImageCapture.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\NotificationBox.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\VideoRecorder.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-  </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
-  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-  <ProjectExtensions />
-  <PropertyGroup>
-    <PreBuildEvent>CScript "$(ProjectDir)/BuildManifestProcessor.js" "$(ProjectPath)"</PreBuildEvent>
-  </PropertyGroup>
-  <PropertyGroup>
-    <PostBuildEvent>
-    </PostBuildEvent>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/templates/standalone/CordovaSolution.sln b/templates/standalone/CordovaSolution.sln
deleted file mode 100644
index 5ce2292..0000000
--- a/templates/standalone/CordovaSolution.sln
+++ /dev/null
@@ -1,22 +0,0 @@
-﻿
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010 Express for Windows Phone
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CordovaAppProj", "CordovaAppProj.csproj", "{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
-		{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}.Release|Any CPU.Build.0 = Release|Any CPU
-		{3677C1B7-D68B-4CF9-BF8A-E869D437A6DF}.Release|Any CPU.Deploy.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/templates/standalone/CordovaSourceDictionary.xml b/templates/standalone/CordovaSourceDictionary.xml
deleted file mode 100644
index ea05ca7..0000000
--- a/templates/standalone/CordovaSourceDictionary.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- This file is auto-generated, do not edit! -jm -->
-<CordovaSourceDictionary>
-    <FilePath Value="www\cordova.js"/>
-    <FilePath Value="www\index.html"/>
-    <FilePath Value="www\css\index.css"/>
-    <FilePath Value="www\img\logo.png"/>
-    <FilePath Value="www\js\index.js"/>
-</CordovaSourceDictionary>
diff --git a/templates/standalone/Images/appbar.back.rest.png b/templates/standalone/Images/appbar.back.rest.png
deleted file mode 100644
index 4bc2b92..0000000
--- a/templates/standalone/Images/appbar.back.rest.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/Images/appbar.close.rest.png b/templates/standalone/Images/appbar.close.rest.png
deleted file mode 100644
index 8166a1c..0000000
--- a/templates/standalone/Images/appbar.close.rest.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/Images/appbar.feature.video.rest.png b/templates/standalone/Images/appbar.feature.video.rest.png
deleted file mode 100644
index baff565..0000000
--- a/templates/standalone/Images/appbar.feature.video.rest.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/Images/appbar.next.rest.png b/templates/standalone/Images/appbar.next.rest.png
deleted file mode 100644
index ed577d7..0000000
--- a/templates/standalone/Images/appbar.next.rest.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/Images/appbar.save.rest.png b/templates/standalone/Images/appbar.save.rest.png
deleted file mode 100644
index d49940e..0000000
--- a/templates/standalone/Images/appbar.save.rest.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/Images/appbar.stop.rest.png b/templates/standalone/Images/appbar.stop.rest.png
deleted file mode 100644
index 4dd724f..0000000
--- a/templates/standalone/Images/appbar.stop.rest.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/MainPage.xaml b/templates/standalone/MainPage.xaml
deleted file mode 100644
index 8b1e84b..0000000
--- a/templates/standalone/MainPage.xaml
+++ /dev/null
@@ -1,35 +0,0 @@
-﻿
-<phone:PhoneApplicationPage 
-    x:Class="$safeprojectname$.MainPage"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
-    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
-    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}"
-    FontSize="{StaticResource PhoneFontSizeNormal}"
-    Foreground="{StaticResource PhoneForegroundBrush}"
-    Background="Black"
-    SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
-    shell:SystemTray.IsVisible="True" d:DesignHeight="768" d:DesignWidth="480" 
-    xmlns:my="clr-namespace:WPCordovaClassLib">
-    <Grid x:Name="LayoutRoot" Background="Transparent" HorizontalAlignment="Stretch">
-        <Grid.RowDefinitions>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-        <my:CordovaView HorizontalAlignment="Stretch" 
-                   Margin="0,0,0,0"  
-                   x:Name="CordovaView" 
-                   VerticalAlignment="Stretch" />
-        <Image Source="SplashScreenImage.jpg"
-          x:Name="SplashImage"
-          VerticalAlignment="Center"
-          HorizontalAlignment="Stretch">
-            <Image.Projection>
-                <PlaneProjection x:Name="SplashProjector"  CenterOfRotationX="0"/>
-            </Image.Projection>
-        </Image>
-    </Grid>
-
-</phone:PhoneApplicationPage>
diff --git a/templates/standalone/MainPage.xaml.cs b/templates/standalone/MainPage.xaml.cs
deleted file mode 100644
index b9ec7e1..0000000
--- a/templates/standalone/MainPage.xaml.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-﻿/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using System.IO;
-using System.Windows.Media.Imaging;
-using System.Windows.Resources;
-
-
-namespace $safeprojectname$
-{
-    public partial class MainPage : PhoneApplicationPage
-    {
-        // Constructor
-        public MainPage()
-        {
-            InitializeComponent();
-            this.CordovaView.Loaded += CordovaView_Loaded;
-        }
-
-        private void CordovaView_Loaded(object sender, RoutedEventArgs e)
-        {
-            this.CordovaView.Loaded -= CordovaView_Loaded;
-            // first time load will have an animation
-            Storyboard _storyBoard = new Storyboard();
-            DoubleAnimation animation = new DoubleAnimation()
-            {
-                From = 0,
-                Duration = TimeSpan.FromSeconds(0.6),
-                To = 90
-            };
-            Storyboard.SetTarget(animation, SplashProjector);
-            Storyboard.SetTargetProperty(animation, new PropertyPath("RotationY"));
-            _storyBoard.Children.Add(animation);
-            _storyBoard.Begin();
-            _storyBoard.Completed += Splash_Completed;
-        }
-
-        void Splash_Completed(object sender, EventArgs e)
-        {
-            (sender as Storyboard).Completed -= Splash_Completed;
-            LayoutRoot.Children.Remove(SplashImage);
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/Accelerometer.cs b/templates/standalone/Plugins/Accelerometer.cs
deleted file mode 100644
index cba911c..0000000
--- a/templates/standalone/Plugins/Accelerometer.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-using System.Globalization;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Captures device motion in the x, y, and z direction.
-    /// </summary>
-    public class Accelerometer : BaseCommand
-    {
-        #region AccelerometerOptions class
-        /// <summary>
-        /// Represents Accelerometer options.
-        /// </summary>
-        [DataContract]
-        public class AccelerometerOptions
-        {
-            /// <summary>
-            /// How often to retrieve the Acceleration in milliseconds
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "frequency")]
-            public int Frequency { get; set; }
-
-            /// <summary>
-            /// Watcher id
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "id")]
-            public string Id { get; set; }
-
-            /// <summary>
-            /// Creates options object with default parameters
-            /// </summary>
-            public AccelerometerOptions()
-            {
-                this.SetDefaultValues(new StreamingContext());
-            }
-
-            /// <summary>
-            /// Initializes default values for class fields.
-            /// Implemented in separate method because default constructor is not invoked during deserialization.
-            /// </summary>
-            /// <param name="context"></param>
-            [OnDeserializing()]
-            public void SetDefaultValues(StreamingContext context)
-            {
-                this.Frequency = 10000;
-            }
-        }
-
-        #endregion
-
-        #region Status codes and Constants
-
-        public const int Stopped = 0;
-        public const int Starting = 1;
-        public const int Running = 2;
-        public const int ErrorFailedToStart = 3;
-
-        public const double gConstant = -9.81;
-
-        #endregion
-
-        #region Static members
-
-        /// <summary>
-        /// Status of listener
-        /// </summary>
-        private static int currentStatus;
-
-        /// <summary>
-        /// Accelerometer
-        /// </summary>
-        private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
-
-        private static DateTime StartOfEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
-
-        #endregion
-
-        /// <summary>
-        /// Sensor listener event
-        /// </summary>        
-        private void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
-        {
-            this.SetStatus(Running);
-
-            PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentAccelerationFormatted());
-            result.KeepCallback = true;
-            DispatchCommandResult(result);
-        }
-
-        /// <summary>
-        /// Starts listening for acceleration sensor
-        /// </summary>
-        /// <returns>status of listener</returns>
-        public void start(string options)
-        {
-            if ((currentStatus == Running) || (currentStatus == Starting))
-            {
-                return;
-            }
-            try
-            {
-                lock (accelerometer)
-                {
-                    accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
-                    accelerometer.Start();
-                    this.SetStatus(Starting);
-                }
-
-                long timeout = 2000;
-                while ((currentStatus == Starting) && (timeout > 0))
-                {
-                    timeout = timeout - 100;
-                    Thread.Sleep(100);
-                }
-
-                if (currentStatus != Running)
-                {
-                    this.SetStatus(ErrorFailedToStart);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
-                    return;
-                }
-            }
-            catch (Exception)
-            {
-                this.SetStatus(ErrorFailedToStart);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
-                return;
-            }
-            PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
-            result.KeepCallback = true;
-            DispatchCommandResult(result);
-        }
-
-        public void stop(string options)
-        {
-            if (currentStatus == Running)
-            {
-                lock (accelerometer)
-                {
-                    accelerometer.CurrentValueChanged -= accelerometer_CurrentValueChanged;
-                    accelerometer.Stop();
-                    this.SetStatus(Stopped);
-                }
-            }
-            DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-        }
-
-        /// <summary>
-        /// Formats current coordinates into JSON format
-        /// </summary>
-        /// <returns>Coordinates in JSON format</returns>
-        private string GetCurrentAccelerationFormatted()
-        {
-            // convert to unix timestamp
-            // long timestamp = ((accelerometer.CurrentValue.Timestamp.DateTime - StartOfEpoch).Ticks) / 10000;
-            // Note: Removed timestamp, to let the JS side create it using (new Date().getTime()) -jm
-            // this resolves an issue with inconsistencies between JS dates and Native DateTime 
-            string resultCoordinates = String.Format("\"x\":{0},\"y\":{1},\"z\":{2}",
-                            (accelerometer.CurrentValue.Acceleration.X * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
-                            (accelerometer.CurrentValue.Acceleration.Y * gConstant).ToString("0.00000", CultureInfo.InvariantCulture),
-                            (accelerometer.CurrentValue.Acceleration.Z * gConstant).ToString("0.00000", CultureInfo.InvariantCulture));
-            return  "{" + resultCoordinates + "}";
-        }
-
-        /// <summary>
-        /// Sets current status
-        /// </summary>
-        /// <param name="status">current status</param>
-        private void SetStatus(int status)
-        {
-            currentStatus = status;
-        }
-    }
-}
-
diff --git a/templates/standalone/Plugins/AudioFormatsHelper.cs b/templates/standalone/Plugins/AudioFormatsHelper.cs
deleted file mode 100644
index dca7ee6..0000000
--- a/templates/standalone/Plugins/AudioFormatsHelper.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-
- */
-
-using System;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides extra functionality to support different audio formats.
-    /// </summary>
-    public static class AudioFormatsHelper
-    {
-        #region Wav
-        /// <summary>
-        /// Adds wav file format header to the stream
-        /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
-        /// </summary>
-        /// <param name="stream">The stream</param>
-        /// <param name="sampleRate">Sample Rate</param>
-        public static void InitializeWavStream(this Stream stream, int sampleRate)
-        {
-            #region args checking
-
-            if (stream == null) 
-            {
-                throw new ArgumentNullException("stream can't be null or empty");
-            }
-
-            #endregion
-
-            int numBits = 16;
-            int numBytes = numBits / 8;
-
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
-            stream.Write(BitConverter.GetBytes(0), 0, 4);
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
-            stream.Write(BitConverter.GetBytes(16), 0, 4);
-            stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-            stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-            stream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
-            stream.Write(BitConverter.GetBytes(sampleRate * numBytes), 0, 4);
-            stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
-            stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
-            stream.Write(BitConverter.GetBytes(0), 0, 4);
-        }
-
-        /// <summary>
-        /// Updates wav file format header
-        /// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
-        /// </summary>
-        /// <param name="stream">Wav stream</param>
-        public static void UpdateWavStream(this Stream stream)
-        {
-            #region args checking
-
-            if (stream == null)
-            {
-                throw new ArgumentNullException("stream can't be null or empty");
-            }
-
-            #endregion
-
-            var position = stream.Position;
-
-            stream.Seek(4, SeekOrigin.Begin);
-            stream.Write(BitConverter.GetBytes((int)stream.Length - 8), 0, 4);
-            stream.Seek(40, SeekOrigin.Begin);
-            stream.Write(BitConverter.GetBytes((int)stream.Length - 44), 0, 4);
-            stream.Seek(position, SeekOrigin.Begin);
-        }
-
-        #endregion
-    }
-}
diff --git a/templates/standalone/Plugins/AudioPlayer.cs b/templates/standalone/Plugins/AudioPlayer.cs
deleted file mode 100644
index fe85e6b..0000000
--- a/templates/standalone/Plugins/AudioPlayer.cs
+++ /dev/null
@@ -1,649 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
-    /// <summary>
-    /// Implements audio record and play back functionality.
-    /// </summary>
-    internal class AudioPlayer : IDisposable
-    {
-        #region Constants
-
-        // AudioPlayer states
-        private const int PlayerState_None = 0;
-        private const int PlayerState_Starting = 1;
-        private const int PlayerState_Running = 2;
-        private const int PlayerState_Paused = 3;
-        private const int PlayerState_Stopped = 4;
-
-        // AudioPlayer messages
-        private const int MediaState = 1;
-        private const int MediaDuration = 2;
-        private const int MediaPosition = 3;
-        private const int MediaError = 9;
-
-        // AudioPlayer errors
-        private const int MediaErrorPlayModeSet = 1;
-        private const int MediaErrorAlreadyRecording = 2;
-        private const int MediaErrorStartingRecording = 3;
-        private const int MediaErrorRecordModeSet = 4;
-        private const int MediaErrorStartingPlayback = 5;
-        private const int MediaErrorResumeState = 6;
-        private const int MediaErrorPauseState = 7;
-        private const int MediaErrorStopState = 8;
-
-        //TODO: get rid of this callback, it should be universal
-        //private const string CallbackFunction = "CordovaMediaonStatus";
-
-        #endregion
-
-
-        /// <summary>
-        /// The AudioHandler object
-        /// </summary>
-        private Media handler;
-
-        /// <summary>
-        /// Temporary buffer to store audio chunk
-        /// </summary>
-        private byte[] buffer;
-
-        /// <summary>
-        /// Xna game loop dispatcher
-        /// </summary>
-        DispatcherTimer dtXna;
-
-        
-
-        /// <summary>
-        /// Output buffer
-        /// </summary>
-        private MemoryStream memoryStream;
-
-        /// <summary>
-        /// The id of this player (used to identify Media object in JavaScript)
-        /// </summary>
-        private String id;
-
-        /// <summary>
-        /// State of recording or playback
-        /// </summary>
-        private int state = PlayerState_None;
-
-        /// <summary>
-        /// File name to play or record to
-        /// </summary>
-        private String audioFile = null;
-
-        /// <summary>
-        /// Duration of audio
-        /// </summary>
-        private double duration = -1;
-
-        /// <summary>
-        /// Audio player object
-        /// </summary>
-        private MediaElement player = null;
-
-        /// <summary>
-        /// Audio source
-        /// </summary>
-        private Microphone recorder;
-
-        /// <summary>
-        /// Internal flag specified that we should only open audio w/o playing it
-        /// </summary>
-        private bool prepareOnly = false;
-
-        /// <summary>
-        /// Creates AudioPlayer instance
-        /// </summary>
-        /// <param name="handler">Media object</param>
-        /// <param name="id">player id</param>
-        public AudioPlayer(Media handler, String id)
-        {
-            this.handler = handler;
-            this.id = id;
-        }
-
-       
-
-        /// <summary>
-        /// Destroys player and stop audio playing or recording
-        /// </summary>
-        public void Dispose()
-        {
-            if (this.player != null)
-            {
-                this.stopPlaying();
-                this.player = null;
-            }
-            if (this.recorder != null)
-            {
-                this.stopRecording();
-                this.recorder = null;
-            }
-
-            this.FinalizeXnaGameLoop();
-        }
-
-        private void InvokeCallback(int message, string value, bool removeHandler)
-        {
-            string args = string.Format("('{0}',{1},{2});", this.id, message, value);
-            string callback = @"(function(id,msg,value){
-                try {
-                    if (msg == Media.MEDIA_ERROR) {
-                        value = {'code':value};
-                    }
-                    Media.onStatus(id,msg,value);
-                }
-                catch(e) {
-                    console.log('Error calling Media.onStatus :: ' + e);
-                }
-            })" + args;
-            this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
-        }
-
-        private void InvokeCallback(int message, int value, bool removeHandler)
-        {
-            InvokeCallback(message, value.ToString(), removeHandler);
-        }
-
-        private void InvokeCallback(int message, double value, bool removeHandler)
-        {
-            InvokeCallback(message, value.ToString(), removeHandler);
-        }
-
-        /// <summary>
-        /// Starts recording, data is stored in memory
-        /// </summary>
-        /// <param name="filePath"></param>
-        public void startRecording(string filePath)
-        {
-            if (this.player != null)
-            {
-                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
-            }
-            else if (this.recorder == null)
-            {
-                try
-                {
-                    this.audioFile = filePath;
-                    this.InitializeXnaGameLoop();
-                    this.recorder = Microphone.Default;
-                    this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
-                    this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
-                    this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
-                    MemoryStream stream  = new MemoryStream();
-                    this.memoryStream = stream;
-                    int numBits = 16;
-                    int numBytes = numBits / 8;
-
-                    // inline version from AudioFormatsHelper
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
-                    stream.Write(BitConverter.GetBytes(0), 0, 4);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
-                    stream.Write(BitConverter.GetBytes(16), 0, 4);
-                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4);
-                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4);
-                    stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
-                    stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
-                    stream.Write(BitConverter.GetBytes(0), 0, 4);
-
-                    this.recorder.Start();
-                    FrameworkDispatcher.Update();
-                    this.SetState(PlayerState_Running);
-                }
-                catch (Exception)
-                {
-                    InvokeCallback(MediaError, MediaErrorStartingRecording, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
-                }
-            }
-            else
-            {
-                InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
-            }
-        }
-
-        /// <summary>
-        /// Stops recording
-        /// </summary>
-        public void stopRecording()
-        {
-            if (this.recorder != null)
-            {
-                if (this.state == PlayerState_Running)
-                {
-                    try
-                    {
-                        this.recorder.Stop();
-                        this.recorder.BufferReady -= recorderBufferReady;
-                        this.recorder = null;
-                        SaveAudioClipToLocalStorage();
-                        this.FinalizeXnaGameLoop();
-                        this.SetState(PlayerState_Stopped);
-                    }
-                    catch (Exception)
-                    {
-                        //TODO 
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Starts or resume playing audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        /// <summary>
-        /// Starts or resume playing audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        public void startPlaying(string filePath)
-        {
-            if (this.recorder != null)
-            {
-                InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
-                return;
-            }
-
-
-            if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
-            {
-                try
-                {
-                    // this.player is a MediaElement, it must be added to the visual tree in order to play
-                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                    if (frame != null)
-                    {
-                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-                        if (page != null)
-                        {
-                            Grid grid = page.FindName("LayoutRoot") as Grid;
-                            if (grid != null)
-                            {
-
-                                this.player = grid.FindName("playerMediaElement") as MediaElement;
-                                if (this.player == null) // still null ?
-                                {
-                                    this.player = new MediaElement();
-                                    this.player.Name = "playerMediaElement";
-                                    grid.Children.Add(this.player);
-                                    this.player.Visibility = Visibility.Visible;
-                                }
-                                if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
-                                {
-                                    this.player.Stop(); // stop it!
-                                }
-
-                                this.player.Source = null; // Garbage collect it.
-                                this.player.MediaOpened += MediaOpened;
-                                this.player.MediaEnded += MediaEnded;
-                                this.player.MediaFailed += MediaFailed;
-                            }
-                        }
-                    }
-
-                    this.audioFile = filePath;
-
-                    Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
-                    if (uri.IsAbsoluteUri)
-                    {
-                        this.player.Source = uri;
-                    }
-                    else
-                    {
-                        using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                        {
-                            if (!isoFile.FileExists(filePath))
-                            {
-                                // try to unpack it from the dll into isolated storage
-                                StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
-                                if (fileResourceStreamInfo != null)
-                                {
-                                    using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
-                                    {
-                                        byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
-                                        string[] dirParts = filePath.Split('/');
-                                        string dirName = "";
-                                        for (int n = 0; n < dirParts.Length - 1; n++)
-                                        {
-                                            dirName += dirParts[n] + "/";
-                                        }
-                                        if (!isoFile.DirectoryExists(dirName))
-                                        {
-                                            isoFile.CreateDirectory(dirName);
-                                        }
-
-                                        using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
-                                        {
-                                            using (BinaryWriter writer = new BinaryWriter(outFile))
-                                            {
-                                                writer.Write(data);
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                            if (isoFile.FileExists(filePath))
-                            {
-                                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
-                                {
-                                    this.player.SetSource(stream);
-                                }
-                            }
-                            else
-                            {
-                                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
-                                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
-                                return;
-                            }
-                        }
-                    }
-                    this.SetState(PlayerState_Starting);
-                }
-                catch (Exception e)
-                {
-                    Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
-                    InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
-                }
-            }
-            else
-            {
-                if (this.state != PlayerState_Running)
-                {
-                    this.player.Play();
-                    this.SetState(PlayerState_Running);
-                }
-                else
-                {
-                    InvokeCallback(MediaError, MediaErrorResumeState, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Callback to be invoked when the media source is ready for playback
-        /// </summary>
-        private void MediaOpened(object sender, RoutedEventArgs arg)
-        {
-            if (this.player != null)
-            {
-                this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
-                InvokeCallback(MediaDuration, this.duration, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
-                if (!this.prepareOnly)
-                {
-                    this.player.Play();
-                    this.SetState(PlayerState_Running);
-                }
-                this.prepareOnly = false;
-            }
-            else
-            {
-                // TODO: occasionally MediaOpened is signalled, but player is null
-            }
-        }
-
-        /// <summary>
-        /// Callback to be invoked when playback of a media source has completed
-        /// </summary>
-        private void MediaEnded(object sender, RoutedEventArgs arg)
-        {
-            this.SetState(PlayerState_Stopped);
-        }
-
-        /// <summary>
-        /// Callback to be invoked when playback of a media source has failed
-        /// </summary>
-        private void MediaFailed(object sender, RoutedEventArgs arg)
-        {
-            player.Stop();
-            InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
-            //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
-        }
-
-        /// <summary>
-        /// Seek or jump to a new time in the track
-        /// </summary>
-        /// <param name="milliseconds">The new track position</param>
-        public void seekToPlaying(int milliseconds)
-        {
-            if (this.player != null)
-            {
-                TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
-                this.player.Position = tsPos;
-                InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
-            }
-        }
-
-        /// <summary>
-        /// Set the volume of the player
-        /// </summary>
-        /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
-        public void setVolume(double vol)
-        {
-            if (this.player != null)
-            {
-                this.player.Volume = vol;
-            }
-        }
-
-        /// <summary>
-        /// Pauses playing
-        /// </summary>
-        public void pausePlaying()
-        {
-            if (this.state == PlayerState_Running)
-            {
-                this.player.Pause();
-                this.SetState(PlayerState_Paused);
-            }
-            else
-            {
-                InvokeCallback(MediaError, MediaErrorPauseState, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
-            }
-        }
-
-
-        /// <summary>
-        /// Stops playing the audio file
-        /// </summary>
-        public void stopPlaying()
-        {
-            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
-            {
-                this.player.Stop();
-
-                this.player.Position = new TimeSpan(0L);
-                this.SetState(PlayerState_Stopped);
-            }
-            //else // Why is it an error to call stop on a stopped media?
-            //{
-            //    this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
-            //}
-        }
-
-        /// <summary>
-        /// Gets current position of playback
-        /// </summary>
-        /// <returns>current position</returns>
-        public double getCurrentPosition()
-        {
-            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
-            {
-                double currentPosition = this.player.Position.TotalSeconds;
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
-                return currentPosition;
-            }
-            else
-            {
-                return 0;
-            }
-        }
-
-        /// <summary>
-        /// Gets the duration of the audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        /// <returns>track duration</returns>
-        public double getDuration(string filePath)
-        {
-            if (this.recorder != null)
-            {
-                return (-2);
-            }
-
-            if (this.player != null)
-            {
-                return this.duration;
-
-            }
-            else
-            {
-                this.prepareOnly = true;
-                this.startPlaying(filePath);
-                return this.duration;
-            }
-        }
-
-        /// <summary>
-        /// Sets the state and send it to JavaScript
-        /// </summary>
-        /// <param name="state">state</param>
-        private void SetState(int state)
-        {
-            if (this.state != state)
-            {
-                InvokeCallback(MediaState, state, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
-            }
-
-            this.state = state;
-        }
-
-        #region record methods
-
-        /// <summary>
-        /// Copies data from recorder to memory storages and updates recording state
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void recorderBufferReady(object sender, EventArgs e)
-        {
-            this.recorder.GetData(this.buffer);
-            this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
-        }
-
-        /// <summary>
-        /// Writes audio data from memory to isolated storage
-        /// </summary>
-        /// <returns></returns>
-        private void SaveAudioClipToLocalStorage()
-        {
-            if (memoryStream == null || memoryStream.Length <= 0)
-            {
-                return;
-            }
-
-            long position = memoryStream.Position;
-            memoryStream.Seek(4, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
-            memoryStream.Seek(40, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
-            memoryStream.Seek(position, SeekOrigin.Begin);
-
-            try
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    string directory = Path.GetDirectoryName(audioFile);
-
-                    if (!isoFile.DirectoryExists(directory))
-                    {
-                        isoFile.CreateDirectory(directory);
-                    }
-
-                    this.memoryStream.Seek(0, SeekOrigin.Begin);
-
-                    using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
-                    {
-                        this.memoryStream.CopyTo(fileStream);
-                    }
-                }
-            }
-            catch (Exception)
-            {
-                //TODO: log or do something else
-                throw;
-            }
-        }
-
-        #region Xna loop
-        /// <summary>
-        /// Special initialization required for the microphone: XNA game loop
-        /// </summary>
-        private void InitializeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            this.dtXna = new DispatcherTimer();
-            this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
-            this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
-            this.dtXna.Start();
-        }
-        /// <summary>
-        /// Finalizes XNA game loop for microphone
-        /// </summary>
-        private void FinalizeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            if (this.dtXna != null)
-            {
-                this.dtXna.Stop();
-                this.dtXna = null;
-            }
-        }
-
-        #endregion
-
-        #endregion
-    }
-}
diff --git a/templates/standalone/Plugins/Battery.cs b/templates/standalone/Plugins/Battery.cs
deleted file mode 100644
index 962959e..0000000
--- a/templates/standalone/Plugins/Battery.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-using Microsoft.Phone.Info;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Listens for changes to the state of the battery on the device.
-    /// Currently only the "isPlugged" parameter available via native APIs.
-    /// </summary>
-    public class Battery : BaseCommand
-    {
-        private bool isPlugged = false;
-        private EventHandler powerChanged;
-
-        public Battery()
-        {
-            powerChanged = new EventHandler(DeviceStatus_PowerSourceChanged);
-            isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
-        }
-
-        public void start(string options)
-        {
-            // Register power changed event handler
-            DeviceStatus.PowerSourceChanged += powerChanged;
-
-            PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
-            result.KeepCallback = true;
-            DispatchCommandResult(result);
-        }
-        public void stop(string options)
-        {
-            // Unregister power changed event handler
-            DeviceStatus.PowerSourceChanged -= powerChanged;
-        }
-
-        private void DeviceStatus_PowerSourceChanged(object sender, EventArgs e)
-        {
-            isPlugged = DeviceStatus.PowerSource.ToString().CompareTo("External") == 0;
-            PluginResult result = new PluginResult(PluginResult.Status.OK, GetCurrentBatteryStateFormatted());
-            result.KeepCallback = true;
-            DispatchCommandResult(result);
-        }
-
-        private string GetCurrentBatteryStateFormatted()
-        {
-            string batteryState = String.Format("\"level\":{0},\"isPlugged\":{1}",
-                                                    "null",
-                                                    isPlugged ? "true" : "false"
-                            );
-            batteryState = "{" + batteryState + "}";
-            return batteryState;
-        }
-
-    }
-}
diff --git a/templates/standalone/Plugins/Camera.cs b/templates/standalone/Plugins/Camera.cs
deleted file mode 100644
index 5ff8045..0000000
--- a/templates/standalone/Plugins/Camera.cs
+++ /dev/null
@@ -1,490 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Collections.Generic;
-using Microsoft.Phone.Tasks;
-using System.Runtime.Serialization;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Xna.Framework.Media;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class Camera : BaseCommand
-    {
-
-        /// <summary>
-        /// Return base64 encoded string
-        /// </summary>
-        private const int DATA_URL = 0;
-
-        /// <summary>
-        /// Return file uri
-        /// </summary>
-        private const int FILE_URI = 1;
-
-        /// <summary>
-        /// Choose image from picture library
-        /// </summary>
-        private const int PHOTOLIBRARY = 0;
-
-        /// <summary>
-        /// Take picture from camera
-        /// </summary>
-
-        private const int CAMERA = 1;
-
-        /// <summary>
-        /// Choose image from picture library
-        /// </summary>
-        private const int SAVEDPHOTOALBUM = 2;
-
-        /// <summary>
-        /// Take a picture of type JPEG
-        /// </summary>
-        private const int JPEG = 0;
-
-        /// <summary>
-        /// Take a picture of type PNG
-        /// </summary>
-        private const int PNG = 1;
-
-        /// <summary>
-        /// Folder to store captured images
-        /// </summary>
-        private const string isoFolder = "CapturedImagesCache";
-
-        /// <summary>
-        /// Represents captureImage action options.
-        /// </summary>
-        [DataContract]
-        public class CameraOptions
-        {
-            /// <summary>
-            /// Source to getPicture from.
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "sourceType")]
-            public int PictureSourceType { get; set; }
-
-            /// <summary>
-            /// Format of image that returned from getPicture.
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "destinationType")]
-            public int DestinationType { get; set; }
-
-            /// <summary>
-            /// Quality of saved image
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "quality")]
-            public int Quality { get; set; }
-
-            /// <summary>
-            /// Controls whether or not the image is also added to the device photo album.
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
-            public bool SaveToPhotoAlbum { get; set; }
-
-            /// <summary>
-            /// Ignored
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "correctOrientation")]
-            public bool CorrectOrientation { get; set; }
-
-            
-
-            /// <summary>
-            /// Ignored
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "allowEdit")]
-            public bool AllowEdit { get; set; }
-
-                        /// <summary>
-            /// Height in pixels to scale image
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "encodingType")]
-            public int EncodingType { get; set; }
-
-                        /// <summary>
-            /// Height in pixels to scale image
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "mediaType")]
-            public int MediaType { get; set; }
-
-
-            /// <summary>
-            /// Height in pixels to scale image
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "targetHeight")]
-            public int TargetHeight { get; set; }
-
-
-            /// <summary>
-            /// Width in pixels to scale image
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "targetWidth")]
-            public int TargetWidth { get; set; }
-
-            /// <summary>
-            /// Creates options object with default parameters
-            /// </summary>
-            public CameraOptions()
-            {
-                this.SetDefaultValues(new StreamingContext());
-            }
-
-            /// <summary>
-            /// Initializes default values for class fields.
-            /// Implemented in separate method because default constructor is not invoked during deserialization.
-            /// </summary>
-            /// <param name="context"></param>
-            [OnDeserializing()]
-            public void SetDefaultValues(StreamingContext context)
-            {
-                PictureSourceType = CAMERA;
-                DestinationType = FILE_URI;
-                Quality = 80;
-                TargetHeight = -1;
-                TargetWidth = -1;
-                SaveToPhotoAlbum = false;
-                CorrectOrientation = true;
-                AllowEdit = false;
-                MediaType = -1;
-                EncodingType = -1;
-            }
-        }
-
-        /// <summary>
-        /// Used to open photo library
-        /// </summary>
-        PhotoChooserTask photoChooserTask;
-
-        /// <summary>
-        /// Used to open camera application
-        /// </summary>
-        CameraCaptureTask cameraTask;
-
-        /// <summary>
-        /// Camera options
-        /// </summary>
-        CameraOptions cameraOptions;
-
-        public void takePicture(string options)
-        {
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
-                //     "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
-                this.cameraOptions = new CameraOptions();
-                this.cameraOptions.Quality = int.Parse(args[0]);
-                this.cameraOptions.DestinationType = int.Parse(args[1]);
-                this.cameraOptions.PictureSourceType = int.Parse(args[2]);
-                this.cameraOptions.TargetWidth = int.Parse(args[3]);
-                this.cameraOptions.TargetHeight = int.Parse(args[4]);
-                this.cameraOptions.EncodingType = int.Parse(args[5]);
-                this.cameraOptions.MediaType = int.Parse(args[6]);
-                this.cameraOptions.AllowEdit = bool.Parse(args[7]);
-                this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
-                this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
-                
-                //this.cameraOptions = String.IsNullOrEmpty(options) ?
-                //        new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
-            }
-            catch (Exception ex)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                return;
-            }
-
-            //TODO Check if all the options are acceptable
-
-
-            if (cameraOptions.PictureSourceType == CAMERA)
-            {
-                cameraTask = new CameraCaptureTask();
-                cameraTask.Completed += onCameraTaskCompleted;
-                cameraTask.Show();
-            }
-            else
-            {
-                if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
-                {
-                    photoChooserTask = new PhotoChooserTask();
-                    photoChooserTask.Completed += onPickerTaskCompleted;
-                    photoChooserTask.Show();
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
-                }
-            }
-
-        }
-
-        public void onCameraTaskCompleted(object sender, PhotoResult e)
-        {
-            if (e.Error != null)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
-                return;
-            }
-
-            switch (e.TaskResult)
-            {
-                case TaskResult.OK:
-                    try
-                    {
-                        string imagePathOrContent = string.Empty;
-
-                        if (cameraOptions.DestinationType == FILE_URI)
-                        {
-                            // Save image in media library
-                            if (cameraOptions.SaveToPhotoAlbum)
-                            {
-                                MediaLibrary library = new MediaLibrary();
-                                Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
-                            }
-
-                            int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
-                            int newAngle = 0;
-                            switch (orient)
-                            {
-                                case ImageExifOrientation.LandscapeLeft:
-                                    newAngle = 90;
-                                    break;
-                                case ImageExifOrientation.PortraitUpsideDown:
-                                    newAngle = 180;
-                                    break;
-                                case ImageExifOrientation.LandscapeRight:
-                                    newAngle = 270;
-                                    break;
-                                case ImageExifOrientation.Portrait:
-                                default: break; // 0 default already set
-                            }
-
-                            Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
-                            // we should return stream position back after saving stream to media library
-                            rotImageStream.Seek(0, SeekOrigin.Begin);
-
-                            WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);
-
-                            imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
-
-
-                        }
-                        else if (cameraOptions.DestinationType == DATA_URL)
-                        {
-                            imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
-                        }
-                        else
-                        {
-                            // TODO: shouldn't this happen before we launch the camera-picker?
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
-                            return;
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
-                    }
-                    catch (Exception)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
-                    }
-                    break;
-
-                case TaskResult.Cancel:
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
-                    break;
-
-                default:
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
-                    break;
-            }
-
-        }
-
-        public void onPickerTaskCompleted(object sender, PhotoResult e)
-        {
-            if (e.Error != null)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
-                return;
-            }
-
-            switch (e.TaskResult)
-            {
-                case TaskResult.OK:
-                    try
-                    {
-                        string imagePathOrContent = string.Empty;
-
-                        if (cameraOptions.DestinationType == FILE_URI)
-                        {
-                            WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
-                            imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
-                        }
-                        else if (cameraOptions.DestinationType == DATA_URL)
-                        {
-                            imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
-
-                        }
-                        else
-                        {
-                            // TODO: shouldn't this happen before we launch the camera-picker?
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
-                            return;
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
-
-                    }
-                    catch (Exception)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
-                    }
-                    break;
-
-                case TaskResult.Cancel:
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
-                    break;
-
-                default:
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// Returns image content in a form of base64 string
-        /// </summary>
-        /// <param name="stream">Image stream</param>
-        /// <returns>Base64 representation of the image</returns>
-        private string GetImageContent(Stream stream)
-        {
-            int streamLength = (int)stream.Length;
-            byte[] fileData = new byte[streamLength + 1];
-            stream.Read(fileData, 0, streamLength);
-
-            //use photo's actual width & height if user doesn't provide width & height
-            if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
-            {
-                stream.Close();
-                return Convert.ToBase64String(fileData);
-            }
-            else
-            {
-                // resize photo
-                byte[] resizedFile = ResizePhoto(stream, fileData);
-                stream.Close();
-                return Convert.ToBase64String(resizedFile);
-            }
-        }
-
-        /// <summary>
-        /// Resize image
-        /// </summary>
-        /// <param name="stream">Image stream</param>
-        /// <param name="fileData">File data</param>
-        /// <returns>resized image</returns>
-        private byte[] ResizePhoto(Stream stream, byte[] fileData)
-        {
-            int streamLength = (int)stream.Length;
-            int intResult = 0;
-
-            byte[] resizedFile;
-
-            stream.Read(fileData, 0, streamLength);
-
-            BitmapImage objBitmap = new BitmapImage();
-            MemoryStream objBitmapStream = new MemoryStream(fileData);
-            MemoryStream objBitmapStreamResized = new MemoryStream();
-            WriteableBitmap objWB;
-            objBitmap.SetSource(stream);
-            objWB = new WriteableBitmap(objBitmap);
-
-            // resize the photo with user defined TargetWidth & TargetHeight
-            Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
-
-            //Convert the resized stream to a byte array. 
-            streamLength = (int)objBitmapStreamResized.Length;
-            resizedFile = new Byte[streamLength]; //-1 
-            objBitmapStreamResized.Position = 0;
-            //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo... 
-            intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);
-
-            return resizedFile;
-        }
-
-        /// <summary>
-        /// Saves captured image in isolated storage
-        /// </summary>
-        /// <param name="imageFileName">image file name</param>
-        /// <returns>Image path</returns>
-        private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
-        {
-
-            if (image == null)
-            {
-                throw new ArgumentNullException("imageBytes");
-            }
-            try
-            {
-
-
-                var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
-                if (!isoFile.DirectoryExists(isoFolder))
-                {
-                    isoFile.CreateDirectory(isoFolder);
-                }
-
-                string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);
-
-                using (var stream = isoFile.CreateFile(filePath))
-                {
-                    // resize image if Height and Width defined via options 
-                    if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
-                    {
-                        image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
-                    }
-                    else
-                    {
-                        image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
-                    }
-                }
-
-                return new Uri(filePath, UriKind.Relative).ToString();
-            }
-            catch (Exception)
-            {
-                //TODO: log or do something else
-                throw;
-            }
-        }
-
-    }
-}
diff --git a/templates/standalone/Plugins/Capture.cs b/templates/standalone/Plugins/Capture.cs
deleted file mode 100644
index 5e14a16..0000000
--- a/templates/standalone/Plugins/Capture.cs
+++ /dev/null
@@ -1,736 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Windows.Media.Imaging;
-using Microsoft.Phone;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework.Media;
-using WPCordovaClassLib.Cordova.UI;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-using System.Windows;
-using System.Diagnostics;
-using Microsoft.Phone.Controls;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides access to the audio, image, and video capture capabilities of the device
-    /// </summary>
-    public class Capture : BaseCommand
-    {
-        #region Internal classes (options and resultant objects)
-
-        /// <summary>
-        /// Represents captureImage action options.
-        /// </summary>
-        [DataContract]
-        public class CaptureImageOptions
-        {
-            /// <summary>
-            /// The maximum number of images the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "limit")]
-            public int Limit { get; set; }
-
-            public static CaptureImageOptions Default
-            {
-                get { return new CaptureImageOptions() { Limit = 1 }; }
-            }
-        }
-
-        /// <summary>
-        /// Represents captureAudio action options.
-        /// </summary>
-        [DataContract]
-        public class CaptureAudioOptions
-        {
-            /// <summary>
-            /// The maximum number of audio files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "limit")]
-            public int Limit { get; set; }
-
-            public static CaptureAudioOptions Default
-            {
-                get { return new CaptureAudioOptions() { Limit = 1 }; }
-            }
-        }
-
-        /// <summary>
-        /// Represents captureVideo action options.
-        /// </summary>
-        [DataContract]
-        public class CaptureVideoOptions
-        {
-            /// <summary>
-            /// The maximum number of video files the device user can capture in a single capture operation. The value must be greater than or equal to 1 (defaults to 1).
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "limit")]
-            public int Limit { get; set; }
-
-            public static CaptureVideoOptions Default
-            {
-                get { return new CaptureVideoOptions() { Limit = 1 }; }
-            }
-        }
-
-        /// <summary>
-        /// Represents getFormatData action options.
-        /// </summary>
-        [DataContract]
-        public class MediaFormatOptions
-        {
-            /// <summary>
-            /// File path
-            /// </summary>
-            [DataMember(IsRequired = true, Name = "fullPath")]
-            public string FullPath { get; set; }
-
-            /// <summary>
-            /// File mime type
-            /// </summary>
-            [DataMember(Name = "type")]
-            public string Type { get; set; }
-
-        }
-
-        /// <summary>
-        /// Stores image info
-        /// </summary>
-        [DataContract]
-        public class MediaFile
-        {
-
-            [DataMember(Name = "name")]
-            public string FileName { get; set; }
-
-            [DataMember(Name = "fullPath")]
-            public string FilePath { get; set; }
-
-            [DataMember(Name = "type")]
-            public string Type { get; set; }
-
-            [DataMember(Name = "lastModifiedDate")]
-            public string LastModifiedDate { get; set; }
-
-            [DataMember(Name = "size")]
-            public long Size { get; set; }
-
-            public MediaFile(string filePath, Picture image)
-            {
-                this.FilePath = filePath;
-                this.FileName = System.IO.Path.GetFileName(this.FilePath);
-                this.Type = MimeTypeMapper.GetMimeType(FileName);
-                this.Size = image.GetImage().Length;
-
-                using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
-                }
-
-            }
-
-            public MediaFile(string filePath, Stream stream)
-            {
-                this.FilePath = filePath;
-                this.FileName = System.IO.Path.GetFileName(this.FilePath);
-                this.Type = MimeTypeMapper.GetMimeType(FileName);
-                this.Size = stream.Length;
-
-                using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    this.LastModifiedDate = storage.GetLastWriteTime(filePath).DateTime.ToString();
-                }
-            }
-        }
-
-        /// <summary>
-        /// Stores additional media file data
-        /// </summary>
-        [DataContract]
-        public class MediaFileData
-        {
-            [DataMember(Name = "height")]
-            public int Height { get; set; }
-
-            [DataMember(Name = "width")]
-            public int Width { get; set; }
-
-            [DataMember(Name = "bitrate")]
-            public int Bitrate { get; set; }
-
-            [DataMember(Name = "duration")]
-            public int Duration { get; set; }
-
-            [DataMember(Name = "codecs")]
-            public string Codecs { get; set; }
-
-            public MediaFileData(WriteableBitmap image)
-            {
-                this.Height = image.PixelHeight;
-                this.Width = image.PixelWidth;
-                this.Bitrate = 0;
-                this.Duration = 0;
-                this.Codecs = "";
-            }
-        }
-
-        #endregion
-
-        /// <summary>
-        /// Folder to store captured images
-        /// </summary>
-        private string isoFolder = "CapturedImagesCache";
-
-        /// <summary>
-        /// Capture Image options
-        /// </summary>
-        protected CaptureImageOptions captureImageOptions;
-
-        /// <summary>
-        /// Capture Audio options
-        /// </summary>
-        protected CaptureAudioOptions captureAudioOptions;
-
-        /// <summary>
-        /// Capture Video options
-        /// </summary>
-        protected CaptureVideoOptions captureVideoOptions;
-
-        /// <summary>
-        /// Used to open camera application
-        /// </summary>
-        private CameraCaptureTask cameraTask;
-
-        /// <summary>
-        /// Used for audio recording
-        /// </summary>
-        private AudioCaptureTask audioCaptureTask;
-
-        /// <summary>
-        /// Used for video recording
-        /// </summary>
-        private VideoCaptureTask videoCaptureTask;
-
-        /// <summary>
-        /// Stores information about captured files
-        /// </summary>
-        List<MediaFile> files = new List<MediaFile>();
-
-        /// <summary>
-        /// Launches default camera application to capture image
-        /// </summary>
-        /// <param name="options">may contains limit or mode parameters</param>
-        public void captureImage(string options)
-        {
-            try
-            {
-                try
-                {
-
-                    string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                    this.captureImageOptions = String.IsNullOrEmpty(args) ? CaptureImageOptions.Default : JSON.JsonHelper.Deserialize<CaptureImageOptions>(args);
-
-                }
-                catch (Exception ex)
-                {
-                    this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                    return;
-                }
-
-
-                cameraTask = new CameraCaptureTask();
-                cameraTask.Completed += this.cameraTask_Completed;
-                cameraTask.Show();
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Launches our own audio recording control to capture audio
-        /// </summary>
-        /// <param name="options">may contains additional parameters</param>
-        public void captureAudio(string options)
-        {
-            try
-            {
-                try
-                {
-                    string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                    this.captureAudioOptions = String.IsNullOrEmpty(args) ? CaptureAudioOptions.Default : JSON.JsonHelper.Deserialize<CaptureAudioOptions>(args);
-
-                }
-                catch (Exception ex)
-                {
-                    this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                    return;
-                }
-
-                audioCaptureTask = new AudioCaptureTask();
-                audioCaptureTask.Completed += audioRecordingTask_Completed;
-                audioCaptureTask.Show();
-
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Launches our own video recording control to capture video
-        /// </summary>
-        /// <param name="options">may contains additional parameters</param>
-        public void captureVideo(string options)
-        {
-            try
-            {
-                try
-                {
-                    string args = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                    this.captureVideoOptions = String.IsNullOrEmpty(args) ? CaptureVideoOptions.Default : JSON.JsonHelper.Deserialize<CaptureVideoOptions>(args);
-
-                }
-                catch (Exception ex)
-                {
-                    this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                    return;
-                }
-
-                videoCaptureTask = new VideoCaptureTask();
-                videoCaptureTask.Completed += videoRecordingTask_Completed;
-                videoCaptureTask.Show();
-
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Retrieves the format information of the media file.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getFormatData(string options)
-        {
-            try
-            {
-                MediaFormatOptions mediaFormatOptions;
-                try
-                {
-                    mediaFormatOptions = new MediaFormatOptions();
-                    string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaFormatOptions.FullPath = optionStrings[0];
-                    mediaFormatOptions.Type = optionStrings[1];
-                }
-                catch (Exception ex)
-                {
-                    this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                    return;
-                }
-
-                if (string.IsNullOrEmpty(mediaFormatOptions.FullPath))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                }
-
-                string mimeType = mediaFormatOptions.Type;
-
-                if (string.IsNullOrEmpty(mimeType))
-                {
-                    mimeType = MimeTypeMapper.GetMimeType(mediaFormatOptions.FullPath);
-                }
-
-                if (mimeType.Equals("image/jpeg"))
-                {
-                    Deployment.Current.Dispatcher.BeginInvoke(() =>
-                    {
-                        WriteableBitmap image = ExtractImageFromLocalStorage(mediaFormatOptions.FullPath);
-
-                        if (image == null)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File not found"));
-                            return;
-                        }
-
-                        MediaFileData mediaData = new MediaFileData(image);
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, mediaData));
-                    });
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
-                }
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
-            }
-        }
-
-        /// <summary>
-        /// Opens specified file in media player
-        /// </summary>
-        /// <param name="options">MediaFile to play</param>
-        public void play(string options)
-        {
-            try
-            {
-                MediaFile file;
-
-                try
-                {
-                    file = String.IsNullOrEmpty(options) ? null : JSON.JsonHelper.Deserialize<MediaFile[]>(options)[0];
-
-                }
-                catch (Exception ex)
-                {
-                    this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                    return;
-                }
-
-                if (file == null || String.IsNullOrEmpty(file.FilePath))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "File path is missing"));
-                    return;
-                }
-
-                // if url starts with '/' media player throws FileNotFound exception
-                Uri fileUri = new Uri(file.FilePath.TrimStart(new char[] { '/', '\\' }), UriKind.Relative);
-
-                MediaPlayerLauncher player = new MediaPlayerLauncher();
-                player.Media = fileUri;
-                player.Location = MediaLocationType.Data;
-                player.Show();
-
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-
-        /// <summary>
-        /// Handles result of capture to save image information 
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e">stores information about current captured image</param>
-        private void cameraTask_Completed(object sender, PhotoResult e)
-        {
-
-            if (e.Error != null)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
-                return;
-            }
-
-            switch (e.TaskResult)
-            {
-                case TaskResult.OK:
-                    try
-                    {
-                        string fileName = System.IO.Path.GetFileName(e.OriginalFileName);
-
-                        // Save image in media library
-                        MediaLibrary library = new MediaLibrary();
-                        Picture image = library.SavePicture(fileName, e.ChosenPhoto);
-
-                        int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
-                        int newAngle = 0;
-                        switch (orient)
-                        {
-                            case ImageExifOrientation.LandscapeLeft:
-                                newAngle = 90;
-                                break;
-                            case ImageExifOrientation.PortraitUpsideDown:
-                                newAngle = 180;
-                                break;
-                            case ImageExifOrientation.LandscapeRight:
-                                newAngle = 270;
-                                break;
-                            case ImageExifOrientation.Portrait:
-                            default: break; // 0 default already set
-                        }
-
-                        Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);
-
-                        // Save image in isolated storage    
-
-                        // we should return stream position back after saving stream to media library
-                        rotImageStream.Seek(0, SeekOrigin.Begin);
-
-                        byte[] imageBytes = new byte[rotImageStream.Length];
-                        rotImageStream.Read(imageBytes, 0, imageBytes.Length);
-                        rotImageStream.Dispose();
-                        string pathLocalStorage = this.SaveImageToLocalStorage(fileName, isoFolder, imageBytes);
-                        imageBytes = null;
-                        // Get image data
-                        MediaFile data = new MediaFile(pathLocalStorage, image);
-
-                        this.files.Add(data);
-
-                        if (files.Count < this.captureImageOptions.Limit)
-                        {
-                            cameraTask.Show();
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                            files.Clear();
-                        }
-                    }
-                    catch (Exception)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing image."));
-                    }
-                    break;
-
-                case TaskResult.Cancel:
-                    if (files.Count > 0)
-                    {
-                        // User canceled operation, but some images were made
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                        files.Clear();
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
-                    }
-                    break;
-
-                default:
-                    if (files.Count > 0)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                        files.Clear();
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
-                    }
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// Handles result of audio recording tasks 
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e">stores information about current captured audio</param>
-        private void audioRecordingTask_Completed(object sender, AudioResult e)
-        {
-
-            if (e.Error != null)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
-                return;
-            }
-
-            switch (e.TaskResult)
-            {
-                case TaskResult.OK:
-                    try
-                    {
-                        // Get image data
-                        MediaFile data = new MediaFile(e.AudioFileName, e.AudioFile);
-
-                        this.files.Add(data);
-
-                        if (files.Count < this.captureAudioOptions.Limit)
-                        {
-                            audioCaptureTask.Show();
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                            files.Clear();
-                        }
-                    }
-                    catch (Exception)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing audio."));
-                    }
-                    break;
-
-                case TaskResult.Cancel:
-                    if (files.Count > 0)
-                    {
-                        // User canceled operation, but some audio clips were made
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                        files.Clear();
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
-                    }
-                    break;
-
-                default:
-                    if (files.Count > 0)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                        files.Clear();
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
-                    }
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// Handles result of video recording tasks 
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e">stores information about current captured video</param>
-        private void videoRecordingTask_Completed(object sender, VideoResult e)
-        {
-
-            if (e.Error != null)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
-                return;
-            }
-
-            switch (e.TaskResult)
-            {
-                case TaskResult.OK:
-                    try
-                    {
-                        // Get image data
-                        MediaFile data = new MediaFile(e.VideoFileName, e.VideoFile);
-
-                        this.files.Add(data);
-
-                        if (files.Count < this.captureVideoOptions.Limit)
-                        {
-                            videoCaptureTask.Show();
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                            files.Clear();
-                        }
-                    }
-                    catch (Exception)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error capturing video."));
-                    }
-                    break;
-
-                case TaskResult.Cancel:
-                    if (files.Count > 0)
-                    {
-                        // User canceled operation, but some video clips were made
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                        files.Clear();
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Canceled."));
-                    }
-                    break;
-
-                default:
-                    if (files.Count > 0)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, files));
-                        files.Clear();
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Did not complete!"));
-                    }
-                    break;
-            }
-        }
-
-        /// <summary>
-        /// Extract file from Isolated Storage as WriteableBitmap object
-        /// </summary>
-        /// <param name="filePath"></param>
-        /// <returns></returns>
-        private WriteableBitmap ExtractImageFromLocalStorage(string filePath)
-        {
-            try
-            {
-
-                var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
-                using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
-                {
-                    var imageSource = PictureDecoder.DecodeJpeg(imageStream);
-                    return imageSource;
-                }
-            }
-            catch (Exception)
-            {
-                return null;
-            }
-        }
-
-
-        /// <summary>
-        /// Saves captured image in isolated storage
-        /// </summary>
-        /// <param name="imageFileName">image file name</param>
-        /// <param name="imageFolder">folder to store images</param>
-        /// <returns>Image path</returns>
-        private string SaveImageToLocalStorage(string imageFileName, string imageFolder, byte[] imageBytes)
-        {
-            if (imageBytes == null)
-            {
-                throw new ArgumentNullException("imageBytes");
-            }
-            try
-            {
-                var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
-
-                if (!isoFile.DirectoryExists(imageFolder))
-                {
-                    isoFile.CreateDirectory(imageFolder);
-                }
-                string filePath = System.IO.Path.Combine("/" + imageFolder + "/", imageFileName);
-
-                using (IsolatedStorageFileStream stream = isoFile.CreateFile(filePath))
-                {
-                    stream.Write(imageBytes, 0, imageBytes.Length);
-                }
-
-                return filePath;
-            }
-            catch (Exception)
-            {
-                //TODO: log or do something else
-                throw;
-            }
-        }
-
-
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/Plugins/Compass.cs b/templates/standalone/Plugins/Compass.cs
deleted file mode 100644
index c9e1c4d..0000000
--- a/templates/standalone/Plugins/Compass.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using DeviceCompass = Microsoft.Devices.Sensors.Compass;
-using System.Windows.Threading;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Threading;
-using Microsoft.Devices.Sensors;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
-    public class Compass : BaseCommand
-    {
-        #region Static members
-
-        /// <summary>
-        /// Status of listener
-        /// </summary>
-        private static int currentStatus;
-
-        /// <summary>
-        /// Id for get getCompass method
-        /// </summary>
-        private static string getCompassId = "getCompassId";
-
-        /// <summary>
-        /// Compass
-        /// </summary>
-        private static DeviceCompass compass = new DeviceCompass();
-
-        /// <summary>
-        /// Listeners for callbacks
-        /// </summary>
-        private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
-
-        #endregion
-
-        #region Status codes
-
-        public const int Stopped = 0;
-        public const int Starting = 1;
-        public const int Running = 2;
-        public const int ErrorFailedToStart = 4;
-        public const int Not_Supported = 20;
-
-        /*
-         *   // Capture error codes
-            CompassError.COMPASS_INTERNAL_ERR = 0;
-            CompassError.COMPASS_NOT_SUPPORTED = 20;
-         * */
-
-        #endregion
-
-        #region CompassOptions class
-        /// <summary>
-        /// Represents Accelerometer options.
-        /// </summary>
-        [DataContract]
-        public class CompassOptions
-        {
-            /// <summary>
-            /// How often to retrieve the Acceleration in milliseconds
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "frequency")]
-            public int Frequency { get; set; }
-
-            /// <summary>
-            /// The change in degrees required to initiate a watchHeadingFilter success callback.
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "filter")]
-            public int Filter { get; set; }
-
-            /// <summary>
-            /// Watcher id
-            /// </summary>
-            [DataMember(IsRequired = false, Name = "id")]
-            public string Id { get; set; }
-
-        }
-        #endregion
-
-
-        /// <summary>
-        /// Time the value was last changed
-        /// </summary>
-        //private DateTime lastValueChangedTime;
-
-        /// <summary>
-        /// Accelerometer options
-        /// </summary>
-        private CompassOptions compassOptions;
-
-        //bool isDataValid;
-
-        //bool calibrating = false;
-
-        public Compass()
-        {
-
-        }
-
-        /// <summary>
-        /// Formats current coordinates into JSON format
-        /// </summary>
-        /// <returns>Coordinates in JSON format</returns>
-        private string GetHeadingFormatted(CompassReading reading)
-        {   
-            // NOTE: timestamp is generated on the JS side, to avoid issues with format conversions
-            string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2}",
-                            reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
-                            reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
-                            reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture));
-            return "{" + result + "}";
-        }
-
-        public void getHeading(string options)
-        {
-            if (!DeviceCompass.IsSupported)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
-            }
-            else
-            {
-                //if (compass == null)
-                //{
-                //    // Instantiate the compass.
-                //    compass = new DeviceCompass();
-                //    compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
-                //    compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
-                //    compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
-                //}
-
-
-                //compass.Start();
-
-            }
-
-            try
-            {
-                if (currentStatus != Running)
-                {
-                    lock (compass)
-                    {
-                        compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
-                        compass.Start();
-                        this.SetStatus(Starting);
-                    }
-
-                    long timeout = 2000;
-                    while ((currentStatus == Starting) && (timeout > 0))
-                    {
-                        timeout = timeout - 100;
-                        Thread.Sleep(100);
-                    }
-
-                    if (currentStatus != Running)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
-                        return;
-                    }
-                }
-                lock (compass)
-                {
-                    compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
-                    if (watchers.Count < 1)
-                    {
-                        compass.Stop();
-                        this.SetStatus(Stopped);
-                    }
-                }
-            }
-            catch (UnauthorizedAccessException)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
-            }
-        }
-
-        void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
-        {
-            this.SetStatus(Running);
-            if (compass.IsDataValid)
-            {
-                // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
-                //  magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time. 
-                //  A negative value indicates that the true heading could not be determined.
-                // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
-                //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
-                //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
-                PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
-
-                DispatchCommandResult(result);
-            }
-        }
-
-        /// <summary>
-        /// Starts listening for compass sensor
-        /// </summary>
-        /// <returns>status of listener</returns>
-        private int start()
-        {
-            if ((currentStatus == Running) || (currentStatus == Starting))
-            {
-                return currentStatus;
-            }
-            try
-            {
-                lock (compass)
-                {
-                    watchers.Add(getCompassId, this);
-                    compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
-                    compass.Start();
-                    this.SetStatus(Starting);
-                }
-            }
-            catch (Exception)
-            {
-                this.SetStatus(ErrorFailedToStart);
-            }
-            return currentStatus;
-        }
-
-        public void startWatch(string options)
-        {
-            if (!DeviceCompass.IsSupported)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
-            }
-
-            try
-            {
-                compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
-            }
-            catch (Exception ex)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                return;
-            }
-
-            if (string.IsNullOrEmpty(compassOptions.Id))
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                lock (compass)
-                {
-                    watchers.Add(compassOptions.Id, this);
-                    compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
-                    compass.Start();
-                    this.SetStatus(Starting);
-                }
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
-                return;
-            }
-        }
-
-        public void stopWatch(string options)
-        {
-            try
-            {
-                compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
-            }
-            catch (Exception ex)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
-                return;
-            }
-
-            if (string.IsNullOrEmpty(compassOptions.Id))
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            if (currentStatus != Stopped)
-            {
-                lock (compass)
-                {
-                    Compass watcher = watchers[compassOptions.Id];
-                    compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
-                    watchers.Remove(compassOptions.Id);
-                    watcher.Dispose();
-                }
-            }
-            this.SetStatus(Stopped);
-
-            this.DispatchCommandResult();
-        }
-
-        void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
-        {
-            //throw new NotImplementedException();
-            // TODO: pass calibration error to JS
-        }
-
-        void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
-        {
-            this.SetStatus(Running);
-            if (compass.IsDataValid)
-            {
-                // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
-                //  magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time. 
-                //  A negative value indicates that the true heading could not be determined.
-                // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
-                //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
-
-                //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
-
-                PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
-                result.KeepCallback = true;
-
-                DispatchCommandResult(result);
-            }
-        }
-
-        /// <summary>
-        /// Sets current status
-        /// </summary>
-        /// <param name="status">current status</param>
-        private void SetStatus(int status)
-        {
-            currentStatus = status;
-        }
-
-    }
-}
diff --git a/templates/standalone/Plugins/Contacts.cs b/templates/standalone/Plugins/Contacts.cs
deleted file mode 100644
index 263cc2c..0000000
--- a/templates/standalone/Plugins/Contacts.cs
+++ /dev/null
@@ -1,669 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using Microsoft.Phone.Tasks;
-using Microsoft.Phone.UserData;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Windows;
-using DeviceContacts = Microsoft.Phone.UserData.Contacts;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    [DataContract]
-    public class SearchOptions
-    {
-        [DataMember]
-        public string filter { get; set; }
-        [DataMember]
-        public bool multiple { get; set; }
-    }
-
-    [DataContract]
-    public class ContactSearchParams
-    {
-        [DataMember]
-        public string[] fields { get; set; }
-        [DataMember]
-        public SearchOptions options { get; set; }
-    }
-
-    [DataContract]
-    public class JSONContactAddress
-    {
-        [DataMember]
-        public string formatted { get; set; }
-        [DataMember]
-        public string type { get; set; }
-        [DataMember]
-        public string streetAddress { get; set; }
-        [DataMember]
-        public string locality { get; set; }
-        [DataMember]
-        public string region { get; set; }
-        [DataMember]
-        public string postalCode { get; set; }
-        [DataMember]
-        public string country { get; set; }
-        [DataMember]
-        public bool pref { get; set; }
-    }
-
-    [DataContract]
-    public class JSONContactName
-    {
-        [DataMember]
-        public string formatted { get; set; }
-        [DataMember]
-        public string familyName { get; set; }
-        [DataMember]
-        public string givenName { get; set; }
-        [DataMember]
-        public string middleName { get; set; }
-        [DataMember]
-        public string honorificPrefix { get; set; }
-        [DataMember]
-        public string honorificSuffix { get; set; }
-    }
-
-    [DataContract]
-    public class JSONContactField
-    {
-        [DataMember]
-        public string type { get; set; }
-        [DataMember]
-        public string value { get; set; }
-        [DataMember]
-        public bool pref { get; set; }
-    }
-
-    [DataContract]
-    public class JSONContactOrganization
-    {
-        [DataMember]
-        public string type { get; set; }
-        [DataMember]
-        public string name { get; set; }
-        [DataMember]
-        public bool pref { get; set; }
-        [DataMember]
-        public string department { get; set; }
-        [DataMember]
-        public string title { get; set; }
-    }
-
-    [DataContract]
-    public class JSONContact
-    {
-        [DataMember]
-        public string id { get; set; }
-        [DataMember]
-        public string rawId { get; set; }
-        [DataMember]
-        public string displayName { get; set; }
-        [DataMember]
-        public string nickname { get; set; }
-        [DataMember]
-        public string note { get; set; }
-
-        [DataMember]
-        public JSONContactName name { get; set; }
-
-        [DataMember]
-        public JSONContactField[] emails { get; set; }
-
-        [DataMember]
-        public JSONContactField[] phoneNumbers { get; set; }
-
-        [DataMember]
-        public JSONContactField[] ims { get; set; }
-
-        [DataMember]
-        public JSONContactField[] photos { get; set; }
-
-        [DataMember]
-        public JSONContactField[] categories { get; set; }
-
-        [DataMember]
-        public JSONContactField[] urls { get; set; }
-
-        [DataMember]
-        public JSONContactOrganization[] organizations { get; set; }
-
-        [DataMember]
-        public JSONContactAddress[] addresses { get; set; }
-    }
-
-
-    public class Contacts : BaseCommand
-    {
-
-        public const int UNKNOWN_ERROR = 0;
-        public const int INVALID_ARGUMENT_ERROR = 1;
-        public const int TIMEOUT_ERROR = 2;
-        public const int PENDING_OPERATION_ERROR = 3;
-        public const int IO_ERROR = 4;
-        public const int NOT_SUPPORTED_ERROR = 5;
-        public const int PERMISSION_DENIED_ERROR = 20;
-        public const int SYNTAX_ERR = 8;
-
-        public Contacts()
-        {
-
-        }
-
-        // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
-        public void save(string jsonContact)
-        {
-
-            // jsonContact is actually an array of 1 {contact}
-            string[] args = JSON.JsonHelper.Deserialize<string[]>(jsonContact);
-
-
-            JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(args[0]);
-
-            SaveContactTask contactTask = new SaveContactTask();
-
-            if (contact.nickname != null)
-            {
-                contactTask.Nickname = contact.nickname;
-            }
-            if (contact.urls != null && contact.urls.Length > 0)
-            {
-                contactTask.Website = contact.urls[0].value;
-            }
-            if (contact.note != null)
-            {
-                contactTask.Notes = contact.note;
-            }
-
-            #region contact.name
-            if (contact.name != null)
-            {
-                if (contact.name.givenName != null)
-                    contactTask.FirstName = contact.name.givenName;
-                if (contact.name.familyName != null)
-                    contactTask.LastName = contact.name.familyName;
-                if (contact.name.middleName != null)
-                    contactTask.MiddleName = contact.name.middleName;
-                if (contact.name.honorificSuffix != null)
-                    contactTask.Suffix = contact.name.honorificSuffix;
-                if (contact.name.honorificPrefix != null)
-                    contactTask.Title = contact.name.honorificPrefix;
-            }
-            #endregion
-
-            #region contact.org
-            if (contact.organizations != null && contact.organizations.Count() > 0)
-            {
-                contactTask.Company = contact.organizations[0].name;
-                contactTask.JobTitle = contact.organizations[0].title;
-            }
-            #endregion
-
-            #region contact.phoneNumbers
-            if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
-            {
-                foreach (JSONContactField field in contact.phoneNumbers)
-                {
-                    string fieldType = field.type.ToLower();
-                    if (fieldType == "work")
-                    {
-                        contactTask.WorkPhone = field.value;
-                    }
-                    else if (fieldType == "home")
-                    {
-                        contactTask.HomePhone = field.value;
-                    }
-                    else if (fieldType == "mobile")
-                    {
-                        contactTask.MobilePhone = field.value;
-                    }
-                }
-            }
-            #endregion
-
-            #region contact.emails
-
-            if (contact.emails != null && contact.emails.Length > 0)
-            {
-
-                // set up different email types if they are not explicitly defined
-                foreach (string type in new string[] { "personal", "work", "other" })
-                {
-                    foreach (JSONContactField field in contact.emails)
-                    {
-                        if (field != null && String.IsNullOrEmpty(field.type))
-                        {
-                            field.type = type;
-                            break;
-                        }
-                    }
-                }
-
-                foreach (JSONContactField field in contact.emails)
-                {
-                    if (field != null)
-                    {
-                        if (field.type != null && field.type != "other")
-                        {
-                            string fieldType = field.type.ToLower();
-                            if (fieldType == "work")
-                            {
-                                contactTask.WorkEmail = field.value;
-                            }
-                            else if (fieldType == "home" || fieldType == "personal")
-                            {
-                                contactTask.PersonalEmail = field.value;
-                            }
-                        }
-                        else
-                        {
-                            contactTask.OtherEmail = field.value;
-                        }
-                    }
-
-                }
-            }
-            #endregion
-
-            if (contact.note != null && contact.note.Length > 0)
-            {
-                contactTask.Notes = contact.note;
-            }
-
-            #region contact.addresses
-            if (contact.addresses != null && contact.addresses.Length > 0)
-            {
-                foreach (JSONContactAddress address in contact.addresses)
-                {
-                    if (address.type == null)
-                    {
-                        address.type = "home"; // set a default
-                    }
-                    string fieldType = address.type.ToLower();
-                    if (fieldType == "work")
-                    {
-                        contactTask.WorkAddressCity = address.locality;
-                        contactTask.WorkAddressCountry = address.country;
-                        contactTask.WorkAddressState = address.region;
-                        contactTask.WorkAddressStreet = address.streetAddress;
-                        contactTask.WorkAddressZipCode = address.postalCode;
-                    }
-                    else if (fieldType == "home" || fieldType == "personal")
-                    {
-                        contactTask.HomeAddressCity = address.locality;
-                        contactTask.HomeAddressCountry = address.country;
-                        contactTask.HomeAddressState = address.region;
-                        contactTask.HomeAddressStreet = address.streetAddress;
-                        contactTask.HomeAddressZipCode = address.postalCode;
-                    }
-                    else
-                    {
-                        // no other address fields available ...
-                        Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
-                    }
-                }
-            }
-            #endregion
-
-
-            contactTask.Completed += new EventHandler<SaveContactResult>(ContactSaveTaskCompleted);
-            contactTask.Show();
-        }
-
-        void ContactSaveTaskCompleted(object sender, SaveContactResult e)
-        {
-            SaveContactTask task = sender as SaveContactTask;
-
-            if (e.TaskResult == TaskResult.OK)
-            {
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    DeviceContacts deviceContacts = new DeviceContacts();
-                    deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
-
-                    string displayName = String.Format("{0}{2}{1}", task.FirstName, task.LastName, String.IsNullOrEmpty(task.FirstName) ? "" : " ");
-
-                    deviceContacts.SearchAsync(displayName, FilterKind.DisplayName, task);
-                });
-
-
-            }
-            else if (e.TaskResult == TaskResult.Cancel)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Operation cancelled."));
-            }
-        }
-
-        void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
-        {
-            if (e.Results.Count() > 0)
-            {
-                List<Contact> foundContacts = new List<Contact>();
-
-                int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
-                Contact newContact = (from Contact contact in e.Results
-                                      where contact.GetHashCode() == n
-                                      select contact).First();
-
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact, null)));
-            }
-            else
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
-            }
-        }
-
-
-
-        public void remove(string id)
-        {
-            // note id is wrapped in [] and always has exactly one string ...
-            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{\"code\":" + NOT_SUPPORTED_ERROR + "}"));
-        }
-
-        public void search(string searchCriteria)
-        {
-            string[] args = JSON.JsonHelper.Deserialize<string[]>(searchCriteria);
-
-            ContactSearchParams searchParams = new ContactSearchParams();
-            try
-            {
-                searchParams.fields = JSON.JsonHelper.Deserialize<string[]>(args[0]);
-                searchParams.options = JSON.JsonHelper.Deserialize<SearchOptions>(args[1]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_ARGUMENT_ERROR));
-                return;
-            }
-
-            //Deal with case where caller has specified no options
-            if (searchParams.options == null)
-            {
-                searchParams.options = new SearchOptions();
-                searchParams.options.filter = "";
-                searchParams.options.multiple = true;
-            }
-            else if (searchParams.options.filter == null) // Deal with the case where caller has specified partial options
-            {
-                searchParams.options.filter = "";
-            }
-
-            DeviceContacts deviceContacts = new DeviceContacts();
-            deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
-
-            // default is to search all fields
-            FilterKind filterKind = FilterKind.None;
-            // if only one field is specified, we will try the 3 available DeviceContact search filters
-            if (searchParams.fields.Count() == 1)
-            {
-                if (searchParams.fields.Contains("name"))
-                {
-                    filterKind = FilterKind.DisplayName;
-                }
-                else if (searchParams.fields.Contains("emails"))
-                {
-                    filterKind = FilterKind.EmailAddress;
-                }
-                else if (searchParams.fields.Contains("phoneNumbers"))
-                {
-                    filterKind = FilterKind.PhoneNumber;
-                }
-            }
-
-            try
-            {
-
-                deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine("search contacts exception :: " + ex.Message);
-            }
-        }
-
-        private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
-        {
-            ContactSearchParams searchParams = (ContactSearchParams)e.State;
-
-            List<Contact> foundContacts = null;
-
-            // if we have multiple search fields
-            if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
-            {
-                foundContacts = new List<Contact>();
-                if (searchParams.fields.Contains("emails"))
-                {
-                    foundContacts.AddRange(from Contact con in e.Results
-                                           from ContactEmailAddress a in con.EmailAddresses
-                                           where a.EmailAddress.Contains(searchParams.options.filter)
-                                           select con);
-                }
-                if (searchParams.fields.Contains("displayName"))
-                {
-                    foundContacts.AddRange(from Contact con in e.Results
-                                           where con.DisplayName.Contains(searchParams.options.filter)
-                                           select con);
-                }
-                if (searchParams.fields.Contains("name"))
-                {
-                    foundContacts.AddRange(from Contact con in e.Results
-                                           where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
-                                           select con);
-                }
-                if (searchParams.fields.Contains("phoneNumbers"))
-                {
-                    foundContacts.AddRange(from Contact con in e.Results
-                                           from ContactPhoneNumber a in con.PhoneNumbers
-                                           where a.PhoneNumber.Contains(searchParams.options.filter)
-                                           select con);
-                }
-                if (searchParams.fields.Contains("urls"))
-                {
-                    foundContacts.AddRange(from Contact con in e.Results
-                                           from string a in con.Websites
-                                           where a.Contains(searchParams.options.filter)
-                                           select con);
-                }
-            }
-            else
-            {
-                foundContacts = new List<Contact>(e.Results);
-            }
-
-            //List<string> contactList = new List<string>();
-
-            string strResult = "";
-
-            IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
-
-            foreach (Contact contact in distinctContacts)
-            {
-                strResult += FormatJSONContact(contact, null) + ",";
-                //contactList.Add(FormatJSONContact(contact, null));
-                if (!searchParams.options.multiple)
-                {
-                    break; // just return the first item
-                }
-            }
-            PluginResult result = new PluginResult(PluginResult.Status.OK);
-            result.Message = "[" + strResult.TrimEnd(',') + "]";
-            DispatchCommandResult(result);
-
-        }
-
-        private string FormatJSONPhoneNumbers(Contact con)
-        {
-            string retVal = "";
-            string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
-            foreach (ContactPhoneNumber number in con.PhoneNumbers)
-            {
-
-                string contactField = string.Format(contactFieldFormat,
-                                                    number.Kind.ToString(),
-                                                    number.PhoneNumber);
-
-                retVal += "{" + contactField + "},";
-            }
-            return retVal.TrimEnd(',');
-        }
-
-        private string FormatJSONEmails(Contact con)
-        {
-            string retVal = "";
-            string contactFieldFormat = "\"type\":\"{0}\",\"value\":\"{1}\",\"pref\":\"false\"";
-            foreach (ContactEmailAddress address in con.EmailAddresses)
-            {
-                string contactField = string.Format(contactFieldFormat,
-                                                    address.Kind.ToString(),
-                                                    address.EmailAddress);
-
-                retVal += "{" + contactField + "},";
-            }
-            return retVal.TrimEnd(',');
-        }
-
-        private string getFormattedJSONAddress(ContactAddress address, bool isPreferred)
-        {
-
-            string addressFormatString = "\"pref\":{0}," + // bool
-                          "\"type\":\"{1}\"," +
-                          "\"formatted\":\"{2}\"," +
-                          "\"streetAddress\":\"{3}\"," +
-                          "\"locality\":\"{4}\"," +
-                          "\"region\":\"{5}\"," +
-                          "\"postalCode\":\"{6}\"," +
-                          "\"country\":\"{7}\"";
-
-            string formattedAddress = address.PhysicalAddress.AddressLine1 + " "
-                                    + address.PhysicalAddress.AddressLine2 + " "
-                                    + address.PhysicalAddress.City + " "
-                                    + address.PhysicalAddress.StateProvince + " "
-                                    + address.PhysicalAddress.CountryRegion + " "
-                                    + address.PhysicalAddress.PostalCode;
-
-            string jsonAddress = string.Format(addressFormatString,
-                                               isPreferred ? "\"true\"" : "\"false\"",
-                                               address.Kind.ToString(),
-                                               formattedAddress,
-                                               address.PhysicalAddress.AddressLine1 + " " + address.PhysicalAddress.AddressLine2,
-                                               address.PhysicalAddress.City,
-                                               address.PhysicalAddress.StateProvince,
-                                               address.PhysicalAddress.PostalCode,
-                                               address.PhysicalAddress.CountryRegion);
-
-            //Debug.WriteLine("getFormattedJSONAddress returning :: " + jsonAddress);
-
-            return "{" + jsonAddress + "}";
-        }
-
-        private string FormatJSONAddresses(Contact con)
-        {
-            string retVal = "";
-            foreach (ContactAddress address in con.Addresses)
-            {
-                retVal += this.getFormattedJSONAddress(address, false) + ",";
-            }
-
-            //Debug.WriteLine("FormatJSONAddresses returning :: " + retVal);
-            return retVal.TrimEnd(',');
-        }
-
-        private string FormatJSONWebsites(Contact con)
-        {
-            string retVal = "";
-            foreach (string website in con.Websites)
-            {
-                retVal += "\"" + website + "\",";
-            }
-            return retVal.TrimEnd(',');
-        }
-
-        /*
-         *  formatted: The complete name of the contact. (DOMString)
-            familyName: The contacts family name. (DOMString)
-            givenName: The contacts given name. (DOMString)
-            middleName: The contacts middle name. (DOMString)
-            honorificPrefix: The contacts prefix (example Mr. or Dr.) (DOMString)
-            honorificSuffix: The contacts suffix (example Esq.). (DOMString)
-         */
-        private string FormatJSONName(Contact con)
-        {
-            string retVal = "";
-            string formatStr = "\"formatted\":\"{0}\"," +
-                                "\"familyName\":\"{1}\"," +
-                                "\"givenName\":\"{2}\"," +
-                                "\"middleName\":\"{3}\"," +
-                                "\"honorificPrefix\":\"{4}\"," +
-                                "\"honorificSuffix\":\"{5}\"";
-
-            if (con.CompleteName != null)
-            {
-                retVal = string.Format(formatStr,
-                                   con.CompleteName.FirstName + " " + con.CompleteName.LastName, // TODO: does this need suffix? middlename?
-                                   con.CompleteName.LastName,
-                                   con.CompleteName.FirstName,
-                                   con.CompleteName.MiddleName,
-                                   con.CompleteName.Title,
-                                   con.CompleteName.Suffix);
-            }
-            else
-            {
-                retVal = string.Format(formatStr, "", "", "", "", "", "");
-            }
-
-            return "{" + retVal + "}";
-        }
-
-        private string FormatJSONContact(Contact con, string[] fields)
-        {
-
-            string contactFormatStr = "\"id\":\"{0}\"," +
-                                      "\"displayName\":\"{1}\"," +
-                                      "\"nickname\":\"{2}\"," +
-                                      "\"phoneNumbers\":[{3}]," +
-                                      "\"emails\":[{4}]," +
-                                      "\"addresses\":[{5}]," +
-                                      "\"urls\":[{6}]," +
-                                      "\"name\":{7}," +
-                                      "\"note\":\"{8}\"," +
-                                      "\"birthday\":\"{9}\"";
-
-
-            string jsonContact = String.Format(contactFormatStr,
-                                               con.GetHashCode(),
-                                               con.DisplayName,
-                                               con.CompleteName != null ? con.CompleteName.Nickname : "",
-                                               FormatJSONPhoneNumbers(con),
-                                               FormatJSONEmails(con),
-                                               FormatJSONAddresses(con),
-                                               FormatJSONWebsites(con),
-                                               FormatJSONName(con),
-                                               con.Notes.FirstOrDefault(),
-                                               con.Birthdays.FirstOrDefault());
-
-            //Debug.WriteLine("jsonContact = " + jsonContact);
-            // JSON requires new line characters be escaped
-            return "{" + jsonContact.Replace("\n", "\\n") + "}";
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/DebugConsole.cs b/templates/standalone/Plugins/DebugConsole.cs
deleted file mode 100644
index fa9863a..0000000
--- a/templates/standalone/Plugins/DebugConsole.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
-    public class DebugConsole : BaseCommand
-    {
-        // warn, error
-        public void log(string msg)
-        {
-            Debug.WriteLine("Log:" + msg);
-        }
-
-        public void error(string msg)
-        {
-            Debug.WriteLine("Error:" + msg);
-        }
-
-        public void warn(string msg)
-        {
-            Debug.WriteLine("Warn:" + msg);
-        }
-
-    }
-}
diff --git a/templates/standalone/Plugins/Device.cs b/templates/standalone/Plugins/Device.cs
deleted file mode 100644
index 6fb9913..0000000
--- a/templates/standalone/Plugins/Device.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Info;
-using System.IO.IsolatedStorage;
-using System.Windows.Resources;
-using System.IO;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class Device : BaseCommand
-    {
-        public void getDeviceInfo(string notused)
-        {
-
-            string res = String.Format("\"name\":\"{0}\",\"cordova\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\",\"model\":\"{5}\"",
-                                        this.name,
-                                        this.cordova,
-                                        this.platform,
-                                        this.uuid,
-                                        this.version,
-                                        this.model);
-
-
-
-            res = "{" + res + "}";
-            //Debug.WriteLine("Result::" + res);
-            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
-        }
-
-        public string model
-        {
-            get
-            {
-                return DeviceStatus.DeviceName;
-                //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion); 
-            }
-        }
-
-        public string name
-        {
-            get
-            {
-                return DeviceStatus.DeviceName;
-                
-            }
-        }
-
-        public string cordova
-        {
-            get
-            {
-                // TODO: should be able to dynamically read the Cordova version from somewhere...
-                return "2.9.0";
-            }
-        }
-
-        public string platform
-        {
-            get
-            {
-                return Environment.OSVersion.Platform.ToString();
-            }
-        }
-
-        public string uuid
-        {
-            get
-            {
-                string returnVal = "";
-                object id;
-                UserExtendedProperties.TryGetValue("ANID", out id);
-
-                if (id != null)
-                {
-                    returnVal = id.ToString().Substring(2, 32);
-                }
-                else
-                {
-                    returnVal = "???unknown???";
-
-                    using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        try
-                        {
-                            IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
-
-                            using (StreamReader reader = new StreamReader(fileStream))
-                            {
-                                returnVal = reader.ReadLine();
-                            }
-                        }
-                        catch (Exception /*ex*/)
-                        {
-
-                        }
-                    }
-                }
-
-                return returnVal;
-            }
-        }
-
-        public string version
-        {
-            get
-            {
-                return Environment.OSVersion.Version.ToString();
-            }
-        }
-
-    }
-}
diff --git a/templates/standalone/Plugins/File.cs b/templates/standalone/Plugins/File.cs
deleted file mode 100644
index cde7a1c..0000000
--- a/templates/standalone/Plugins/File.cs
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Security;
-using System.Text;
-using System.Windows;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides access to isolated storage
-    /// </summary>
-    public class File : BaseCommand
-    {
-        // Error codes
-        public const int NOT_FOUND_ERR = 1;
-        public const int SECURITY_ERR = 2;
-        public const int ABORT_ERR = 3;
-        public const int NOT_READABLE_ERR = 4;
-        public const int ENCODING_ERR = 5;
-        public const int NO_MODIFICATION_ALLOWED_ERR = 6;
-        public const int INVALID_STATE_ERR = 7;
-        public const int SYNTAX_ERR = 8;
-        public const int INVALID_MODIFICATION_ERR = 9;
-        public const int QUOTA_EXCEEDED_ERR = 10;
-        public const int TYPE_MISMATCH_ERR = 11;
-        public const int PATH_EXISTS_ERR = 12;
-
-        // File system options
-        public const int TEMPORARY = 0;
-        public const int PERSISTENT = 1;
-        public const int RESOURCE = 2;
-        public const int APPLICATION = 3;
-
-        /// <summary>
-        /// Temporary directory name
-        /// </summary>
-        private readonly string TMP_DIRECTORY_NAME = "tmp";
-
-        /// <summary>
-        /// Represents error code for callback
-        /// </summary>
-        [DataContract]
-        public class ErrorCode
-        {
-            /// <summary>
-            /// Error code
-            /// </summary>
-            [DataMember(IsRequired = true, Name = "code")]
-            public int Code { get; set; }
-
-            /// <summary>
-            /// Creates ErrorCode object
-            /// </summary>
-            public ErrorCode(int code)
-            {
-                this.Code = code;
-            }
-        }
-
-        /// <summary>
-        /// Represents File action options.
-        /// </summary>
-        [DataContract]
-        public class FileOptions
-        {
-            /// <summary>
-            /// File path
-            /// </summary>
-            /// 
-            private string _fileName;
-            [DataMember(Name = "fileName")]
-            public string FilePath
-            {
-                get
-                {
-                    return this._fileName;
-                }
-
-                set
-                {
-                    int index = value.IndexOfAny(new char[] { '#', '?' });
-                    this._fileName = index > -1 ? value.Substring(0, index) : value;
-                }
-            }
-
-            /// <summary>
-            /// Full entryPath
-            /// </summary>
-            [DataMember(Name = "fullPath")]
-            public string FullPath { get; set; }
-
-            /// <summary>
-            /// Directory name
-            /// </summary>
-            [DataMember(Name = "dirName")]
-            public string DirectoryName { get; set; }
-
-            /// <summary>
-            /// Path to create file/directory
-            /// </summary>
-            [DataMember(Name = "path")]
-            public string Path { get; set; }
-
-            /// <summary>
-            /// The encoding to use to encode the file's content. Default is UTF8.
-            /// </summary>
-            [DataMember(Name = "encoding")]
-            public string Encoding { get; set; }
-
-            /// <summary>
-            /// Uri to get file
-            /// </summary>
-            /// 
-            private string _uri;
-            [DataMember(Name = "uri")]
-            public string Uri
-            {
-                get
-                {
-                    return this._uri;
-                }
-
-                set
-                {
-                    int index = value.IndexOfAny(new char[] { '#', '?' });
-                    this._uri = index > -1 ? value.Substring(0, index) : value;
-                }
-            }
-
-            /// <summary>
-            /// Size to truncate file
-            /// </summary>
-            [DataMember(Name = "size")]
-            public long Size { get; set; }
-
-            /// <summary>
-            /// Data to write in file
-            /// </summary>
-            [DataMember(Name = "data")]
-            public string Data { get; set; }
-
-            /// <summary>
-            /// Position the writing starts with
-            /// </summary>
-            [DataMember(Name = "position")]
-            public int Position { get; set; }
-
-            /// <summary>
-            /// Type of file system requested
-            /// </summary>
-            [DataMember(Name = "type")]
-            public int FileSystemType { get; set; }
-
-            /// <summary>
-            /// New file/directory name
-            /// </summary>
-            [DataMember(Name = "newName")]
-            public string NewName { get; set; }
-
-            /// <summary>
-            /// Destination directory to copy/move file/directory
-            /// </summary>
-            [DataMember(Name = "parent")]
-            public string Parent { get; set; }
-
-            /// <summary>
-            /// Options for getFile/getDirectory methods
-            /// </summary>
-            [DataMember(Name = "options")]
-            public CreatingOptions CreatingOpt { get; set; }
-
-            /// <summary>
-            /// Creates options object with default parameters
-            /// </summary>
-            public FileOptions()
-            {
-                this.SetDefaultValues(new StreamingContext());
-            }
-
-            /// <summary>
-            /// Initializes default values for class fields.
-            /// Implemented in separate method because default constructor is not invoked during deserialization.
-            /// </summary>
-            /// <param name="context"></param>
-            [OnDeserializing()]
-            public void SetDefaultValues(StreamingContext context)
-            {
-                this.Encoding = "UTF-8";
-                this.FilePath = "";
-                this.FileSystemType = -1; 
-            }
-        }
-
-        /// <summary>
-        /// Stores image info
-        /// </summary>
-        [DataContract]
-        public class FileMetadata
-        {
-            [DataMember(Name = "fileName")]
-            public string FileName { get; set; }
-
-            [DataMember(Name = "fullPath")]
-            public string FullPath { get; set; }
-
-            [DataMember(Name = "type")]
-            public string Type { get; set; }
-
-            [DataMember(Name = "lastModifiedDate")]
-            public string LastModifiedDate { get; set; }
-
-            [DataMember(Name = "size")]
-            public long Size { get; set; }
-
-            public FileMetadata(string filePath)
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    if (string.IsNullOrEmpty(filePath))
-                    {
-                        throw new FileNotFoundException("File doesn't exist");
-                    }
-                    else if (!isoFile.FileExists(filePath))
-                    {
-                        // attempt to get it from the resources
-                        if (filePath.IndexOf("www") == 0)
-                        {
-                            Uri fileUri = new Uri(filePath, UriKind.Relative);
-                            StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
-                            if (streamInfo != null)
-                            {
-                                this.Size = streamInfo.Stream.Length;
-                                this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
-                                this.FullPath = filePath;
-                            }
-                        }
-                        else
-                        {
-                            throw new FileNotFoundException("File doesn't exist");
-                        }
-                    }
-                    else
-                    {
-                        //TODO get file size the other way if possible                
-                        using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
-                        {
-                            this.Size = stream.Length;
-                        }
-                        this.FullPath = filePath;
-                        this.FileName = System.IO.Path.GetFileName(filePath);
-                        this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
-                    }
-                    this.Type = MimeTypeMapper.GetMimeType(this.FileName);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Represents file or directory modification metadata
-        /// </summary>
-        [DataContract]
-        public class ModificationMetadata
-        {
-            /// <summary>
-            /// Modification time
-            /// </summary>
-            [DataMember]
-            public string modificationTime { get; set; }
-        }
-
-        /// <summary>
-        /// Represents file or directory entry
-        /// </summary>
-        [DataContract]
-        public class FileEntry
-        {
-
-            /// <summary>
-            /// File type
-            /// </summary>
-            [DataMember(Name = "isFile")]
-            public bool IsFile { get; set; }
-
-            /// <summary>
-            /// Directory type
-            /// </summary>
-            [DataMember(Name = "isDirectory")]
-            public bool IsDirectory { get; set; }
-
-            /// <summary>
-            /// File/directory name
-            /// </summary>
-            [DataMember(Name = "name")]
-            public string Name { get; set; }
-
-            /// <summary>
-            /// Full path to file/directory
-            /// </summary>
-            [DataMember(Name = "fullPath")]
-            public string FullPath { get; set; }
-
-            public bool IsResource { get; set; }
-
-            public static FileEntry GetEntry(string filePath, bool bIsRes=false)
-            {
-                FileEntry entry = null;
-                try
-                {
-                    entry = new FileEntry(filePath, bIsRes);
-
-                }
-                catch (Exception ex)
-                {
-                    Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
-                }
-                return entry;
-            }
-
-            /// <summary>
-            /// Creates object and sets necessary properties
-            /// </summary>
-            /// <param name="filePath"></param>
-            public FileEntry(string filePath, bool bIsRes = false)
-            {
-                if (string.IsNullOrEmpty(filePath))
-                {
-                    throw new ArgumentException();
-                }
-
-                if(filePath.Contains(" ")) 
-                {
-                    Debug.WriteLine("FilePath with spaces :: " +  filePath);
-                }
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    IsResource = bIsRes;
-                    IsFile = isoFile.FileExists(filePath);
-                    IsDirectory = isoFile.DirectoryExists(filePath);
-                    if (IsFile)
-                    {
-                        this.Name = Path.GetFileName(filePath);
-                    }
-                    else if (IsDirectory)
-                    {
-                        this.Name = this.GetDirectoryName(filePath);
-                        if (string.IsNullOrEmpty(Name))
-                        {
-                            this.Name = "/";
-                        }
-                    }
-                    else
-                    {
-                        if (IsResource)
-                        {
-                            this.Name = Path.GetFileName(filePath);
-                        }
-                        else
-                        {
-                            throw new FileNotFoundException();
-                        }
-                    }
-
-                    try
-                    {
-                        this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
-                    }
-                    catch (Exception)
-                    {
-                        this.FullPath = filePath;
-                    }
-                }
-            }
-
-            /// <summary>
-            /// Extracts directory name from path string
-            /// Path should refer to a directory, for example \foo\ or /foo.
-            /// </summary>
-            /// <param name="path"></param>
-            /// <returns></returns>
-            private string GetDirectoryName(string path)
-            {
-                if (String.IsNullOrEmpty(path))
-                {
-                    return path;
-                }
-
-                string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
-                if (split.Length < 1)
-                {
-                    return null;
-                }
-                else
-                {
-                    return split[split.Length - 1];
-                }
-            }
-        }
-
-
-        /// <summary>
-        /// Represents info about requested file system
-        /// </summary>
-        [DataContract]
-        public class FileSystemInfo
-        {
-            /// <summary>
-            /// file system type
-            /// </summary>
-            [DataMember(Name = "name", IsRequired = true)]
-            public string Name { get; set; }
-
-            /// <summary>
-            /// Root directory entry
-            /// </summary>
-            [DataMember(Name = "root", EmitDefaultValue = false)]
-            public FileEntry Root { get; set; }
-
-            /// <summary>
-            /// Creates class instance
-            /// </summary>
-            /// <param name="name"></param>
-            /// <param name="rootEntry"> Root directory</param>
-            public FileSystemInfo(string name, FileEntry rootEntry = null)
-            {
-                Name = name;
-                Root = rootEntry;
-            }
-        }
-
-        [DataContract]
-        public class CreatingOptions
-        {
-            /// <summary>
-            /// Create file/directory if is doesn't exist
-            /// </summary>
-            [DataMember(Name = "create")]
-            public bool Create { get; set; }
-
-            /// <summary>
-            /// Generate an exception if create=true and file/directory already exists
-            /// </summary>
-            [DataMember(Name = "exclusive")]
-            public bool Exclusive { get; set; }
-
-
-        }
-
-        // returns null value if it fails.
-        private string[] getOptionStrings(string options)
-        {
-            string[] optStings = null;
-            try
-            {
-                optStings = JSON.JsonHelper.Deserialize<string[]>(options);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
-            }
-            return optStings;
-        }
-
-        /// <summary>
-        /// Gets amount of free space available for Isolated Storage
-        /// </summary>
-        /// <param name="options">No options is needed for this method</param>
-        public void getFreeDiskSpace(string options)
-        {
-            string callbackId = getOptionStrings(options)[0];
-
-            try
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
-                }
-            }
-            catch (IsolatedStorageException)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Check if file exists
-        /// </summary>
-        /// <param name="options">File path</param>
-        public void testFileExists(string options)
-        {
-            IsDirectoryOrFileExist(options, false);
-        }
-
-        /// <summary>
-        /// Check if directory exists
-        /// </summary>
-        /// <param name="options">directory name</param>
-        public void testDirectoryExists(string options)
-        {
-            IsDirectoryOrFileExist(options, true);
-        }
-
-        /// <summary>
-        /// Check if file or directory exist
-        /// </summary>
-        /// <param name="options">File path/Directory name</param>
-        /// <param name="isDirectory">Flag to recognize what we should check</param>
-        public void IsDirectoryOrFileExist(string options, bool isDirectory)
-        {
-            string[] args = getOptionStrings(options);
-            string callbackId = args[1];
-            FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
-            string filePath = args[0];
-
-            if (fileOptions == null)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
-            }
-
-            try
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    bool isExist;
-                    if (isDirectory)
-                    {
-                        isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
-                    }
-                    else
-                    {
-                        isExist = isoFile.FileExists(fileOptions.FilePath);
-                    }
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
-                }
-            }
-            catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                }
-            }
-
-        }
-
-        public void readAsDataURL(string options)
-        {
-            string[] optStrings = getOptionStrings(options);
-            string filePath = optStrings[0];
-            int startPos = int.Parse(optStrings[1]);
-            int endPos = int.Parse(optStrings[2]);
-            string callbackId = optStrings[3];
-
-            if (filePath != null)
-            {
-                try
-                {
-                    string base64URL = null;
-
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (!isoFile.FileExists(filePath))
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                            return;
-                        }
-                        string mimeType = MimeTypeMapper.GetMimeType(filePath);
-
-                        using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
-                        {
-                            string base64String = GetFileContent(stream);
-                            base64URL = "data:" + mimeType + ";base64," + base64String;
-                        }
-                    }
-
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
-                }
-                catch (Exception ex)
-                {
-                    if (!this.HandleException(ex))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                    }
-                }
-            }
-        }
-
-        public void readAsArrayBuffer(string options)
-        {
-            string[] optStrings = getOptionStrings(options);
-            string filePath = optStrings[0];
-            int startPos = int.Parse(optStrings[1]);
-            int endPos = int.Parse(optStrings[2]);
-            string callbackId = optStrings[3];
-            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
-        }
-
-        public void readAsBinaryString(string options)
-        {
-            string[] optStrings = getOptionStrings(options);
-            string filePath = optStrings[0];
-            int startPos = int.Parse(optStrings[1]);
-            int endPos = int.Parse(optStrings[2]);
-            string callbackId = optStrings[3];
-            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
-        }
-
-        public void readAsText(string options)
-        {
-            string[] optStrings = getOptionStrings(options);
-            string filePath = optStrings[0];
-            string encStr = optStrings[1];
-            int startPos = int.Parse(optStrings[2]);
-            int endPos = int.Parse(optStrings[3]);
-            string callbackId = optStrings[4];
-
-            try
-            {
-                string text = "";
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    if (!isoFile.FileExists(filePath))
-                    {
-                        readResourceAsText(options);
-                        return;
-                    }
-                    Encoding encoding = Encoding.GetEncoding(encStr);
-
-                    using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
-                    {
-                        text = reader.ReadToEnd();
-                        if (startPos < 0)
-                        {
-                            startPos = Math.Max(text.Length + startPos, 0);
-                        }
-                        else if (startPos > 0)
-                        {
-                            startPos = Math.Min(text.Length, startPos);
-                        }
-
-                        if (endPos > 0)
-                        {
-                            endPos = Math.Min(text.Length, endPos);
-                        }
-                        else if (endPos < 0)
-                        {
-                            endPos = Math.Max(endPos + text.Length, 0);
-                        }
-                        
-                        
-                        text = text.Substring(startPos, endPos - startPos);
-                        
-                    }
-                }
-
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex, callbackId))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Reads application resource as a text
-        /// </summary>
-        /// <param name="options">Path to a resource</param>
-        public void readResourceAsText(string options)
-        {
-            string[] optStrings = getOptionStrings(options);
-            string pathToResource = optStrings[0];
-            string encStr = optStrings[1];
-            int start = int.Parse(optStrings[2]);
-            int endMarker = int.Parse(optStrings[3]);
-            string callbackId = optStrings[4];
-
-            try
-            {
-                if (pathToResource.StartsWith("/"))
-                {
-                    pathToResource = pathToResource.Remove(0, 1);
-                }
-                
-                var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
-                
-                if (resource == null)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                    return;
-                }
-
-                string text;
-                StreamReader streamReader = new StreamReader(resource.Stream);
-                text = streamReader.ReadToEnd();
-
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex, callbackId))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                }
-            }
-        }
-
-        public void truncate(string options)
-        {
-            string[] optStrings = getOptionStrings(options);
-
-            string filePath = optStrings[0];
-            int size = int.Parse(optStrings[1]);
-            string callbackId = optStrings[2];
-
-            try
-            {
-                long streamLength = 0;
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    if (!isoFile.FileExists(filePath))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                        return;
-                    }
-
-                    using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
-                    {
-                        if (0 <= size && size <= stream.Length)
-                        {
-                            stream.SetLength(size);
-                        }
-                        streamLength = stream.Length;
-                    }
-                }
-
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex, callbackId))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                }
-            }
-        }
-
-        //write:["filePath","data","position"],
-        public void write(string options)
-        {
-            // TODO: try/catch
-            string[] optStrings = getOptionStrings(options);
-
-            string filePath = optStrings[0];
-            string data = optStrings[1];
-            int position = int.Parse(optStrings[2]);
-            string callbackId = optStrings[3];
-
-            try
-            {
-                if (string.IsNullOrEmpty(data))
-                {
-                    Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
-                    return;
-                }
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    // create the file if not exists
-                    if (!isoFile.FileExists(filePath))
-                    {
-                        var file = isoFile.CreateFile(filePath);
-                        file.Close();
-                    }
-
-                    using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
-                    {
-                        if (0 <= position && position <= stream.Length)
-                        {
-                            stream.SetLength(position);
-                        }
-                        using (BinaryWriter writer = new BinaryWriter(stream))
-                        {
-                            writer.Seek(0, SeekOrigin.End);
-                            writer.Write(data.ToCharArray());
-                        }
-                    }
-                }
-
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex, callbackId))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Look up metadata about this entry.
-        /// </summary>
-        /// <param name="options">filePath to entry</param>   
-        public void getMetadata(string options)
-        {
-            string[] optStings = getOptionStrings(options);
-            string filePath = optStings[0];
-            string callbackId = optStings[1];
-
-            if (filePath != null)
-            {
-                try
-                {
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (isoFile.FileExists(filePath))
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
-                                new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
-                        }
-                        else if (isoFile.DirectoryExists(filePath))
-                        {
-                            string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                        }
-
-                    }
-                }
-                catch (IsolatedStorageException)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                }
-                catch (Exception ex)
-                {
-                    if (!this.HandleException(ex))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                    }
-                }
-            }
-
-        }
-
-
-        /// <summary>
-        /// Returns a File that represents the current state of the file that this FileEntry represents.
-        /// </summary>
-        /// <param name="filePath">filePath to entry</param>
-        /// <returns></returns>
-        public void getFileMetadata(string options)
-        {
-            string[] optStings = getOptionStrings(options);
-            string filePath = optStings[0];
-            string callbackId = optStings[1];
-
-            if (filePath != null)
-            {
-                try
-                {
-                    FileMetadata metaData = new FileMetadata(filePath);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
-                }
-                catch (IsolatedStorageException)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                }
-                catch (Exception ex)
-                {
-                    if (!this.HandleException(ex))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Look up the parent DirectoryEntry containing this Entry. 
-        /// If this Entry is the root of IsolatedStorage, its parent is itself.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getParent(string options)
-        {
-            string[] optStings = getOptionStrings(options);
-            string filePath = optStings[0];
-            string callbackId = optStings[1];
-
-            if (filePath != null)
-            {
-                try
-                {
-                    if (string.IsNullOrEmpty(filePath))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
-                        return;
-                    }
-
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        FileEntry entry;
-
-                        if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
-                        {
-                           
-                             
-                            string path = this.GetParentDirectory(filePath);
-                            entry = FileEntry.GetEntry(path);
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
-                        }
-
-                    }
-                }
-                catch (Exception ex)
-                {
-                    if (!this.HandleException(ex))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
-                    }
-                }
-            }
-        }
-
-        public void remove(string options)
-        {
-            string[] args = getOptionStrings(options);
-            string filePath = args[0];
-            string callbackId = args[1];
-
-            if (filePath != null)
-            {
-                try
-                {
-                    if (filePath == "/" || filePath == "" || filePath == @"\")
-                    {
-                        throw new Exception("Cannot delete root file system") ;
-                    }
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (isoFile.FileExists(filePath))
-                        {
-                            isoFile.DeleteFile(filePath);
-                        }
-                        else
-                        {
-                            if (isoFile.DirectoryExists(filePath))
-                            {
-                                isoFile.DeleteDirectory(filePath);
-                            }
-                            else
-                            {
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
-                                return;
-                            }
-                        }
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
-                    }
-                }
-                catch (Exception ex)
-                {
-                    if (!this.HandleException(ex))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
-                    }
-                }
-            }
-        }
-
-        public void removeRecursively(string options)
-        {
-            string[] args = getOptionStrings(options);
-            string filePath = args[0];
-            string callbackId = args[1];
-
-            if (filePath != null)
-            {
-                if (string.IsNullOrEmpty(filePath))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
-                }
-                else
-                {
-                    if (removeDirRecursively(filePath, callbackId))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
-                    }
-                }
-            }
-        }
-
-        public void readEntries(string options)
-        {
-            string[] args = getOptionStrings(options);
-            string filePath = args[0];
-            string callbackId = args[1];
-
-            if (filePath != null)
-            {
-                try
-                {
-                    if (string.IsNullOrEmpty(filePath))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
-                        return;
-                    }
-
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (isoFile.DirectoryExists(filePath))
-                        {
-                            string path = File.AddSlashToDirectory(filePath);
-                            List<FileEntry> entries = new List<FileEntry>();
-                            string[] files = isoFile.GetFileNames(path + "*");
-                            string[] dirs = isoFile.GetDirectoryNames(path + "*");
-                            foreach (string file in files)
-                            {
-                                entries.Add(FileEntry.GetEntry(path + file));
-                            }
-                            foreach (string dir in dirs)
-                            {
-                                entries.Add(FileEntry.GetEntry(path + dir + "/"));
-                            }
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
-                        }
-                    }
-                }
-                catch (Exception ex)
-                {
-                    if (!this.HandleException(ex))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
-                    }
-                }
-            }
-        }
-
-        public void requestFileSystem(string options)
-        {
-            // TODO: try/catch
-            string[] optVals = getOptionStrings(options);
-            //FileOptions fileOptions = new FileOptions();
-            int fileSystemType = int.Parse(optVals[0]);
-            double size = double.Parse(optVals[1]);
-            string callbackId = optVals[2];
-
-
-            IsolatedStorageFile.GetUserStoreForApplication();
-
-            if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
-                return;
-            }
-
-            try
-            {
-                if (size != 0)
-                {
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        long availableSize = isoFile.AvailableFreeSpace;
-                        if (size > availableSize)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
-                            return;
-                        }
-                    }
-                }
-
-                if (fileSystemType == PERSISTENT)
-                {
-                    // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
-                }
-                else if (fileSystemType == TEMPORARY)
-                {
-                    using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
-                        {
-                            isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
-                        }
-                    }
-
-                    string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
-
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
-                }
-                else if (fileSystemType == RESOURCE)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
-                }
-                else if (fileSystemType == APPLICATION)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
-                }
-
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
-                }
-            }
-        }
-
-        public void resolveLocalFileSystemURI(string options)
-        {
-
-            string[] optVals = getOptionStrings(options);
-            string uri = optVals[0].Split('?')[0];
-            string callbackId = optVals[1];
-
-            if (uri != null)
-            {
-                // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
-                if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
-                {
-                     DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
-                     return;
-                }
-                try
-                {
-                    // fix encoded spaces
-                    string path = Uri.UnescapeDataString(uri);
-
-                    FileEntry uriEntry = FileEntry.GetEntry(path);
-                    if (uriEntry != null)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                    }
-                }
-                catch (Exception ex)
-                {
-                    if (!this.HandleException(ex, callbackId))
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
-                    }
-                }
-            }
-        }
-
-        public void copyTo(string options)
-        {
-            TransferTo(options, false);
-        }
-
-        public void moveTo(string options)
-        {
-            TransferTo(options, true);
-        }
-
-        public void getFile(string options)
-        {
-            GetFileOrDirectory(options, false);
-        }
-
-        public void getDirectory(string options)
-        {
-            GetFileOrDirectory(options, true);
-        }
-
-        #region internal functionality
-
-        /// <summary>
-        /// Retrieves the parent directory name of the specified path,
-        /// </summary>
-        /// <param name="path">Path</param>
-        /// <returns>Parent directory name</returns>
-        private string GetParentDirectory(string path)
-        {
-            if (String.IsNullOrEmpty(path) || path == "/")
-            {
-                return "/";
-            }
-
-            if (path.EndsWith(@"/") || path.EndsWith(@"\"))
-            {
-                return this.GetParentDirectory(Path.GetDirectoryName(path));
-            }
-
-            string result = Path.GetDirectoryName(path);
-            if (result == null)
-            {
-                result = "/";
-            }
-
-            return result;
-        }
-
-        private bool removeDirRecursively(string fullPath,string callbackId)
-        {
-            try
-            {
-                if (fullPath == "/")
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
-                    return false;
-                }
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    if (isoFile.DirectoryExists(fullPath))
-                    {
-                        string tempPath = File.AddSlashToDirectory(fullPath);
-                        string[] files = isoFile.GetFileNames(tempPath + "*");
-                        if (files.Length > 0)
-                        {
-                            foreach (string file in files)
-                            {
-                                isoFile.DeleteFile(tempPath + file);
-                            }
-                        }
-                        string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
-                        if (dirs.Length > 0)
-                        {
-                            foreach (string dir in dirs)
-                            {
-                                if (!removeDirRecursively(tempPath + dir, callbackId))
-                                {
-                                    return false;
-                                }
-                            }
-                        }
-                        isoFile.DeleteDirectory(fullPath);
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private bool CanonicalCompare(string pathA, string pathB)
-        {
-            string a = pathA.Replace("//", "/");
-            string b = pathB.Replace("//", "/");
-
-            return a.Equals(b, StringComparison.OrdinalIgnoreCase);
-        }
-
-        /*
-         *  copyTo:["fullPath","parent", "newName"],
-         *  moveTo:["fullPath","parent", "newName"],
-         */
-        private void TransferTo(string options, bool move)
-        {
-            // TODO: try/catch
-            string[] optStrings = getOptionStrings(options);
-            string fullPath = optStrings[0];
-            string parent = optStrings[1];
-            string newFileName = optStrings[2];
-            string callbackId = optStrings[3];
-
-            char[] invalids = Path.GetInvalidPathChars();
-            
-            if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
-                return;
-            }
-
-            try
-            {
-                if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                    return;
-                }
-
-                string parentPath = File.AddSlashToDirectory(parent);
-                string currentPath = fullPath;
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    bool isFileExist = isoFile.FileExists(currentPath);
-                    bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
-                    bool isParentExist = isoFile.DirectoryExists(parentPath);
-
-                    if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                        return;
-                    }
-                    string newName;
-                    string newPath;
-                    if (isFileExist)
-                    {
-                        newName = (string.IsNullOrEmpty(newFileName))
-                                    ? Path.GetFileName(currentPath)
-                                    : newFileName;
-
-                        newPath = Path.Combine(parentPath, newName);
-                        
-                        // sanity check ..
-                        // cannot copy file onto itself
-                        if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
-                            return;
-                        }
-                        else if (isoFile.DirectoryExists(newPath)) 
-                        {
-                            // there is already a folder with the same name, operation is not allowed
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
-                            return;
-                        }
-                        else if (isoFile.FileExists(newPath))
-                        {   // remove destination file if exists, in other case there will be exception
-                            isoFile.DeleteFile(newPath);
-                        }
-
-                        if (move)
-                        {
-                            isoFile.MoveFile(currentPath, newPath);
-                        }
-                        else
-                        {
-                            isoFile.CopyFile(currentPath, newPath, true);
-                        }
-                    }
-                    else
-                    {
-                        newName = (string.IsNullOrEmpty(newFileName))
-                                    ? currentPath
-                                    : newFileName;
-
-                        newPath = Path.Combine(parentPath, newName);
-
-                        if (move)
-                        {
-                            // remove destination directory if exists, in other case there will be exception
-                            // target directory should be empty
-                            if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
-                            {
-                                isoFile.DeleteDirectory(newPath);
-                            }
-
-                            isoFile.MoveDirectory(currentPath, newPath);
-                        }
-                        else
-                        {
-                            CopyDirectory(currentPath, newPath, isoFile);
-                        }
-                    }
-                    FileEntry entry = FileEntry.GetEntry(newPath);
-                    if (entry != null)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                    }
-                }
-
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex, callbackId))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
-                }
-            }
-        }
-
-        private bool HandleException(Exception ex, string cbId="")
-        {
-            bool handled = false;
-            string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
-            if (ex is SecurityException)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
-                handled = true;
-            }
-            else if (ex is FileNotFoundException)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                handled = true;
-            }
-            else if (ex is ArgumentException)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
-                handled = true;
-            }
-            else if (ex is IsolatedStorageException)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
-                handled = true;
-            }
-            else if (ex is DirectoryNotFoundException)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                handled = true;
-            }
-            return handled;
-        }
-
-        private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
-        {
-            string path = File.AddSlashToDirectory(sourceDir);
-
-            bool bExists = isoFile.DirectoryExists(destDir);
-
-            if (!bExists)
-            {
-                isoFile.CreateDirectory(destDir);
-            }
-
-            destDir = File.AddSlashToDirectory(destDir);
-               
-            string[] files = isoFile.GetFileNames(path + "*");
-                
-            if (files.Length > 0)
-            {
-                foreach (string file in files)
-                {
-                    isoFile.CopyFile(path + file, destDir + file,true);
-                }
-            }
-            string[] dirs = isoFile.GetDirectoryNames(path + "*");
-            if (dirs.Length > 0)
-            {
-                foreach (string dir in dirs)
-                {
-                    CopyDirectory(path + dir, destDir + dir, isoFile);
-                }
-            }
-        }
-
-        private void GetFileOrDirectory(string options, bool getDirectory)
-        {
-            FileOptions fOptions = new FileOptions();
-            string[] args = getOptionStrings(options);
-
-            fOptions.FullPath = args[0];
-            fOptions.Path = args[1];
-
-            string callbackId = args[3];
-
-            try
-            {
-                fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
-                return;
-            }
-
-            try
-            {
-                if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                    return;
-                }
-
-                string path;
-
-                if (fOptions.Path.Split(':').Length > 2)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
-                    return;
-                }
-
-                try
-                {
-                    path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
-                    return;
-                }        
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    bool isFile = isoFile.FileExists(path);
-                    bool isDirectory = isoFile.DirectoryExists(path);
-                    bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
-                    bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
-                    if (create)
-                    {
-                        if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
-                            return;
-                        }
-
-                        // need to make sure the parent exists
-                        // it is an error to create a directory whose immediate parent does not yet exist
-			            // see issue: https://issues.apache.org/jira/browse/CB-339
-                        string[] pathParts = path.Split('/');
-                        string builtPath = pathParts[0];
-                        for (int n = 1; n < pathParts.Length - 1; n++)
-                        {
-                            builtPath += "/" + pathParts[n];
-                            if (!isoFile.DirectoryExists(builtPath))
-                            {
-                                Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                                return;
-                            }
-                        }
-
-                        if ((getDirectory) && (!isDirectory))
-                        {
-                            isoFile.CreateDirectory(path);
-                        }
-                        else
-                        {
-                            if ((!getDirectory) && (!isFile))
-                            {
-
-                                IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
-                                fileStream.Close();
-                            }
-                        }
-                    }
-                    else // (not create)
-                    {
-                        if ((!isFile) && (!isDirectory))
-                        {
-                            if (path.IndexOf("//www") == 0)
-                            {
-                                Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
-                                StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
-                                if (streamInfo != null)
-                                {
-                                    FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
-
-                                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
-
-                                    //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
-                                    //{
-                                    //    byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
-                                   
-                                    //}
-
-                                }
-                                else
-                                {
-                                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                                }
-
-
-                            }
-                            else
-                            {
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                            }
-                            return;
-                        }
-                        if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
-                            return;
-                        }
-                    }
-                    FileEntry entry = FileEntry.GetEntry(path);
-                    if (entry != null)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                if (!this.HandleException(ex))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
-                }
-            }
-        }
-
-        private static string AddSlashToDirectory(string dirPath)
-        {
-            if (dirPath.EndsWith("/"))
-            {
-                return dirPath;
-            }
-            else
-            {
-                return dirPath + "/";
-            }
-        }
-
-        /// <summary>
-        /// Returns file content in a form of base64 string
-        /// </summary>
-        /// <param name="stream">File stream</param>
-        /// <returns>Base64 representation of the file</returns>
-        private string GetFileContent(Stream stream)
-        {
-            int streamLength = (int)stream.Length;
-            byte[] fileData = new byte[streamLength + 1];
-            stream.Read(fileData, 0, streamLength);
-            stream.Close();
-            return Convert.ToBase64String(fileData);
-        }
-
-        #endregion
-
-    }
-}
diff --git a/templates/standalone/Plugins/FileTransfer.cs b/templates/standalone/Plugins/FileTransfer.cs
deleted file mode 100644
index e585895..0000000
--- a/templates/standalone/Plugins/FileTransfer.cs
+++ /dev/null
@@ -1,526 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Net;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Security;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class FileTransfer : BaseCommand
-    {
-        public class DownloadRequestState
-        {
-            // This class stores the State of the request.
-            public HttpWebRequest request;
-            public DownloadOptions options;
-
-            public DownloadRequestState()
-            {
-                request = null;
-                options = null;
-            }
-        }
-
-        /// <summary>
-        /// Boundary symbol
-        /// </summary>       
-        private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
-
-        // Error codes
-        public const int FileNotFoundError = 1;
-        public const int InvalidUrlError = 2;
-        public const int ConnectionError = 3;
-
-        /// <summary>
-        /// Options for downloading file
-        /// </summary>
-        [DataContract]
-        public class DownloadOptions
-        {
-            /// <summary>
-            /// File path to download to
-            /// </summary>
-            [DataMember(Name = "filePath", IsRequired = true)]
-            public string FilePath { get; set; }
-
-            /// <summary>
-            /// Server address to the file to download
-            /// </summary>
-            [DataMember(Name = "url", IsRequired = true)]
-            public string Url { get; set; }
-        }
-
-        /// <summary>
-        /// Options for uploading file
-        /// </summary>
-        [DataContract]
-        public class UploadOptions
-        {
-            /// <summary>
-            /// File path to upload
-            /// </summary>
-            [DataMember(Name = "filePath", IsRequired = true)]
-            public string FilePath { get; set; }
-
-            /// <summary>
-            /// Server address
-            /// </summary>
-            [DataMember(Name = "server", IsRequired = true)]
-            public string Server { get; set; }
-
-            /// <summary>
-            /// File key
-            /// </summary>
-            [DataMember(Name = "fileKey")]
-            public string FileKey { get; set; }
-
-            /// <summary>
-            /// File name on the server
-            /// </summary>
-            [DataMember(Name = "fileName")]
-            public string FileName { get; set; }
-
-            /// <summary>
-            /// File Mime type
-            /// </summary>
-            [DataMember(Name = "mimeType")]
-            public string MimeType { get; set; }
-
-
-            /// <summary>
-            /// Additional options
-            /// </summary>
-            [DataMember(Name = "params")]
-            public string Params { get; set; }
-
-            /// <summary>
-            /// Flag to recognize if we should trust every host (only in debug environments)
-            /// </summary>
-            [DataMember(Name = "debug")]
-            public bool Debug { get; set; }
-
-            /// <summary>
-            /// Creates options object with default parameters
-            /// </summary>
-            public UploadOptions()
-            {
-                this.SetDefaultValues(new StreamingContext());
-            }
-
-            /// <summary>
-            /// Initializes default values for class fields.
-            /// Implemented in separate method because default constructor is not invoked during deserialization.
-            /// </summary>
-            /// <param name="context"></param>
-            [OnDeserializing()]
-            public void SetDefaultValues(StreamingContext context)
-            {
-                this.FileKey = "file";
-                this.FileName = "image.jpg";
-                this.MimeType = "image/jpeg";
-            }
-
-        }
-
-        /// <summary>
-        /// Uploading response info
-        /// </summary>
-        [DataContract]
-        public class FileUploadResult
-        {
-            /// <summary>
-            /// Amount of sent bytes
-            /// </summary>
-            [DataMember(Name = "bytesSent")]
-            public long BytesSent { get; set; }
-
-            /// <summary>
-            /// Server response code
-            /// </summary>
-            [DataMember(Name = "responseCode")]
-            public long ResponseCode { get; set; }
-
-            /// <summary>
-            /// Server response
-            /// </summary>
-            [DataMember(Name = "response", EmitDefaultValue = false)]
-            public string Response { get; set; }
-
-            /// <summary>
-            /// Creates FileUploadResult object with response values
-            /// </summary>
-            /// <param name="bytesSent">Amount of sent bytes</param>
-            /// <param name="responseCode">Server response code</param>
-            /// <param name="response">Server response</param>
-            public FileUploadResult(long bytesSent, long responseCode, string response)
-            {
-                this.BytesSent = bytesSent;
-                this.ResponseCode = responseCode;
-                this.Response = response;
-            }
-        }
-
-        /// <summary>
-        /// Represents transfer error codes for callback
-        /// </summary>
-        [DataContract]
-        public class FileTransferError
-        {
-            /// <summary>
-            /// Error code
-            /// </summary>
-            [DataMember(Name = "code", IsRequired = true)]
-            public int Code { get; set; }
-
-            /// <summary>
-            /// The source URI
-            /// </summary>
-            [DataMember(Name = "source", IsRequired = true)]
-            public string Source { get; set; }
-
-            /// <summary>
-            /// The target URI
-            /// </summary>
-            [DataMember(Name = "target", IsRequired = true)]
-            public string Target { get; set; }
-
-            /// <summary>
-            /// The http status code response from the remote URI
-            /// </summary>
-            [DataMember(Name = "http_status", IsRequired = true)]
-            public int HttpStatus { get; set; }
-
-            /// <summary>
-            /// Creates FileTransferError object
-            /// </summary>
-            /// <param name="errorCode">Error code</param>
-            public FileTransferError(int errorCode)
-            {
-                this.Code = errorCode;
-                this.Source = null;
-                this.Target = null;
-                this.HttpStatus = 0;
-            }
-            public FileTransferError(int errorCode, string source, string target, int status)
-            {
-                this.Code = errorCode;
-                this.Source = source;
-                this.Target = target;
-                this.HttpStatus = status;
-            }
-        }
-
-        /// <summary>
-        /// Upload options
-        /// </summary>
-        private UploadOptions uploadOptions;
-
-        /// <summary>
-        /// Bytes sent
-        /// </summary>
-        private long bytesSent;
-
-        /// <summary>
-        /// sends a file to a server
-        /// </summary>
-        /// <param name="options">Upload options</param>
-        public void upload(string options)
-        {
-            Debug.WriteLine("options = " + options);
-            options = options.Replace("{}", "null");
-
-            try 
-            {
-                try 
-                {
-                    string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                    uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                Uri serverUri;
-                try
-                {
-                    serverUri = new Uri(uploadOptions.Server);
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
-                    return;
-                }
-                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
-                webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
-                webRequest.Method = "POST";
-                webRequest.BeginGetRequestStream(WriteCallback, webRequest);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
-            }
-        }
-
-        public void download(string options)
-        {
-            DownloadOptions downloadOptions = null;
-            HttpWebRequest webRequest = null;
-
-            try
-            {
-                string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-
-                downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
-                downloadOptions.Url = optionStrings[0];
-                downloadOptions.FilePath = optionStrings[1];
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
-                return;
-            }
-
-            if (downloadOptions != null && webRequest != null)
-            {
-                DownloadRequestState state = new DownloadRequestState();
-                state.options = downloadOptions;
-                state.request = webRequest;
-                webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
-            }
-
-
-
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="asynchronousResult"></param>
-        private void downloadCallback(IAsyncResult asynchronousResult)
-        {
-            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
-            HttpWebRequest request = reqState.request;
-
-            try
-            {
-                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    // create the file if not exists
-                    if (!isoFile.FileExists(reqState.options.FilePath))
-                    {
-                        var file = isoFile.CreateFile(reqState.options.FilePath);
-                        file.Close();
-                    }
-
-                    using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
-                    {
-                        long totalBytes = response.ContentLength;
-                        int bytesRead = 0;
-                        using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
-                        {
-
-                            using (BinaryWriter writer = new BinaryWriter(fileStream))
-                            {
-                                int BUFFER_SIZE = 1024;
-                                byte[] buffer;
-
-                                while (true)
-                                {
-                                    buffer = reader.ReadBytes(BUFFER_SIZE);
-                                    // fire a progress event ?
-                                    bytesRead += buffer.Length;
-                                    if (buffer.Length > 0)
-                                    {
-                                        writer.Write(buffer);
-                                    }
-                                    else
-                                    {
-                                        writer.Close();
-                                        reader.Close();
-                                        fileStream.Close();
-                                        break;
-                                    }
-                                }
-                            }
-
-                        }
-
-
-                    }
-                }
-                WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
-            }
-            catch (IsolatedStorageException)
-            {
-                // Trying to write the file somewhere within the IsoStorage.
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
-            }
-            catch (SecurityException)
-            {
-                // Trying to write the file somewhere not allowed.
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
-            }
-            catch (WebException webex)
-            {
-                // TODO: probably need better work here to properly respond with all http status codes back to JS
-                // Right now am jumping through hoops just to detect 404.
-                if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
-                {
-                    // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
-                    // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
-                    // FACEPALM
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
-                }
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
-            }
-        }
-
-
-
-        /// <summary>
-        /// Read file from Isolated Storage and sends it to server
-        /// </summary>
-        /// <param name="asynchronousResult"></param>
-        private void WriteCallback(IAsyncResult asynchronousResult)
-        {
-            try
-            {
-                HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
-                using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
-                {
-                    string lineStart = "--";
-                    string lineEnd = Environment.NewLine;
-                    byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
-                    string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
-
-                    if (uploadOptions.Params != null)
-                    {
-
-                        string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
-
-                        foreach (string param in arrParams)
-                        {
-                            string[] split = param.Split('=');
-                            string key = split[0];
-                            string val = split[1];
-                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
-                            string formItem = string.Format(formdataTemplate, key, val);
-                            byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
-                            requestStream.Write(formItemBytes, 0, formItemBytes.Length);
-                        }
-                        requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
-                    }
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (!isoFile.FileExists(uploadOptions.FilePath))
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
-                            return;
-                        }
-
-                        using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
-                        {
-                            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
-                            string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
-                            byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
-                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
-                            requestStream.Write(headerBytes, 0, headerBytes.Length);
-                            byte[] buffer = new byte[4096];
-                            int bytesRead = 0;
-
-                            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
-                            {
-                                requestStream.Write(buffer, 0, bytesRead);
-                                bytesSent += bytesRead;
-                            }
-                        }
-                        byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
-                        requestStream.Write(endRequest, 0, endRequest.Length);
-                    }
-                }
-                webRequest.BeginGetResponse(ReadCallback, webRequest);
-            }
-            catch (Exception)
-            {
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
-                });
-            }
-        }
-
-        /// <summary>
-        /// Reads response into FileUploadResult
-        /// </summary>
-        /// <param name="asynchronousResult"></param>
-        private void ReadCallback(IAsyncResult asynchronousResult)
-        {
-            try
-            {
-                HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
-                using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
-                {
-                    using (Stream streamResponse = response.GetResponseStream())
-                    {
-                        using (StreamReader streamReader = new StreamReader(streamResponse))
-                        {
-                            string responseString = streamReader.ReadToEnd();
-                            Deployment.Current.Dispatcher.BeginInvoke(() =>
-                            {
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
-                            });
-                        }
-                    }
-                }
-            }
-            catch (Exception)
-            {
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
-                });
-            }
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/GeoLocation.cs b/templates/standalone/Plugins/GeoLocation.cs
deleted file mode 100644
index c53cb29..0000000
--- a/templates/standalone/Plugins/GeoLocation.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Device.Location;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// This is a command stub, the browser provides the correct implementation.  We use this to trigger the static analyzer that we require this permission 
-    /// </summary>
-    public class GeoLocation
-    {
-        /* Unreachable code, by design -jm */
-        private void triggerGeoInclusion()
-        {
-            new GeoCoordinateWatcher();
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/Globalization.cs b/templates/standalone/Plugins/Globalization.cs
deleted file mode 100644
index 1528807..0000000
--- a/templates/standalone/Plugins/Globalization.cs
+++ /dev/null
@@ -1,1178 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Globalization;
-using System.Runtime.Serialization;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides information about system locale, culture settings, number formats, ect.
-    /// </summary>
-    public class Globalization : BaseCommand
-    {
-
-        #region Globalization errors
-
-        /// <summary>
-        /// Globalization error codes.
-        /// </summary>
-        public enum ErrorCode : int
-        {
-            UnknownError = 0,
-            FormattingError = 1,
-            ParsingError = 2,
-            PatternError = 3
-        }
-
-        /// <summary>
-        /// Represents globalization error object.
-        /// </summary>
-        [DataContract]
-        public class GlobalizationError
-        {
-            #region Error messages
-            /// <summary>
-            /// Error messages
-            /// </summary>        
-            public const string UnknownError = "UNKNOWN_ERROR";
-            public const string FormattingError = "FORMATTIN_ERROR";
-            public const string ParsingError = "PARSING_ERROR";
-            public const string PatternError = "PATTERN_ERROR";
-
-            #endregion
-
-            /// <summary>
-            /// Error code
-            /// </summary>
-            [DataMember(Name = "code", IsRequired = false)]
-            public ErrorCode Code { get; set; }
-
-            /// <summary>
-            /// Error message
-            /// </summary>
-            [DataMember(Name = "message", IsRequired = false)]
-            public string Message { get; set; }
-
-            /// <summary>
-            /// Default constructor
-            /// </summary>
-            public GlobalizationError()
-            {
-                this.Code = ErrorCode.UnknownError;
-                this.Message = UnknownError;
-            }
-
-            /// <summary>
-            /// Constructor setting error code
-            /// </summary>
-            public GlobalizationError(ErrorCode error)
-            {
-                this.Code = error;
-
-                switch (error)
-                {
-                    case ErrorCode.ParsingError:
-                        {
-                            this.Message = ParsingError;
-                            break;
-                        }
-                    case ErrorCode.FormattingError:
-                        {
-                            this.Message = FormattingError;
-                            break;
-                        }
-                    case ErrorCode.PatternError:
-                        {
-                            this.Message = PatternError;
-                            break;
-                        }
-                    default:
-                        {
-                            this.Message = UnknownError;
-                            break;
-                        }
-                }
-            }
-        }
-
-        #endregion
-
-        #region Globalization options
-
-        /// <summary>
-        /// Represents globalization options.
-        /// </summary>
-        [DataContract]
-        public class GlobalizationOptions
-        {
-            #region available option values
-            /// <summary>
-            /// Number pattern types.
-            /// </summary>        
-            public const string Percent = "percent";
-            public const string Currency = "currency";
-            public const string Decimal = "decimal";
-
-            /// <summary>
-            /// Format length types
-            /// </summary>        
-            public const string Short = "short";
-            public const string Medium = "medium";
-            public const string Long = "long";
-            public const string Full = "full";
-
-            /// <summary>
-            /// Selector types
-            /// </summary>        
-            public const string TimeSelector = "time";
-            public const string DateSelector = "date";
-            public const string DateAndTimeSelector = "date and time";
-
-            /// <summary>
-            /// Date name types
-            /// </summary>        
-            public const string Narrow = "narrow";
-            public const string Wide = "wide";
-
-            /// <summary>
-            /// Date name items
-            /// </summary>        
-            public const string Months = "months";
-            public const string Days = "days";
-
-            #endregion
-
-            /// <summary>
-            /// Additional options
-            /// </summary>
-            [DataMember(Name = "options", IsRequired = false)]
-            public Options AdditionalOptions { get; set; }
-
-            /// <summary>
-            /// Date to convert
-            /// </summary>
-            [DataMember(Name = "date", IsRequired = false)]
-            public long Date { get; set; }
-
-            /// <summary>
-            /// Date as stirng
-            /// </summary>
-            [DataMember(Name = "dateString", IsRequired = false)]
-            public string DateString { get; set; }
-
-            /// <summary>
-            /// Currency code
-            /// </summary>
-            [DataMember(Name = "currencyCode", IsRequired = false)]
-            public string CurrencyCode { get; set; }
-
-            /// <summary>
-            /// Number as string
-            /// </summary>
-            [DataMember(Name = "numberString", IsRequired = false)]
-            public string NumberString { get; set; }
-
-            /// <summary>
-            /// Number to convert
-            /// </summary>
-            [DataMember(Name = "number", IsRequired = false)]
-            public double Number { get; set; }
-        }
-
-        /// <summary>
-        /// Represents additional options
-        /// </summary>
-        [DataContract]
-        public class Options
-        {
-            /// <summary>
-            /// Pattern type
-            /// </summary>
-            [DataMember(Name = "type", IsRequired = false)]
-            public string Type { get; set; }
-
-            /// <summary>
-            /// Format length
-            /// </summary>
-            [DataMember(Name = "formatLength", IsRequired = false)]
-            public string FormatLength { get; set; }
-
-            /// <summary>
-            /// Selector
-            /// </summary>
-            [DataMember(Name = "selector", IsRequired = false)]
-            public string Selector { get; set; }
-
-            /// <summary>
-            /// Date name item
-            /// </summary>
-            [DataMember(Name = "item", IsRequired = false)]
-            public string Item { get; set; }
-        }
-
-        #endregion
-
-        #region returned objects
-
-        #region Number pattern object
-
-        /// <summary>
-        /// Represents number pattern
-        /// </summary>
-        [DataContract]
-        public class NumberPattern
-        {
-            /// <summary>
-            /// Pattern
-            /// </summary>
-            [DataMember(Name = "pattern", IsRequired = false)]
-            public string Pattern { get; set; }
-
-            /// <summary>
-            /// Symbol
-            /// </summary>
-            [DataMember(Name = "symbol", IsRequired = false)]
-            public string Symbol { get; set; }
-
-            /// <summary>
-            /// Fraction
-            /// </summary>
-            [DataMember(Name = "fraction", IsRequired = false)]
-            public int Fraction { get; set; }
-
-            /// <summary>
-            /// Positive
-            /// </summary>
-            [DataMember(Name = "positive", IsRequired = false)]
-            public string Positive { get; set; }
-
-            /// <summary>
-            /// Negative
-            /// </summary>
-            [DataMember(Name = "negative", IsRequired = false)]
-            public string Negative { get; set; }
-
-            /// <summary>
-            /// Rounding
-            /// </summary>
-            [DataMember(Name = "rounding", IsRequired = false)]
-            public int Rounding { get; set; }
-
-            /// <summary>
-            /// Decimal
-            /// </summary>
-            [DataMember(Name = "decimal", IsRequired = false)]
-            public string Decimal { get; set; }
-
-            /// <summary>
-            /// Grouping
-            /// </summary>
-            [DataMember(Name = "grouping", IsRequired = false)]
-            public string Grouping { get; set; }
-
-            /// <summary>
-            /// Constructor of the class
-            /// </summary>
-            /// <param name="pattern"></param>
-            /// <param name="symbol"></param>
-            /// <param name="fraction"></param>
-            /// <param name="positive"></param>
-            /// <param name="negative"></param>
-            /// <param name="rounding"></param>
-            /// <param name="dec"></param>
-            /// <param name="grouping"></param>
-            public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
-            {
-                this.Pattern = pattern;
-                this.Symbol = symbol;
-                this.Fraction = fraction;
-                this.Positive = positive;
-                this.Negative = negative;
-                this.Rounding = rounding;
-                this.Decimal = dec;
-                this.Grouping = grouping;
-            }
-        }
-        #endregion
-
-        #region Date format object
-
-        /// <summary>
-        /// Represents date format
-        /// </summary>
-        [DataContract]
-        public class DateFormat
-        {
-            /// <summary>
-            /// Year
-            /// </summary>
-            [DataMember(Name = "year", IsRequired = false)]
-            public int Year { get; set; }
-
-            /// <summary>
-            /// Month
-            /// </summary>
-            [DataMember(Name = "month", IsRequired = false)]
-            public int Month { get; set; }
-
-            /// <summary>
-            /// Day
-            /// </summary>
-            [DataMember(Name = "day", IsRequired = false)]
-            public int Day { get; set; }
-
-            /// <summary>
-            /// Hour
-            /// </summary>
-            [DataMember(Name = "hour", IsRequired = false)]
-            public int Hour { get; set; }
-
-            /// <summary>
-            /// Minute
-            /// </summary>
-            [DataMember(Name = "minute", IsRequired = false)]
-            public int Minute { get; set; }
-
-            /// <summary>
-            /// Second
-            /// </summary>
-            [DataMember(Name = "second", IsRequired = false)]
-            public int Second { get; set; }
-
-            /// <summary>
-            /// Millisecond
-            /// </summary>
-            [DataMember(Name = "millisecond", IsRequired = false)]
-            public int Millisecond { get; set; }
-
-            public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
-            {
-                this.Year = year;
-                this.Month = month;
-                this.Day = day;
-                this.Hour = hour;
-                this.Minute = minute;
-                this.Millisecond = millisecond;
-            }
-
-        }
-        #endregion
-
-        #region Date pattern object
-
-        /// <summary>
-        /// Represents date pattern object
-        /// </summary>
-        [DataContract]
-        public class DatePattern
-        {
-
-            /// <summary>
-            /// Date pattern
-            /// </summary>
-            [DataMember(Name = "pattern", IsRequired = false)]
-            public string Pattern { get; set; }
-
-            /// <summary>
-            /// TimeZone
-            /// </summary>
-            [DataMember(Name = "timezone", IsRequired = false)]
-            public string TimeZone { get; set; }
-
-            /// <summary>
-            /// UTC offset
-            /// </summary>
-            [DataMember(Name = "utc_offset", IsRequired = false)]
-            public double UtcOffset { get; set; }
-
-            /// <summary>
-            /// Dst offset
-            /// </summary>
-            [DataMember(Name = "dst_offset", IsRequired = false)]
-            public double DstOffset { get; set; }
-
-            /// <summary>
-            /// Constructor of the class
-            /// </summary>
-            /// <param name="pattern"></param>
-            /// <param name="timezone"></param>
-            /// <param name="utcOffset"></param>
-            /// <param name="dstOffset"></param>
-            public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
-            {
-                this.Pattern = pattern;
-                this.TimeZone = timezone;
-                this.UtcOffset = utcOffset;
-                this.DstOffset = dstOffset;
-            }
-
-        }
-
-        #endregion
-
-        #endregion
-
-        #region Locale info
-
-        /// <summary>
-        /// Gets the string identifier for the client's current locale setting.
-        /// </summary>
-        /// <param name="options"></param>               
-        public void getLocaleName(string options)
-        {
-            try
-            {
-                var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
-                PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
-                this.DispatchCommandResult(result);
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        /// <summary>
-        /// Gets the string identifier for the client's current language.
-        /// </summary>
-        /// <param name="options"></param>               
-        public void getPreferredLanguage(string options)
-        {
-            try
-            {
-                var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
-                PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
-                this.DispatchCommandResult(result);
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        #endregion
-
-        #region Date and time info
-
-        /// <summary>
-        /// Gets whether daylight savings time is in effect for a given date using the client's 
-        /// time zone and calendar.        
-        /// </summary>
-        /// <param name="opitons">Date to daylight savings check.</param>
-        public void isDayLightSavingsTime(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-                DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-                TimeZoneInfo localZone = TimeZoneInfo.Local;
-                bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        /// <summary>
-        /// Gets the first day of the week according to the client's user preferences and calendar.
-        /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getFirstDayOfWeek(string options)
-        {
-            try
-            {
-                // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
-                var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
-                PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
-                this.DispatchCommandResult(result);
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        #endregion
-
-        #region Formatting
-
-        /// <summary>
-        /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client. 
-        /// </summary>
-        /// <param name="options"></param>
-        public void dateToString(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-                DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-
-                string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
-                int formatLength = 0; //default format
-                int selector = 0; //default selector 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.FormatLength != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.FormatLength;
-
-                        if (t.Equals(GlobalizationOptions.Full))
-                        {
-                            formatLength++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Selector != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Selector;
-
-                        if (t.Equals(GlobalizationOptions.DateSelector))
-                        {
-                            selector += 10;
-                        }
-                        else if (t.Equals(GlobalizationOptions.TimeSelector))
-                        {
-                            selector += 20;
-                        }
-                    }
-
-                    //determine return value
-                    int method = formatLength + selector;
-
-                    switch (method)
-                    {
-                        case 1: // full datetime
-                            {
-                                format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
-                                break;
-                            }
-                        case 10: // short date
-                            {
-                                format = "{0:d}";
-                                break;
-                            }
-                        case 11: // full date
-                            {
-                                format = "{0:D}";
-                                break;
-                            }
-                        case 20: // short time
-                            {
-                                format = "{0:t}";
-                                break;
-                            }
-                        case 21: // full time
-                            {
-                                format = "{0:T}";
-                                break;
-                            }
-                        default: // short datetime
-                            {
-                                format = "{0:M/dd/yy H:m:s}";
-                                break;
-                            }
-                    }
-                }
-
-                string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
-            }
-        }
-
-        /// <summary>
-        /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
-        /// </summary>
-        /// <param name="options"></param>
-        public void stringToDate(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                if (string.IsNullOrEmpty(globalOptions.DateString))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                string format = "M/dd/yy H:m:s"; // short datetime by default
-                int formatLength = 0; //default format
-                int selector = 0; //default selector 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.FormatLength != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.FormatLength;
-
-                        if (t.Equals(GlobalizationOptions.Full))
-                        {
-                            formatLength++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Selector != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Selector;
-
-                        if (t.Equals(GlobalizationOptions.DateSelector))
-                        {
-                            selector += 10;
-                        }
-                        else if (t.Equals(GlobalizationOptions.TimeSelector))
-                        {
-                            selector += 20;
-                        }
-                    }
-
-                    //determine return value
-                    int method = formatLength + selector;
-
-                    switch (method)
-                    {
-                        case 1: // full datetime
-                            {
-                                format = "MMMM/dddd/yyyy HH:mm:ss tt";
-                                break;
-                            }
-                        case 10: // short date
-                            {
-                                format = "d";
-                                break;
-                            }
-                        case 11: // full date
-                            {
-                                format = "D";
-                                break;
-                            }
-                        case 20: // short time
-                            {
-                                format = "t";
-                                break;
-                            }
-                        case 21: // full time
-                            {
-                                format = "T";
-                                break;
-                            }
-                        default: // short datetime
-                            {
-                                format = "M/dd/yy H:m:s";
-                                break;
-                            }
-                    }
-                }
-
-                DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
-                DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
-
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getDatePattern(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
-                string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
-                int formatLength = 0; //default format
-                int selector = 0; //default selector 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.FormatLength != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.FormatLength;
-
-                        if (t.Equals(GlobalizationOptions.Full))
-                        {
-                            formatLength++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Selector != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Selector;
-
-                        if (t.Equals(GlobalizationOptions.DateSelector))
-                        {
-                            selector += 10;
-                        }
-                        else if (t.Equals(GlobalizationOptions.TimeSelector))
-                        {
-                            selector += 20;
-                        }
-                    }
-
-                    //determine return value
-                    int method = formatLength + selector;
-
-                    switch (method)
-                    {
-                        case 1: // full datetime
-                            {
-                                pattern = dateFormatInfo.FullDateTimePattern;
-                                break;
-                            }
-                        case 10: // short date
-                            {
-                                pattern = dateFormatInfo.ShortDatePattern;
-                                break;
-                            }
-                        case 11: // full date
-                            {
-                                pattern = dateFormatInfo.LongDatePattern;
-                                break;
-                            }
-                        case 20: // short time
-                            {
-                                pattern = dateFormatInfo.ShortTimePattern;
-                                break;
-                            }
-                        case 21: // full time
-                            {
-                                pattern = dateFormatInfo.LongTimePattern;
-                                break;
-                            }
-                        default: // short datetime
-                            {
-                                // Seems like C# doesn't support short datetime pattern so we use full format
-                                // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
-                                pattern = dateFormatInfo.FullDateTimePattern;
-                                break;
-                            }
-                    }
-                }
-
-                TimeZoneInfo localZone = TimeZoneInfo.Local;
-                DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getDateNames(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                int type = 0; //default wide
-                int item = 0; //default months 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.Type != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Type;
-
-                        if (t.Equals(GlobalizationOptions.Narrow))
-                        {
-                            type++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Item != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Item;
-
-                        if (t.Equals(GlobalizationOptions.Days))
-                        {
-                            item += 10;
-                        }
-                    }
-                }
-
-                //determine return value
-                int method = item + type;
-                string[] namesArray;
-                CultureInfo currentCulture = CultureInfo.CurrentCulture;
-
-                if (method == 1) //months and narrow
-                {
-                    namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
-                }
-                else if (method == 10) //days and wide
-                {
-                    namesArray = currentCulture.DateTimeFormat.DayNames;
-                }
-                else if (method == 11) //days and narrow
-                {
-                    namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
-                }
-                else //default: months and wide
-                {
-                    namesArray = currentCulture.DateTimeFormat.MonthNames;
-                }
-
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        /// <summary>
-        /// Gets a number formatted as a string according to the client's user preferences. 
-        /// </summary>
-        /// <param name="options"></param>
-        public void numberToString(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                string format = string.Empty;
-                string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
-                    GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
-                switch (numberFormatType)
-                {
-                    case GlobalizationOptions.Percent:
-                        {
-                            format = "{0:p}";
-                            break;
-                        }
-
-                    case GlobalizationOptions.Currency:
-                        {
-                            format = "{0:c}";
-                            break;
-                        }
-
-                    default:
-                        {
-                            format = "{0:f}";
-                            break;
-                        }
-                }
-
-                string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
-        /// </summary>
-        /// <param name="options"></param>
-        public void stringToNumber(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                if (string.IsNullOrEmpty(globalOptions.NumberString))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                string numberString = globalOptions.NumberString;
-                string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
-                    GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
-                NumberStyles numberStyle;
-
-                switch (numberFormatType)
-                {
-                    case GlobalizationOptions.Percent:
-                        {
-                            numberStyle = NumberStyles.Any;
-                            numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
-                            break;
-                        }
-
-                    case GlobalizationOptions.Currency:
-                        {
-                            numberStyle = NumberStyles.Currency;
-                            break;
-                        }
-
-                    default:
-                        {
-                            numberStyle = NumberStyles.Number;
-                            break;
-                        }
-                }
-
-                double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
-
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
-            }
-        }
-
-
-        /// <summary>
-        /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getNumberPattern(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                CultureInfo cultureInfo = CultureInfo.CurrentCulture;
-                NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
-                string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
-                    GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-                NumberPattern pattern = null;
-                string symbol;
-
-                // TODO find out how to get format pattern and the number of fraction digits
-                switch (numberFormatType)
-                {
-                    case GlobalizationOptions.Percent:
-                        {
-                            symbol = formatInfo.PercentSymbol;
-                            pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
-                            break;
-                        }
-                    case GlobalizationOptions.Currency:
-                        {
-                            symbol = formatInfo.CurrencySymbol;
-                            pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
-                            break;
-                        }
-                    default:
-                        {
-                            symbol = formatInfo.NumberDecimalSeparator;
-                            pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
-                            break;
-                        }
-                }
-
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getCurrencyPattern(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                string currencyCode = globalOptions.CurrencyCode;
-
-                // temporary not supported via lack of api required
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
-                return;
-
-                // TODO find the way to get currency info from currency code
-                // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
-                // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
-                // CultureInfo cultureInfo = new CultureInfo(currencyCode);
-                // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
-            }
-            catch (Exception e)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
-            }
-        }
-
-        #endregion
-
-
-        #region private methods
-
-        /// <summary>
-        /// Wraps data into JSON format
-        /// </summary>
-        /// <param name="data">data</param>
-        /// <returns>data formatted as JSON object</returns>
-        private string WrapIntoJSON<T>(T data, string keyName = "value")
-        {
-            string param = "{0}";
-            string stringifiedData = data.ToString();
-
-            if (data.GetType() == typeof(string))
-            {
-                param = "\"" + param + "\"";
-            }
-
-            if (data.GetType() == typeof(bool))
-            {
-                stringifiedData = stringifiedData.ToLower();
-            }
-
-            if (data.GetType() == typeof(string[]))
-            {
-                stringifiedData = JSON.JsonHelper.Serialize(data);
-            }
-
-            var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
-            formattedData = "{" + formattedData + "}";
-
-            return formattedData;
-        }
-
-        #endregion
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/Plugins/InAppBrowser.cs b/templates/standalone/Plugins/InAppBrowser.cs
deleted file mode 100644
index 425f5ae..0000000
--- a/templates/standalone/Plugins/InAppBrowser.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-﻿using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-using WPCordovaClassLib.Cordova;
-using WPCordovaClassLib.Cordova.Commands;
-using WPCordovaClassLib.Cordova.JSON;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    [DataContract]
-    public class BrowserOptions
-    {
-        [DataMember]
-        public string url;
-
-        [DataMember]
-        public bool isGeolocationEnabled;
-    }
-
-    public class InAppBrowser : BaseCommand
-    {
-
-        private static WebBrowser browser;
-        private static ApplicationBarIconButton backButton;
-        private static ApplicationBarIconButton fwdButton;
-
-        public void open(string options)
-        {
-            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-            //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
-            string urlLoc = args[0];
-            string target = args[1];
-            /*
-                _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser 
-                _blank - always open in the InAppBrowser 
-                _system - always open in the system web browser 
-            */
-            switch (target)
-            {
-                case "_blank":
-                    ShowInAppBrowser(urlLoc);
-                    break;
-                case "_self":
-                    ShowCordovaBrowser(urlLoc);
-                    break;
-                case "_system":
-                    ShowSystemBrowser(urlLoc);
-                    break;
-            }
-
-
-        }
-
-        private void ShowCordovaBrowser(string url)
-        {
-            Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                if (frame != null)
-                {
-                    PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-                    if (page != null)
-                    {
-                        CordovaView cView = page.FindName("CordovaView") as CordovaView;
-                        if (cView != null)
-                        {
-                            WebBrowser br = cView.Browser;
-                            br.Navigate(loc);
-                        }
-                    }
-
-                }
-            });
-        }
-
-        private void ShowSystemBrowser(string url)
-        {
-            WebBrowserTask webBrowserTask = new WebBrowserTask();
-            webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
-            webBrowserTask.Show();
-        }
-
-
-        // Display an inderminate progress indicator
-        private void ShowInAppBrowser(string url)
-        {
-            Uri loc = new Uri(url);
-
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                if (browser != null)
-                {
-                    //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
-                    browser.Navigate(loc);
-                }
-                else
-                {
-                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                    if (frame != null)
-                    {
-                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
-                        if (page != null)
-                        {
-                            Grid grid = page.FindName("LayoutRoot") as Grid;
-                            if (grid != null)
-                            {
-                                browser = new WebBrowser();
-                                browser.IsScriptEnabled = true;
-                                browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
-                                browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
-                                browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
-                                browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
-                                
-                                browser.Navigate(loc);
-                                //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
-                                grid.Children.Add(browser);
-                            }
-
-                            ApplicationBar bar = new ApplicationBar();
-                            bar.BackgroundColor = Colors.Gray;
-                            bar.IsMenuEnabled = false;
-
-                            backButton = new ApplicationBarIconButton();
-                            backButton.Text = "Back";
-                            backButton.IconUri = new Uri("/Images/appbar.back.rest.png", UriKind.Relative);
-                            backButton.Click += new EventHandler(backButton_Click);
-                            //backButton.IsEnabled = false;
-                            bar.Buttons.Add(backButton);
-
-
-                            fwdButton = new ApplicationBarIconButton();
-                            fwdButton.Text = "Forward";
-                            fwdButton.IconUri = new Uri("/Images/appbar.next.rest.png", UriKind.Relative);
-                            fwdButton.Click += new EventHandler(fwdButton_Click);
-                            //fwdButton.IsEnabled = false;
-                            bar.Buttons.Add(fwdButton);
-
-                            ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
-                            closeBtn.Text = "Close";
-                            closeBtn.IconUri = new Uri("/Images/appbar.close.rest.png", UriKind.Relative);
-                            closeBtn.Click += new EventHandler(closeBtn_Click);
-                            bar.Buttons.Add(closeBtn);
-
-                            page.ApplicationBar = bar;
-                        }
-
-                    }
-                }
-            });
-        }
-
-        void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-
-        }
-
-        void fwdButton_Click(object sender, EventArgs e)
-        {
-            if (browser != null)
-            {
-                try
-                {
-                    //browser.GoForward();
-                    browser.InvokeScript("execScript", "history.forward();");
-                }
-                catch (Exception)
-                {
-
-                }
-            }
-        }
-
-        void backButton_Click(object sender, EventArgs e)
-        {
-            if (browser != null)
-            {
-                try
-                {
-                    //browser.GoBack();
-                    browser.InvokeScript("execScript", "history.back();");
-                }
-                catch (Exception)
-                {
-
-                }
-            }
-        }
-
-        void closeBtn_Click(object sender, EventArgs e)
-        {
-            this.close();
-        }
-
-
-        public void close(string options = "")
-        {
-            if (browser != null)
-            {
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                    if (frame != null)
-                    {
-                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-                        if (page != null)
-                        {
-                            Grid grid = page.FindName("LayoutRoot") as Grid;
-                            if (grid != null)
-                            {
-                                grid.Children.Remove(browser);
-                            }
-                            page.ApplicationBar = null;
-                        }
-                    }
-                    browser = null;
-                    string message = "{\"type\":\"exit\"}";
-                    PluginResult result = new PluginResult(PluginResult.Status.OK, message);
-                    result.KeepCallback = false;
-                    this.DispatchCommandResult(result);
-                });
-            }
-        }
-
-        void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            //if (browser != null)
-            //{
-            //    backButton.IsEnabled = browser.CanGoBack;
-            //    fwdButton.IsEnabled = browser.CanGoForward;
-            //}
-            string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
-            PluginResult result = new PluginResult(PluginResult.Status.OK, message);
-            result.KeepCallback = true;
-            this.DispatchCommandResult(result);
-        }
-
-        void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
-        {
-            string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
-            PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
-            result.KeepCallback = true;
-            this.DispatchCommandResult(result);
-        }
-
-        void browser_Navigating(object sender, NavigatingEventArgs e)
-        {
-            string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
-            PluginResult result = new PluginResult(PluginResult.Status.OK, message);
-            result.KeepCallback = true;
-            this.DispatchCommandResult(result);
-        }
-
-    }
-}
diff --git a/templates/standalone/Plugins/Media.cs b/templates/standalone/Plugins/Media.cs
deleted file mode 100644
index 90c54f1..0000000
--- a/templates/standalone/Plugins/Media.cs
+++ /dev/null
@@ -1,532 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides the ability to record and play back audio files on a device. 
-    /// </summary>
-    public class Media : BaseCommand
-    {
-        /// <summary>
-        /// Audio player objects
-        /// </summary>
-        private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
-
-        /// <summary>
-        /// Represents Media action options.
-        /// </summary>
-        [DataContract]
-        public class MediaOptions
-        {
-            /// <summary>
-            /// Audio id
-            /// </summary>
-            [DataMember(Name = "id", IsRequired = true)]
-            public string Id { get; set; }
-
-            /// <summary>
-            /// Path to audio file
-            /// </summary>
-            [DataMember(Name = "src")]
-            public string Src { get; set; }
-
-            /// <summary>
-            /// New track position
-            /// </summary>
-            [DataMember(Name = "milliseconds")]
-            public int Milliseconds { get; set; }
-        }
-
-        /// <summary>
-        /// Releases the audio player instance to save memory.
-        /// </summary>  
-        public void release(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                if (!Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
-                    return;
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        AudioPlayer audio = Media.players[mediaOptions.Id];
-                        Media.players.Remove(mediaOptions.Id);
-                        audio.Dispose();
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Starts recording and save the specified file 
-        /// </summary>
-        public void startRecordingAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                if (mediaOptions != null)
-                {
-
-                    Deployment.Current.Dispatcher.BeginInvoke(() =>
-                    {
-                        try
-                        {
-                            if (!Media.players.ContainsKey(mediaOptions.Id))
-                            {
-                                AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
-                                Media.players.Add(mediaOptions.Id, audio);
-                                audio.startRecording(mediaOptions.Src);
-                            }
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                        }
-                        catch (Exception e)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                        }
-
-                    });
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                }
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Stops recording and save to the file specified when recording started 
-        /// </summary>
-        public void stopRecordingAudio(string options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.stopRecording();
-                            Media.players.Remove(mediaId);
-                        }
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-        }
-
-        public void setVolume(string options) // id,volume
-        {
-            try
-            {
-                string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                string id = optionsString[0];
-                double volume = double.Parse(optionsString[1]);
-
-                if (Media.players.ContainsKey(id))
-                {
-                    Deployment.Current.Dispatcher.BeginInvoke(() =>
-                    {
-                        try
-                        {
-                            AudioPlayer player = Media.players[id];
-                            player.setVolume(volume);
-                        }
-                        catch (Exception e)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                        }
-                    });
-                }
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
-                return;
-            }
-        }
-
-        // Some Audio Notes:
-        // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
-        // While playing, a MediaElement stops all other media playback on the phone.
-        // Multiple MediaElement controls are NOT supported
-
-        // Called when you create a new Media('blah') object in JS.
-        public void create(string options)
-        {
-            // Debug.WriteLine("Creating Audio :: " + options);
-            try
-            {
-                MediaOptions mediaOptions;
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
-                    return;
-                }
-
-                AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
-                Media.players.Add(mediaOptions.Id, audio);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Starts or resume playing audio file 
-        /// </summary>
-        public void startPlayingAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                    if (optionsString.Length > 2 && optionsString[2] != null)
-                    {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[2]);
-                    }
-
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                AudioPlayer audio;
-
-                if (!Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    audio = new AudioPlayer(this, mediaOptions.Id);
-                    Media.players[mediaOptions.Id] = audio;
-                }
-                else
-                {
-                    Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
-                    audio = Media.players[mediaOptions.Id];
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        audio.startPlaying(mediaOptions.Src);
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-
-        /// <summary>
-        /// Seeks to a location
-        /// </summary>
-        public void seekToAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    if (optionsString.Length > 1 && optionsString[1] != null)
-                    {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[1]);
-                    }
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaOptions.Id))
-                        {
-                            AudioPlayer audio = Media.players[mediaOptions.Id];
-                            audio.seekToPlaying(mediaOptions.Milliseconds);
-                        }
-                        else
-                        {
-                            Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Pauses playing 
-        /// </summary>
-        public void pausePlayingAudio(string options)
-        {
-
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.pausePlaying();
-                        }
-                        else
-                        {
-                            Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-
-
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-
-
-        }
-
-
-        /// <summary>
-        /// Stops playing the audio file
-        /// </summary>
-        public void stopPlayingAudio(String options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.stopPlaying();
-                        }
-                        else
-                        {
-                            Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-        }
-
-        /// <summary>
-        /// Gets current position of playback
-        /// </summary>
-        public void getCurrentPositionAudio(string options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-        }
-
-
-        /// <summary>
-        /// Gets the duration of the audio file
-        /// </summary>
-        
-        [Obsolete("This method will be removed shortly")]
-        public void getDurationAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                AudioPlayer audio;
-                if (Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    audio = Media.players[mediaOptions.Id];
-                }
-                else
-                {
-                    Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
-                    audio = new AudioPlayer(this, mediaOptions.Id);
-                    Media.players.Add(mediaOptions.Id, audio);
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/MimeTypeMapper.cs b/templates/standalone/Plugins/MimeTypeMapper.cs
deleted file mode 100644
index 01ba4cb..0000000
--- a/templates/standalone/Plugins/MimeTypeMapper.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System.Collections.Generic;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Represents file extension to mime type mapper.
-    /// </summary>
-    public static class MimeTypeMapper
-    {
-        /// <summary>
-        /// For unknown type it is recommended to use 'application/octet-stream'
-        /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
-        /// </summary>
-        private static string DefaultMimeType = "application/octet-stream";
-
-        /// <summary>
-        /// Stores mime type for all necessary extension
-        /// </summary>
-        private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
-                                                                             {                                                                                
-                                                                                 {"avi", "video/x-msvideo"},
-                                                                                 {"bmp", "image/bmp"},                                                                                                                                                                
-                                                                                 {"gif", "image/gif"},                                                                                                                                                               
-                                                                                 {"jpe", "image/jpeg"},
-                                                                                 {"jpeg", "image/jpeg"},
-                                                                                 {"jpg", "image/jpeg"},                                                                                                                                                             
-                                                                                 {"mov", "video/quicktime"},
-                                                                                 {"mp2", "audio/mpeg"},
-                                                                                 {"mp3", "audio/mpeg"},
-                                                                                 {"mp4", "video/mp4"},
-                                                                                 {"mpe", "video/mpeg"},
-                                                                                 {"mpeg", "video/mpeg"},
-                                                                                 {"mpg", "video/mpeg"},
-                                                                                 {"mpga", "audio/mpeg"},                                                                                
-                                                                                 {"pbm", "image/x-portable-bitmap"},
-                                                                                 {"pcm", "audio/x-pcm"},
-                                                                                 {"pct", "image/pict"},
-                                                                                 {"pgm", "image/x-portable-graymap"},
-                                                                                 {"pic", "image/pict"},
-                                                                                 {"pict", "image/pict"},
-                                                                                 {"png", "image/png"},
-                                                                                 {"pnm", "image/x-portable-anymap"},
-                                                                                 {"pnt", "image/x-macpaint"},
-                                                                                 {"pntg", "image/x-macpaint"},
-                                                                                 {"ppm", "image/x-portable-pixmap"},
-                                                                                 {"qt", "video/quicktime"},
-                                                                                 {"ra", "audio/x-pn-realaudio"},
-                                                                                 {"ram", "audio/x-pn-realaudio"},
-                                                                                 {"ras", "image/x-cmu-raster"},
-                                                                                 {"rgb", "image/x-rgb"},
-                                                                                 {"snd", "audio/basic"},
-                                                                                 {"txt", "text/plain"},
-                                                                                 {"tif", "image/tiff"},
-                                                                                 {"tiff", "image/tiff"},
-                                                                                 {"wav", "audio/x-wav"},
-                                                                                 {"wbmp", "image/vnd.wap.wbmp"},
-
-                                                                             };
-        /// <summary>
-        /// Gets mime type by file extension
-        /// </summary>
-        /// <param name="fileName">file name to extract extension</param>
-        /// <returns>mime type</returns>
-        public static string GetMimeType(string fileName)
-        {
-            string ext = Path.GetExtension(fileName);
-
-            // invalid extension
-            if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
-            {
-                return DefaultMimeType;
-            }
-
-            ext = ext.Remove(0, 1);
-
-            if (MIMETypesDictionary.ContainsKey(ext))
-            {
-                return MIMETypesDictionary[ext];
-            }
-
-            return DefaultMimeType;
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/NetworkStatus.cs b/templates/standalone/Plugins/NetworkStatus.cs
deleted file mode 100644
index 12eb061..0000000
--- a/templates/standalone/Plugins/NetworkStatus.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Diagnostics;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Net.NetworkInformation;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
-    // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
-    // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
-
-    public class NetworkStatus : BaseCommand
-    {
-        const string UNKNOWN = "unknown";
-        const string ETHERNET = "ethernet";
-        const string WIFI = "wifi";
-        const string CELL_2G = "2g";
-        const string CELL_3G = "3g";
-        const string CELL_4G = "4g";
-        const string NONE = "none";
-        const string CELL = "cellular";
-
-        private bool HasCallback = false;
-
-        public NetworkStatus()
-        {
-            DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);
-        }
-
-        public override void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
-        {
-            this.getConnectionInfo("");
-        }
-
-        public void getConnectionInfo(string empty)
-        {
-            HasCallback = true;
-            updateConnectionType(checkConnectionType());
-        }
-
-        private string checkConnectionType()
-        {
-            if (DeviceNetworkInformation.IsNetworkAvailable)
-            {
-                if (DeviceNetworkInformation.IsWiFiEnabled)
-                {
-                    return WIFI;
-                }
-                else
-                {
-                    return DeviceNetworkInformation.IsCellularDataEnabled ? CELL : UNKNOWN;
-                }
-            }
-            return NONE;
-        }
-
-        private string checkConnectionType(NetworkInterfaceSubType type)
-        {
-            switch (type)
-            {
-                case NetworkInterfaceSubType.Cellular_1XRTT: //cell
-                case NetworkInterfaceSubType.Cellular_GPRS: //cell
-                    return CELL;
-                case NetworkInterfaceSubType.Cellular_EDGE: //2
-                    return CELL_2G;
-                case NetworkInterfaceSubType.Cellular_3G:
-                case NetworkInterfaceSubType.Cellular_EVDO: //3
-                case NetworkInterfaceSubType.Cellular_EVDV: //3 
-                case NetworkInterfaceSubType.Cellular_HSPA: //3
-                    return CELL_3G;
-                case NetworkInterfaceSubType.WiFi:
-                    return WIFI;
-                case NetworkInterfaceSubType.Unknown:
-                case NetworkInterfaceSubType.Desktop_PassThru:
-                default:
-                    return UNKNOWN;
-            }
-        }
-
-        void ChangeDetected(object sender, NetworkNotificationEventArgs e)
-        {
-            switch (e.NotificationType)
-            {
-                case NetworkNotificationType.InterfaceConnected:
-                    updateConnectionType(checkConnectionType(e.NetworkInterface.InterfaceSubtype));
-                    break;
-                case NetworkNotificationType.InterfaceDisconnected:
-                    updateConnectionType(NONE);
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        private void updateConnectionType(string type)
-        {
-            // This should also implicitly fire offline/online events as that is handled on the JS side
-            if (this.HasCallback)
-            {
-                PluginResult result = new PluginResult(PluginResult.Status.OK, type);
-                result.KeepCallback = true;
-                DispatchCommandResult(result);
-            }
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/Notification.cs b/templates/standalone/Plugins/Notification.cs
deleted file mode 100644
index 11f14bd..0000000
--- a/templates/standalone/Plugins/Notification.cs
+++ /dev/null
@@ -1,367 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using Microsoft.Devices;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Windows.Resources;
-using Microsoft.Phone.Controls;
-using Microsoft.Xna.Framework.Audio;
-using WPCordovaClassLib.Cordova.UI;
-using System.Diagnostics;
-
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class Notification : BaseCommand
-    {
-        static ProgressBar progressBar = null;
-        const int DEFAULT_DURATION = 5;
-
-        private NotificationBox notifyBox;
-
-        private class NotifBoxData
-        {
-            public NotificationBox previous;
-            public string callbackId;
-        }
-
-        private PhoneApplicationPage Page
-        {
-            get
-            {
-                PhoneApplicationPage page = null;
-                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                if (frame != null)
-                {
-                    page = frame.Content as PhoneApplicationPage;
-                }
-                return page;
-            }
-        }
-
-        // blink api - doesn't look like there is an equivalent api we can use...
-
-        [DataContract]
-        public class AlertOptions
-        {
-            [OnDeserializing]
-            public void OnDeserializing(StreamingContext context)
-            {
-                // set defaults
-                this.message = "message";
-                this.title = "Alert";
-                this.buttonLabel = "ok";
-            }
-
-            /// <summary>
-            /// message to display in the alert box
-            /// </summary>
-            [DataMember]
-            public string message;
-
-            /// <summary>
-            /// title displayed on the alert window
-            /// </summary>
-            [DataMember]
-            public string title;
-
-            /// <summary>
-            /// text to display on the button
-            /// </summary>
-            [DataMember]
-            public string buttonLabel;
-        }
-
-        public void alert(string options)
-        {
-            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-            AlertOptions alertOpts = new AlertOptions();
-            alertOpts.message = args[0];
-            alertOpts.title = args[1];
-            alertOpts.buttonLabel = args[2];
-            string aliasCurrentCommandCallbackId = args[3];
-
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                PhoneApplicationPage page = Page;
-                if (page != null)
-                {
-                    Grid grid = page.FindName("LayoutRoot") as Grid;
-                    if (grid != null)
-                    {
-                        var previous = notifyBox;
-                        notifyBox = new NotificationBox();
-                        notifyBox.Tag = new NotifBoxData{ previous = previous, callbackId = aliasCurrentCommandCallbackId };
-                        notifyBox.PageTitle.Text = alertOpts.title;
-                        notifyBox.SubTitle.Text = alertOpts.message;
-                        Button btnOK = new Button();
-                        btnOK.Content = alertOpts.buttonLabel;
-                        btnOK.Click += new RoutedEventHandler(btnOK_Click);
-                        btnOK.Tag = 1;
-                        notifyBox.ButtonPanel.Children.Add(btnOK);
-                        grid.Children.Add(notifyBox);
-
-                        if (previous == null)
-                        {
-                            page.BackKeyPress += page_BackKeyPress;
-                        }
-                    }
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
-                }
-            });
-        }
-
-        public void confirm(string options)
-        {
-            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-            AlertOptions alertOpts = new AlertOptions();
-            alertOpts.message = args[0];
-            alertOpts.title = args[1];
-            alertOpts.buttonLabel = args[2];
-            string aliasCurrentCommandCallbackId = args[3];
-
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                PhoneApplicationPage page = Page;
-                if (page != null)
-                {
-                    Grid grid = page.FindName("LayoutRoot") as Grid;
-                    if (grid != null)
-                    {
-                        var previous = notifyBox;
-                        notifyBox = new NotificationBox();
-                        notifyBox.Tag = new NotifBoxData{ previous = previous, callbackId = aliasCurrentCommandCallbackId };
-                        notifyBox.PageTitle.Text = alertOpts.title;
-                        notifyBox.SubTitle.Text = alertOpts.message;
-
-                        string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
-
-                        if (labels == null)
-                        {
-                            labels = alertOpts.buttonLabel.Split(',');
-                        }
-
-                        for (int n = 0; n < labels.Length; n++)
-                        {
-                            Button btn = new Button();
-                            btn.Content = labels[n];
-                            btn.Tag = n;
-                            btn.Click += new RoutedEventHandler(btnOK_Click);
-                            notifyBox.ButtonPanel.Children.Add(btn);
-                        }
-
-                        grid.Children.Add(notifyBox);
-                        if (previous == null)
-                        {
-                            page.BackKeyPress += page_BackKeyPress;
-                        }
-                    }
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
-                }
-            });
-        }
-
-        void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
-        {
-            PhoneApplicationPage page = sender as PhoneApplicationPage;
-            string callbackId = "";
-            if (page != null && notifyBox != null)
-            {
-                Grid grid = page.FindName("LayoutRoot") as Grid;
-                if (grid != null)
-                {
-                    grid.Children.Remove(notifyBox);
-                    NotifBoxData notifBoxData = notifyBox.Tag as NotifBoxData;
-                    notifyBox = notifBoxData.previous;
-                    callbackId = notifBoxData.callbackId;
-                }
-                if (notifyBox == null)
-                {
-                    page.BackKeyPress -= page_BackKeyPress;
-                }
-                e.Cancel = true;
-            }
-
-            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
-        }
-
-        void btnOK_Click(object sender, RoutedEventArgs e)
-        {
-            Button btn = sender as Button;
-            FrameworkElement notifBoxParent = null;
-            int retVal = 0;
-            string callbackId = "";
-            if (btn != null)
-            {
-                retVal = (int)btn.Tag + 1;
-
-                notifBoxParent = btn.Parent as FrameworkElement;
-                while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
-                       !(notifBoxParent is NotificationBox)) ;
-            }
-            if (notifBoxParent != null)
-            {
-                PhoneApplicationPage page = Page;
-                if (page != null)
-                {
-                    Grid grid = page.FindName("LayoutRoot") as Grid;
-                    if (grid != null)
-                    {
-                        grid.Children.Remove(notifBoxParent);
-                    }
-
-                    NotifBoxData notifBoxData = notifBoxParent.Tag as NotifBoxData;
-                    notifyBox = notifBoxData.previous;
-                    callbackId = notifBoxData.callbackId;
-
-                    if (notifyBox == null)
-                    {
-                        page.BackKeyPress -= page_BackKeyPress;
-                    }
-                }
-
-            }
-            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal),callbackId);
-        }
-
-
-
-        public void beep(string options)
-        {
-            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-            int times = int.Parse(args[0]);
-
-            string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";
-
-            StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
-
-            if (sri != null)
-            {
-                SoundEffect effect = SoundEffect.FromStream(sri.Stream);
-                SoundEffectInstance inst = effect.CreateInstance();
-                ThreadPool.QueueUserWorkItem((o) =>
-                {
-                    // cannot interact with UI !!
-                    do
-                    {
-                        inst.Play();
-                        Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
-                    }
-                    while (--times > 0);
-
-                });
-
-            }
-
-            // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
-            DispatchCommandResult();
-        }
-
-        // Display an indeterminate progress indicator
-        public void activityStart(string unused)
-        {
-
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-
-                if (frame != null)
-                {
-                    PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
-                    if (page != null)
-                    {
-                        var temp = page.FindName("LayoutRoot");
-                        Grid grid = temp as Grid;
-                        if (grid != null)
-                        {
-                            if (progressBar != null)
-                            {
-                                grid.Children.Remove(progressBar);
-                            }
-                            progressBar = new ProgressBar();
-                            progressBar.IsIndeterminate = true;
-                            progressBar.IsEnabled = true;
-
-                            grid.Children.Add(progressBar);
-                        }
-                    }
-                }
-            });
-        }
-
-
-        // Remove our indeterminate progress indicator
-        public void activityStop(string unused)
-        {
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                if (progressBar != null)
-                {
-                    progressBar.IsEnabled = false;
-                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                    if (frame != null)
-                    {
-                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-                        if (page != null)
-                        {
-                            Grid grid = page.FindName("LayoutRoot") as Grid;
-                            if (grid != null)
-                            {
-                                grid.Children.Remove(progressBar);
-                            }
-                        }
-                    }
-                    progressBar = null;
-                }
-            });
-        }
-
-        public void vibrate(string vibrateDuration)
-        {
-
-            int msecs = 200; // set default
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
-
-                msecs = int.Parse(args[0]);
-                if (msecs < 1)
-                {
-                    msecs = 1;
-                }
-            }
-            catch (FormatException)
-            {
-
-            }
-
-            VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
-
-            // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
-            DispatchCommandResult();
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/UI/AudioCaptureTask.cs b/templates/standalone/Plugins/UI/AudioCaptureTask.cs
deleted file mode 100644
index 9f43d23..0000000
--- a/templates/standalone/Plugins/UI/AudioCaptureTask.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
-    /// <summary>
-    /// Allows an application to launch the Audio Recording application. 
-    /// Use this to allow users to record audio from your application.
-    /// </summary>
-    public class AudioCaptureTask
-    {
-        /// <summary>
-        /// Represents recorded audio returned from a call to the Show method of
-        /// a WPCordovaClassLib.Cordova.Controls.AudioCaptureTask object
-        /// </summary>
-        public class AudioResult : TaskEventArgs
-        {
-            /// <summary>
-            /// Initializes a new instance of the AudioResult class.
-            /// </summary>
-            public AudioResult()
-            { }
-
-            /// <summary>
-            /// Initializes a new instance of the AudioResult class
-            /// with the specified Microsoft.Phone.Tasks.TaskResult.
-            /// </summary>
-            /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
-            public AudioResult(TaskResult taskResult)
-                : base(taskResult)
-            { }
-
-            /// <summary>
-            ///  Gets the file name of the recorded audio.
-            /// </summary>
-            public Stream AudioFile { get; internal set; }
-
-            /// <summary>
-            /// Gets the stream containing the data for the recorded audio.
-            /// </summary>
-            public string AudioFileName { get; internal set; }
-        }
-
-        /// <summary>
-        /// Occurs when a audio recording task is completed.
-        /// </summary>
-        public event EventHandler<AudioResult> Completed;
-
-        /// <summary>
-        /// Shows Audio Recording application
-        /// </summary>
-        public void Show()
-        {
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
-                root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
-                string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
-                // dummy parameter is used to always open a fresh version
-                root.Navigate(new System.Uri(baseUrl + "CordovaLib/UI/AudioRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
-
-            });
-        }
-
-        /// <summary>
-        /// Performs additional configuration of the recording application.
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            if (!(e.Content is AudioRecorder)) return;
-
-            (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
-            AudioRecorder audioRecorder = (AudioRecorder)e.Content;
-
-            if (audioRecorder != null)
-            {
-                audioRecorder.Completed += this.Completed;
-            }
-            else if (this.Completed != null)
-            {
-                this.Completed(this, new AudioResult(TaskResult.Cancel));
-            }
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/UI/AudioRecorder.xaml b/templates/standalone/Plugins/UI/AudioRecorder.xaml
deleted file mode 100644
index 0fd26ab..0000000
--- a/templates/standalone/Plugins/UI/AudioRecorder.xaml
+++ /dev/null
@@ -1,66 +0,0 @@
-﻿<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
--->
-<phone:PhoneApplicationPage 
-    x:Class="WPCordovaClassLib.Cordova.UI.AudioRecorder"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
-    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
-    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    FontFamily="{StaticResource PhoneFontFamilyNormal}"
-    FontSize="{StaticResource PhoneFontSizeNormal}"
-    Foreground="{StaticResource PhoneForegroundBrush}"
-    SupportedOrientations="Portrait" Orientation="Portrait"
-    mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
-    shell:SystemTray.IsVisible="True">
-
-    <!--LayoutRoot is the root grid where all page content is placed-->
-    <Grid x:Name="LayoutRoot" Background="Transparent">
-        <Grid.RowDefinitions>
-            <RowDefinition Height="Auto"/>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-
-        <!--TitlePanel contains the name of the application and page title-->
-        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0,17,0,28">
-            <TextBlock x:Name="PageTitle" Text="Audio recorder" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
-        </StackPanel>
-
-        <!--ContentPanel - place additional content here-->
-        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
-            <Button Name="btnStartStop" Content="Start" Height="72" HorizontalAlignment="Left" Margin="156,96,0,0"  VerticalAlignment="Top" Width="160" Click="btnStartStop_Click" />
-            <Button Name="btnTake" Content="Take" IsEnabled="False" Height="72" HorizontalAlignment="Left" Margin="155,182,0,0" VerticalAlignment="Top" Width="160" Click="btnTake_Click" />
-            <TextBlock Height="30" HorizontalAlignment="Left" Margin="168,60,0,0" Name="txtDuration" Text="Duration: 00:00" VerticalAlignment="Top" />
-        </Grid>
-    </Grid>
- 
-    <!--Sample code showing usage of ApplicationBar-->
-    <!--<phone:PhoneApplicationPage.ApplicationBar>
-        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
-            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
-            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
-            <shell:ApplicationBar.MenuItems>
-                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
-                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
-            </shell:ApplicationBar.MenuItems>
-        </shell:ApplicationBar>
-    </phone:PhoneApplicationPage.ApplicationBar>-->
-
-</phone:PhoneApplicationPage>
diff --git a/templates/standalone/Plugins/UI/AudioRecorder.xaml.cs b/templates/standalone/Plugins/UI/AudioRecorder.xaml.cs
deleted file mode 100644
index 6ff0b5c..0000000
--- a/templates/standalone/Plugins/UI/AudioRecorder.xaml.cs
+++ /dev/null
@@ -1,330 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Threading;
-using WPCordovaClassLib.Cordova.Commands;
-using AudioResult = WPCordovaClassLib.Cordova.UI.AudioCaptureTask.AudioResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
-    /// <summary>
-    /// Implements Audio Recording application
-    /// </summary>
-    public partial class AudioRecorder : PhoneApplicationPage
-    {
-
-        #region Constants
-
-        private const string RecordingStartCaption = "Start";
-        private const string RecordingStopCaption = "Stop";
-
-        private const string LocalFolderName = "AudioCache";
-        private const string FileNameFormat = "Audio-{0}.wav";
-
-        #endregion
-
-        #region Callbacks
-
-        /// <summary>
-        /// Occurs when a audio recording task is completed.
-        /// </summary>
-        public event EventHandler<AudioResult> Completed;
-
-        #endregion
-
-        #region Fields
-
-        /// <summary>
-        /// Audio source
-        /// </summary>
-        private Microphone microphone;
-
-        /// <summary>
-        /// Temporary buffer to store audio chunk
-        /// </summary>
-        private byte[] buffer;
-
-        /// <summary>
-        /// Recording duration
-        /// </summary>
-        private TimeSpan duration;
-
-        /// <summary>
-        /// Output buffer
-        /// </summary>
-        private MemoryStream memoryStream;
-
-        /// <summary>
-        /// Xna game loop dispatcher
-        /// </summary>
-        DispatcherTimer dtXna;
-
-        /// <summary>
-        /// Recording result, dispatched back when recording page is closed
-        /// </summary>
-        private AudioResult result = new AudioResult(TaskResult.Cancel);
-
-        /// <summary>
-        /// Whether we are recording audio now
-        /// </summary>
-        private bool IsRecording
-        {
-            get
-            {
-                return (this.microphone != null && this.microphone.State == MicrophoneState.Started);
-            }
-        }
-
-        #endregion
-
-        /// <summary>
-        /// Creates new instance of the AudioRecorder class.
-        /// </summary>
-        public AudioRecorder()
-        {
-
-            this.InitializeXnaGameLoop();
-
-            // microphone requires special XNA initialization to work
-            InitializeComponent();
-        }
-
-        /// <summary>
-        /// Starts recording, data is stored in memory
-        /// </summary>
-        private void StartRecording()
-        {
-            this.microphone = Microphone.Default;
-            this.microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
-
-            this.btnTake.IsEnabled = false;
-            this.btnStartStop.Content = RecordingStopCaption;
-
-            this.buffer = new byte[microphone.GetSampleSizeInBytes(this.microphone.BufferDuration)];
-            this.microphone.BufferReady += new EventHandler<EventArgs>(MicrophoneBufferReady);
-
-            MemoryStream stream = new MemoryStream();
-            this.memoryStream = stream;
-            int numBits = 16;
-            int numBytes = numBits / 8;
-
-            // inline version from AudioFormatsHelper
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
-            stream.Write(BitConverter.GetBytes(0), 0, 4);
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
-            stream.Write(BitConverter.GetBytes(16), 0, 4);
-            stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-            stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-            stream.Write(BitConverter.GetBytes(this.microphone.SampleRate), 0, 4);
-            stream.Write(BitConverter.GetBytes(this.microphone.SampleRate * numBytes), 0, 4);
-            stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
-            stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
-            stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
-            stream.Write(BitConverter.GetBytes(0), 0, 4);
-
-            this.duration = new TimeSpan(0);
-
-            this.microphone.Start();
-        }
-
-        /// <summary>
-        /// Stops recording
-        /// </summary>
-        private void StopRecording()
-        {
-            this.microphone.Stop();
-
-            this.microphone.BufferReady -= MicrophoneBufferReady;
-
-            this.microphone = null;
-
-            btnStartStop.Content = RecordingStartCaption;
-
-            // check there is some data
-            this.btnTake.IsEnabled = true;
-        }
-
-        /// <summary>
-        /// Handles Start/Stop events
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void btnStartStop_Click(object sender, RoutedEventArgs e)
-        {
-
-            if (this.IsRecording)
-            {
-                this.StopRecording();
-            }
-            else
-            {
-                this.StartRecording();
-            }
-        }
-
-        /// <summary>
-        /// Handles Take button click
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void btnTake_Click(object sender, RoutedEventArgs e)
-        {
-            this.result = this.SaveAudioClipToLocalStorage();
-
-            if (Completed != null)
-            {
-                Completed(this, result);
-            }
-
-            if (this.NavigationService.CanGoBack)
-            {
-                this.NavigationService.GoBack();
-            }
-        }
-
-        /// <summary>
-        /// Handles page closing event, stops recording if needed and dispatches results.
-        /// </summary>
-        /// <param name="e"></param>
-        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
-        {
-            if (IsRecording)
-            {
-                StopRecording();
-            }
-
-            this.FinalizeXnaGameLoop();
-
-            base.OnNavigatedFrom(e);
-        }
-
-        /// <summary>
-        /// Copies data from microphone to memory storages and updates recording state
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void MicrophoneBufferReady(object sender, EventArgs e)
-        {
-            this.microphone.GetData(this.buffer);
-            this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
-            TimeSpan bufferDuration = this.microphone.BufferDuration;
-
-            this.Dispatcher.BeginInvoke(() =>
-            {
-                this.duration += bufferDuration;
-
-                this.txtDuration.Text = "Duration: " +
-                    this.duration.Minutes.ToString().PadLeft(2, '0') + ":" +
-                    this.duration.Seconds.ToString().PadLeft(2, '0');
-            });
-
-        }
-
-        /// <summary>
-        /// Writes audio data from memory to isolated storage
-        /// </summary>
-        /// <returns></returns>
-        private AudioResult SaveAudioClipToLocalStorage()
-        {
-            if (this.memoryStream == null || this.memoryStream.Length <= 0)
-            {
-                return new AudioResult(TaskResult.Cancel);
-            }
-
-            //this.memoryStream.UpdateWavStream();
-            long position = memoryStream.Position;
-            memoryStream.Seek(4, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
-            memoryStream.Seek(40, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
-            memoryStream.Seek(position, SeekOrigin.Begin);
-
-            // save audio data to local isolated storage
-
-            string filename = String.Format(FileNameFormat, Guid.NewGuid().ToString());
-
-            try
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-
-                    if (!isoFile.DirectoryExists(LocalFolderName))
-                    {
-                        isoFile.CreateDirectory(LocalFolderName);
-                    }
-
-                    string filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", filename);
-
-                    this.memoryStream.Seek(0, SeekOrigin.Begin);
-
-                    using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(filePath))
-                    {
-
-                        this.memoryStream.CopyTo(fileStream);
-                    }
-
-                    AudioResult result = new AudioResult(TaskResult.OK);
-                    result.AudioFileName = filePath;
-
-                    result.AudioFile = this.memoryStream;
-                    result.AudioFile.Seek(0, SeekOrigin.Begin);
-
-                    return result;
-                }
-
-
-
-            }
-            catch (Exception)
-            {
-                //TODO: log or do something else
-                throw;
-            }
-        }
-
-        /// <summary>
-        /// Special initialization required for the microphone: XNA game loop
-        /// </summary>
-        private void InitializeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            this.dtXna = new DispatcherTimer();
-            this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
-            this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
-            this.dtXna.Start();
-        }
-        /// <summary>
-        /// Finalizes XNA game loop for microphone
-        /// </summary>
-        private void FinalizeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            if (dtXna != null)
-            {
-                dtXna.Stop();
-                dtXna = null;
-            }
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/Plugins/UI/ImageCapture.xaml b/templates/standalone/Plugins/UI/ImageCapture.xaml
deleted file mode 100644
index a7eee21..0000000
--- a/templates/standalone/Plugins/UI/ImageCapture.xaml
+++ /dev/null
@@ -1,26 +0,0 @@
-﻿<phone:PhoneApplicationPage 
-    x:Class="WPCordovaClassLib.Cordova.UI.ImageCapture"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
-    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
-    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    FontFamily="{StaticResource PhoneFontFamilyNormal}"
-    FontSize="{StaticResource PhoneFontSizeNormal}"
-    Foreground="{StaticResource PhoneForegroundBrush}"
-    SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
-    mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
-    shell:SystemTray.IsVisible="True">
-
-    <!--LayoutRoot is the root grid where all page content is placed-->
-    <Grid x:Name="LayoutRoot" Background="Yellow">
-        <Grid.RowDefinitions>
-            <RowDefinition Height="Auto"/>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-
-    </Grid>
- 
-
-</phone:PhoneApplicationPage>
diff --git a/templates/standalone/Plugins/UI/ImageCapture.xaml.cs b/templates/standalone/Plugins/UI/ImageCapture.xaml.cs
deleted file mode 100644
index 234b444..0000000
--- a/templates/standalone/Plugins/UI/ImageCapture.xaml.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
-    public partial class ImageCapture : PhoneApplicationPage
-    {
-        public ImageCapture()
-        {
-            InitializeComponent();
-        }
-    }
-
-    public class ImageCaptureTask
-    {
-        /// <summary>
-        /// Represents an image returned from a call to the Show method of
-        /// a WPCordovaClassLib.Cordova.Controls.ImageCaptureTask object
-        /// </summary>
-        //public class AudioResult : TaskEventArgs
-        //{
-        //    /// <summary>
-        //    /// Initializes a new instance of the AudioResult class.
-        //    /// </summary>
-        //    public AudioResult()
-        //    { }
-
-        //    /// <summary>
-        //    /// Initializes a new instance of the AudioResult class
-        //    /// with the specified Microsoft.Phone.Tasks.TaskResult.
-        //    /// </summary>
-        //    /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
-        //    public AudioResult(TaskResult taskResult)
-        //        : base(taskResult)
-        //    { }
-
-        //    /// <summary>
-        //    ///  Gets the file name of the recorded audio.
-        //    /// </summary>
-        //    public Stream AudioFile { get; internal set; }
-
-        //    /// <summary>
-        //    /// Gets the stream containing the data for the recorded audio.
-        //    /// </summary>
-        //    public string AudioFileName { get; internal set; }
-        //}
-
-        ///// <summary>
-        ///// Occurs when a audio recording task is completed.
-        ///// </summary>
-        //public event EventHandler<AudioResult> Completed;
-
-        /// <summary>
-        /// Shows Audio Recording application
-        /// </summary>
-        public void Show()
-        {
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
-                root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
-                string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
-
-                // dummy parameter is used to always open a fresh version
-                root.Navigate(new System.Uri(baseUrl + "Cordova/UI/ImageCapture.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
-            });
-        }
-
-        /// <summary>
-        /// Performs additional configuration of the recording application.
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            ImageCapture imageCapture = e.Content as ImageCapture;
-            if (imageCapture != null)
-            {
-                (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
-                //imageCapture.Completed += this.Completed;
-                //else if (this.Completed != null)
-                //{
-                //    this.Completed(this, new AudioResult(TaskResult.Cancel));
-                //}
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/Plugins/UI/NotificationBox.xaml b/templates/standalone/Plugins/UI/NotificationBox.xaml
deleted file mode 100644
index 1ca5d5f..0000000
--- a/templates/standalone/Plugins/UI/NotificationBox.xaml
+++ /dev/null
@@ -1,62 +0,0 @@
-﻿<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
--->
-<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    mc:Ignorable="d"
-    FontFamily="{StaticResource PhoneFontFamilyNormal}"
-    FontSize="{StaticResource PhoneFontSizeNormal}"
-    Foreground="{StaticResource PhoneForegroundBrush}"
-    d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
-
-    <Grid x:Name="LayoutRoot" 
-          Background="{StaticResource PhoneSemitransparentBrush}" VerticalAlignment="Stretch">
-        
-        <Grid.RowDefinitions>
-            <RowDefinition Height="Auto"/>
-            <RowDefinition Height="*"/>
-        </Grid.RowDefinitions>
-        
-
-        <!--TitlePanel contains the name of the application and page title-->
-        <StackPanel x:Name="TitlePanel" 
-                    Grid.Row="0" 
-                    Background="{StaticResource PhoneSemitransparentBrush}">
-            <TextBlock x:Name="PageTitle" 
-                       Text="Title" 
-                       Margin="10,10" 
-                       Style="{StaticResource PhoneTextTitle2Style}"/>
-            
-            <TextBlock x:Name="SubTitle" 
-                       Text="Subtitle" 
-                       TextWrapping="Wrap"
-                       Margin="10,10"
-                       Style="{StaticResource PhoneTextTitle3Style}"/>
-            
-            <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">       
-            <StackPanel x:Name="ButtonPanel"
-                        Margin="10,10"
-                        Orientation="Horizontal"/>
-            </ScrollViewer>
-
-        </StackPanel>
-    </Grid>
-</UserControl>
diff --git a/templates/standalone/Plugins/UI/NotificationBox.xaml.cs b/templates/standalone/Plugins/UI/NotificationBox.xaml.cs
deleted file mode 100644
index 50b2f2a..0000000
--- a/templates/standalone/Plugins/UI/NotificationBox.xaml.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-﻿/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
-    public partial class NotificationBox : UserControl
-    {
-        public NotificationBox()
-        {
-            InitializeComponent();
-        }
-    }
-}
diff --git a/templates/standalone/Plugins/UI/VideoCaptureTask.cs b/templates/standalone/Plugins/UI/VideoCaptureTask.cs
deleted file mode 100644
index def2a88..0000000
--- a/templates/standalone/Plugins/UI/VideoCaptureTask.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.IO;
-using System.Windows;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Tasks;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
-    /// <summary>
-    /// Allows an application to launch the Video Recording application. 
-    /// Use this to allow users to record video from your application.
-    /// </summary>
-    public class VideoCaptureTask
-    {
-        /// <summary>
-        /// Represents recorded video returned from a call to the Show method of
-        /// a WPCordovaClassLib.Cordova.Controls.VideoCaptureTask object
-        /// </summary>
-        public class VideoResult : TaskEventArgs
-        {
-            /// <summary>
-            /// Initializes a new instance of the VideoResult class.
-            /// </summary>
-            public VideoResult()
-            { }
-
-            /// <summary>
-            /// Initializes a new instance of the VideoResult class
-            /// with the specified Microsoft.Phone.Tasks.TaskResult.
-            /// </summary>
-            /// <param name="taskResult">Associated Microsoft.Phone.Tasks.TaskResult</param>
-            public VideoResult(TaskResult taskResult)
-                : base(taskResult)
-            { }
-
-            /// <summary>
-            ///  Gets the file name of the recorded Video.
-            /// </summary>
-            public Stream VideoFile { get; internal set; }
-
-            /// <summary>
-            /// Gets the stream containing the data for the recorded Video.
-            /// </summary>
-            public string VideoFileName { get; internal set; }
-        }
-
-        /// <summary>
-        /// Occurs when a Video recording task is completed.
-        /// </summary>
-        public event EventHandler<VideoResult> Completed;
-
-        /// <summary>
-        /// Shows Video Recording application
-        /// </summary>
-        public void Show()
-        {
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                var root = Application.Current.RootVisual as PhoneApplicationFrame;
-
-                root.Navigated += new System.Windows.Navigation.NavigatedEventHandler(NavigationService_Navigated);
-
-                string baseUrl = WPCordovaClassLib.Cordova.Commands.BaseCommand.GetBaseURL();
-                // dummy parameter is used to always open a fresh version
-                root.Navigate(new System.Uri(baseUrl + "CordovaLib/UI/VideoRecorder.xaml?dummy=" + Guid.NewGuid().ToString(), UriKind.Relative));
-            });
-        }
-
-        /// <summary>
-        /// Performs additional configuration of the recording application.
-        /// </summary>
-        private void NavigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            if (!(e.Content is VideoRecorder)) return;
-
-            (Application.Current.RootVisual as PhoneApplicationFrame).Navigated -= NavigationService_Navigated;
-
-            VideoRecorder VideoRecorder = (VideoRecorder)e.Content;
-
-            if (VideoRecorder != null)
-            {
-                VideoRecorder.Completed += this.Completed;
-            }
-            else if (this.Completed != null)
-            {
-                this.Completed(this, new VideoResult(TaskResult.Cancel));
-            }
-        }
-
-    }
-}
diff --git a/templates/standalone/Plugins/UI/VideoRecorder.xaml b/templates/standalone/Plugins/UI/VideoRecorder.xaml
deleted file mode 100644
index c78fdb0..0000000
--- a/templates/standalone/Plugins/UI/VideoRecorder.xaml
+++ /dev/null
@@ -1,52 +0,0 @@
-﻿<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
--->
-<phone:PhoneApplicationPage 
-    x:Class="WPCordovaClassLib.Cordova.UI.VideoRecorder"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
-    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
-    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
-    FontFamily="{StaticResource PhoneFontFamilyNormal}"
-    FontSize="{StaticResource PhoneFontSizeNormal}"
-    Foreground="{StaticResource PhoneForegroundBrush}"
-    SupportedOrientations="Landscape" Orientation="LandscapeLeft"
-    shell:SystemTray.IsVisible="False">
-   
-    <Canvas x:Name="LayoutRoot" Background="Transparent" Grid.ColumnSpan="1" Grid.Column="0">
-
-        <Rectangle 
-            x:Name="viewfinderRectangle"
-            Width="640" 
-            Height="480" 
-            HorizontalAlignment="Left" 
-            Canvas.Left="80"/>
-        
-    </Canvas>
-
-    <phone:PhoneApplicationPage.ApplicationBar>
-        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
-            <shell:ApplicationBarIconButton IconUri="/Images/appbar.feature.video.rest.png" Text="Record"  x:Name="btnStartRecording" Click="StartRecording_Click" />
-            <shell:ApplicationBarIconButton IconUri="/Images/appbar.save.rest.png" Text="Take" x:Name="btnTakeVideo" Click="TakeVideo_Click"/>            
-        </shell:ApplicationBar>
-    </phone:PhoneApplicationPage.ApplicationBar>
-
-</phone:PhoneApplicationPage>
diff --git a/templates/standalone/Plugins/UI/VideoRecorder.xaml.cs b/templates/standalone/Plugins/UI/VideoRecorder.xaml.cs
deleted file mode 100644
index 6ab1cc3..0000000
--- a/templates/standalone/Plugins/UI/VideoRecorder.xaml.cs
+++ /dev/null
@@ -1,405 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows.Media;
-using System.Windows.Navigation;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-using Microsoft.Phone.Tasks;
-using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;
-
-namespace WPCordovaClassLib.Cordova.UI
-{
-    public partial class VideoRecorder : PhoneApplicationPage
-    {
-
-        #region Constants
-
-        /// <summary>
-        /// Caption for record button in ready state
-        /// </summary>
-        private const string RecordingStartCaption = "Record";
-
-        /// <summary>
-        /// Caption for record button in recording state
-        /// </summary>
-        private const string RecordingStopCaption = "Stop";
-
-        /// <summary>
-        /// Start record icon URI
-        /// </summary>
-        private const string StartIconUri = "/Images/appbar.feature.video.rest.png";
-
-        /// <summary>
-        /// Stop record icon URI
-        /// </summary>
-        private const string StopIconUri = "/Images/appbar.stop.rest.png";
-
-        /// <summary>
-        /// Folder to save video clips
-        /// </summary>
-        private const string LocalFolderName = "VideoCache";
-
-        /// <summary>
-        /// File name format
-        /// </summary>
-        private const string FileNameFormat = "Video-{0}.mp4";
-
-        /// <summary>
-        /// Temporary file name
-        /// </summary>
-        private const string defaultFileName = "NewVideoFile.mp4";
-
-        #endregion
-
-        #region Callbacks
-        /// <summary>
-        /// Occurs when a video recording task is completed.
-        /// </summary>
-        public event EventHandler<VideoResult> Completed;
-
-        #endregion
-
-        #region Fields
-
-        /// <summary>
-        /// Viewfinder for capturing video
-        /// </summary>
-        private VideoBrush videoRecorderBrush;
-
-        /// <summary>
-        /// Path to save video clip
-        /// </summary>
-        private string filePath;
-
-        /// <summary>
-        /// Source for capturing video. 
-        /// </summary>
-        private CaptureSource captureSource;
-
-        /// <summary>
-        /// Video device
-        /// </summary>
-        private VideoCaptureDevice videoCaptureDevice;
-
-        /// <summary>
-        /// File sink so save recording video in Isolated Storage
-        /// </summary>
-        private FileSink fileSink;
-
-        /// <summary>
-        /// For managing button and application state 
-        /// </summary>
-        private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };
-
-        /// <summary>
-        /// Current video state
-        /// </summary>
-        private VideoState currentVideoState;
-
-        /// <summary>
-        /// Stream to return result
-        /// </summary>
-        private MemoryStream memoryStream;
-
-        /// <summary>
-        /// Recording result, dispatched back when recording page is closed
-        /// </summary>
-        private VideoResult result = new VideoResult(TaskResult.Cancel);
-
-        #endregion
-
-        /// <summary>
-        /// Initializes components
-        /// </summary>
-        public VideoRecorder()
-        {
-            InitializeComponent();
-
-            PhoneAppBar = (ApplicationBar)ApplicationBar;
-            PhoneAppBar.IsVisible = true;
-            btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
-            btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
-        }
-
-        /// <summary>
-        /// Initializes the video recorder then page is loading
-        /// </summary>
-        protected override void OnNavigatedTo(NavigationEventArgs e)
-        {
-            base.OnNavigatedTo(e);
-            this.InitializeVideoRecorder();
-        }
-
-        /// <summary>
-        /// Disposes camera and media objects then leave the page
-        /// </summary>
-        protected override void OnNavigatedFrom(NavigationEventArgs e)
-        {
-            this.DisposeVideoRecorder();
-
-            if (this.Completed != null)
-            {
-                this.Completed(this, result);
-            }
-            base.OnNavigatedFrom(e);
-        }
-
-        /// <summary>
-        /// Handles TakeVideo button click
-        /// </summary>
-        private void TakeVideo_Click(object sender, EventArgs e)
-        {
-            this.result = this.SaveVideoClip();
-            this.NavigateBack();
-        }
-
-        private void NavigateBack()
-        {
-            if (this.NavigationService.CanGoBack)
-            {
-                this.NavigationService.GoBack();
-            }
-        }
-
-        /// <summary>
-        /// Resaves video clip from temporary directory to persistent 
-        /// </summary>
-        private VideoResult SaveVideoClip()
-        {
-            try
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
-                    {
-                        return new VideoResult(TaskResult.Cancel);
-                    }
-
-                    string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
-                    string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
-                    isoFile.CopyFile(filePath, newPath);
-                    isoFile.DeleteFile(filePath);
-
-                    memoryStream = new MemoryStream();
-                    using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
-                    {
-                        fileStream.CopyTo(memoryStream);
-                    }
-
-                    VideoResult result = new VideoResult(TaskResult.OK);
-                    result.VideoFileName = newPath;
-                    result.VideoFile = this.memoryStream;
-                    result.VideoFile.Seek(0, SeekOrigin.Begin);
-                    return result;
-                }
-
-            }
-            catch (Exception)
-            {
-                return new VideoResult(TaskResult.None);
-            }
-        }
-
-        /// <summary>
-        /// Updates the buttons on the UI thread based on current state. 
-        /// </summary>
-        /// <param name="currentState">current UI state</param>
-        private void UpdateUI(VideoState currentState)
-        {
-            Dispatcher.BeginInvoke(delegate
-            {
-                switch (currentState)
-                {
-                    case VideoState.CameraNotSupported:
-                        btnStartRecording.IsEnabled = false;
-                        btnTakeVideo.IsEnabled = false;
-                        break;
-
-                    case VideoState.Initialized:
-                        btnStartRecording.Text = RecordingStartCaption;
-                        btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
-                        btnTakeVideo.IsEnabled = false;
-                        break;
-
-                    case VideoState.Ready:
-                        btnStartRecording.Text = RecordingStartCaption;
-                        btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
-                        btnTakeVideo.IsEnabled = true;
-                        break;
-
-                    case VideoState.Recording:
-                        btnStartRecording.Text = RecordingStopCaption;
-                        btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
-                        btnTakeVideo.IsEnabled = false;
-                        break;
-
-                    default:
-                        break;
-                }
-                currentVideoState = currentState;
-            });
-        }
-
-        /// <summary>
-        /// Initializes VideoRecorder
-        /// </summary>
-        public void InitializeVideoRecorder()
-        {
-            if (captureSource == null)
-            {
-                captureSource = new CaptureSource();
-                fileSink = new FileSink();
-                videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
-
-                if (videoCaptureDevice != null)
-                {
-                    videoRecorderBrush = new VideoBrush();
-                    videoRecorderBrush.SetSource(captureSource);
-                    viewfinderRectangle.Fill = videoRecorderBrush;
-                    captureSource.Start();
-                    this.UpdateUI(VideoState.Initialized);
-                }
-                else
-                {
-                    this.UpdateUI(VideoState.CameraNotSupported);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Sets recording state: start recording 
-        /// </summary>
-        private void StartVideoRecording()
-        {
-            try
-            {
-                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
-                {
-                    captureSource.Stop();
-                    fileSink.CaptureSource = captureSource;
-                    filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);
-
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (!isoFile.DirectoryExists(LocalFolderName))
-                        {
-                            isoFile.CreateDirectory(LocalFolderName);
-                        }
-
-                        if (isoFile.FileExists(filePath))
-                        {
-                            isoFile.DeleteFile(filePath);
-                        }
-                    }
-
-                    fileSink.IsolatedStorageFileName = filePath;
-                }
-
-                if (captureSource.VideoCaptureDevice != null
-                    && captureSource.State == CaptureState.Stopped)
-                {
-                    captureSource.Start();
-                }
-                this.UpdateUI(VideoState.Recording);
-            }
-            catch (Exception)
-            {
-                this.result = new VideoResult(TaskResult.None);
-                this.NavigateBack();
-            }
-        }
-
-        /// <summary>
-        /// Sets the recording state: stop recording
-        /// </summary>
-        private void StopVideoRecording()
-        {
-            try
-            {
-                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
-                {
-                    captureSource.Stop();
-                    fileSink.CaptureSource = null;
-                    fileSink.IsolatedStorageFileName = null;
-                    this.StartVideoPreview();
-                }
-            }
-            catch (Exception)
-            {
-                this.result = new VideoResult(TaskResult.None);
-                this.NavigateBack();
-            }
-        }
-
-        /// <summary>
-        /// Sets the recording state: display the video on the viewfinder. 
-        /// </summary>
-        private void StartVideoPreview()
-        {
-            try
-            {
-                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
-                {
-                    videoRecorderBrush.SetSource(captureSource);
-                    viewfinderRectangle.Fill = videoRecorderBrush;
-                    captureSource.Start();
-                    this.UpdateUI(VideoState.Ready);
-                }
-            }
-            catch (Exception)
-            {
-                this.result = new VideoResult(TaskResult.None);
-                this.NavigateBack();
-            }
-        }
-
-        /// <summary>
-        /// Starts video recording 
-        /// </summary>
-        private void StartRecording_Click(object sender, EventArgs e)
-        {
-            if (currentVideoState == VideoState.Recording)
-            {
-                this.StopVideoRecording();
-            }
-            else
-            {
-                this.StartVideoRecording();
-            }
-        }
-
-        /// <summary>
-        /// Releases resources
-        /// </summary>
-        private void DisposeVideoRecorder()
-        {
-            if (captureSource != null)
-            {
-                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
-                {
-                    captureSource.Stop();
-                }
-                captureSource = null;
-                videoCaptureDevice = null;
-                fileSink = null;
-                videoRecorderBrush = null;
-            }
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/Properties/AppManifest.xml b/templates/standalone/Properties/AppManifest.xml
deleted file mode 100644
index 877ea4b..0000000
--- a/templates/standalone/Properties/AppManifest.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-﻿<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
-        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
->
-  <Deployment.Parts>
-  </Deployment.Parts>
-</Deployment>
diff --git a/templates/standalone/Properties/AssemblyInfo.cs b/templates/standalone/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3f5dc5a..0000000
--- a/templates/standalone/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-﻿using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Resources;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("CordovaAppProj")]
-[assembly: AssemblyDescription("2.0.0.0")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Apache Cordova")]
-[assembly: AssemblyProduct("CordovaAppProj")]
-[assembly: AssemblyCopyright("Copyright © Apache Cordova 2013")]
-[assembly: AssemblyTrademark("Apache Cordova")]
-[assembly: AssemblyCulture("")]
-
-[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("9e27b972-0825-4386-ba17-63c695262c3d")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers 
-// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/templates/standalone/Properties/WMAppManifest.xml b/templates/standalone/Properties/WMAppManifest.xml
deleted file mode 100644
index 96332e1..0000000
--- a/templates/standalone/Properties/WMAppManifest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.1">
-  <App xmlns="" ProductID="{$guid1$}" Title="$safeprojectname$" 
-       RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal"  
-       Author="$safeprojectname$ author" 
-       BitsPerPixel="32" 
-       Description="Apache Cordova for Windows Phone 7"
-       Publisher="$safeprojectname$">
-    
-    <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
-    <Capabilities>
-      <Capability Name="ID_CAP_IDENTITY_DEVICE" />
-      <Capability Name="ID_CAP_IDENTITY_USER" />
-      <Capability Name="ID_CAP_LOCATION" />
-      <Capability Name="ID_CAP_NETWORKING" />
-      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
-      <Capability Name="ID_CAP_APPOINTMENTS"/>
-      <Capability Name="ID_CAP_CONTACTS"/>
-      <Capability Name="ID_CAP_ISV_CAMERA"/>
-      <Capability Name="ID_CAP_MEDIALIB"/>
-      <Capability Name="ID_CAP_MICROPHONE"/>
-      <Capability Name="ID_CAP_PHONEDIALER"/>
-      <Capability Name="ID_CAP_PUSH_NOTIFICATION"/>
-      <Capability Name="ID_CAP_SENSORS"/>
-      <Capability Name="ID_HW_FRONTCAMERA"/>      
-    </Capabilities>
-    
-    <Tasks>
-      <DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
-    </Tasks>
-    <Tokens>
-      <PrimaryToken TokenID="$safeprojectname$Token" TaskName="_default">
-        <TemplateType5>
-          <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
-          <Count>0</Count>
-          <Title>$safeprojectname$</Title>
-        </TemplateType5>
-      </PrimaryToken>
-    </Tokens>
-  </App>
-</Deployment>
\ No newline at end of file
diff --git a/templates/standalone/README.md b/templates/standalone/README.md
deleted file mode 100644
index 6374253..0000000
--- a/templates/standalone/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Project Template
-===
-
-This project template needs to be built to be installed.
-
-
-This template includes the full source code for Windows Phone 7
-
-
-In order to build this template in Visual Studio Express for Windows Phone 7 :
-
-1. Open the solution file in Visual Studio
-2. Choose File->Export Template and follow the directions.
\ No newline at end of file
diff --git a/templates/standalone/SplashScreenImage.jpg b/templates/standalone/SplashScreenImage.jpg
deleted file mode 100644
index d35501d..0000000
--- a/templates/standalone/SplashScreenImage.jpg
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/VERSION b/templates/standalone/VERSION
deleted file mode 100644
index c8e38b6..0000000
--- a/templates/standalone/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-2.9.0
diff --git a/templates/standalone/config.xml b/templates/standalone/config.xml
deleted file mode 100644
index 6ef524c..0000000
--- a/templates/standalone/config.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-﻿<?xml version="1.0" encoding="UTF-8"?>
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-# http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
--->
-<widget>
-
-  <features>
-    <feature name="Device">
-      <param name="wp-package" value="Device" onload="false"/>
-    </feature>
-    <feature name="Logger">
-      <param name="wp-package" value="Logger"/>
-    </feature>
-    <feature name="Compass">
-      <param name="wp-package" value="Compass" />
-    </feature>
-    <feature name="Accelerometer">
-      <param name="wp-package" value="Accelerometer"/>
-    </feature>
-    <feature name="Camera">
-      <param name="wp-package" value="Camera"/>
-    </feature>
-    <feature name="NetworkStatus">
-      <param name="wp-package" value="NetworkStatus"/>
-    </feature>
-    <feature name="Contacts">
-      <param name="wp-package" value="Contacts"/>
-    </feature>
-    <feature name="DebugConsole">
-      <param name="wp-package" value="DebugConsole"/>
-    </feature>
-    <feature name="Echo">
-      <param name="wp-package" value="Echo"/>
-    </feature>
-    <feature name="File">
-      <param name="wp-package" value="File"/>
-    </feature>
-    <feature name="FileTransfer">
-      <param name="wp-package" value="FileTransfer"/>
-    </feature>
-    <feature name="Geolocation">
-      <param name="wp-package" value="Geolocation"/>
-    </feature>
-    <feature name="Geolocation">
-      <param name="wp-package" value="Geolocation"/>
-    </feature>
-    <feature name="Media">
-      <param name="wp-package" value="Media"/>
-    </feature>
-    <feature name="Capture">
-      <param name="wp-package" value="Capture"/>
-    </feature>
-    <feature name="SplashScreen">
-      <param name="wp-package" value="SplashScreen"/>
-    </feature>
-    <feature name="Battery">
-      <param name="wp-package" value="Battery"/>
-    </feature>
-    <feature name="Globalization">
-      <param name="wp-package" value="Globalization"/>
-    </feature>
-    <feature name="InAppBrowser">
-      <param name="wp-package" value="InAppBrowser"/>
-    </feature>
-  </features>
-
-
-  <access origin="*"/>
-
-</widget>
diff --git a/templates/standalone/cordova/build.bat b/templates/standalone/cordova/build.bat
deleted file mode 100644
index b48598a..0000000
--- a/templates/standalone/cordova/build.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\build.js (
-    cscript "%full_path%lib\build.js" %* //nologo
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find 'build.js' in cordova/lib, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/templates/standalone/cordova/clean.bat b/templates/standalone/cordova/clean.bat
deleted file mode 100644
index 1bafe1b..0000000
--- a/templates/standalone/cordova/clean.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\clean.js (
-    cscript "%full_path%lib\clean.js" %* //nologo
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find 'clean.js' in cordova/lib, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy.sln b/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy.sln
deleted file mode 100644
index 3305276..0000000
--- a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-﻿
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CordovaDeploy", "CordovaDeploy\CordovaDeploy.csproj", "{E752165B-AF59-4FF0-8601-A2A69FE09E0E}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|x86 = Debug|x86
-		Release|x86 = Release|x86
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{E752165B-AF59-4FF0-8601-A2A69FE09E0E}.Debug|x86.ActiveCfg = Debug|x86
-		{E752165B-AF59-4FF0-8601-A2A69FE09E0E}.Debug|x86.Build.0 = Debug|x86
-		{E752165B-AF59-4FF0-8601-A2A69FE09E0E}.Release|x86.ActiveCfg = Release|x86
-		{E752165B-AF59-4FF0-8601-A2A69FE09E0E}.Release|x86.Build.0 = Release|x86
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/CordovaDeploy.csproj b/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/CordovaDeploy.csproj
deleted file mode 100644
index fb9949f..0000000
--- a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/CordovaDeploy.csproj
+++ /dev/null
@@ -1,79 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
--->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{E752165B-AF59-4FF0-8601-A2A69FE09E0E}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>CordovaDeploy</RootNamespace>
-    <AssemblyName>CordovaDeploy</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <PlatformTarget>x86</PlatformTarget>
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <PlatformTarget>x86</PlatformTarget>
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Microsoft.Smartdevice.Connectivity, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>C:\Program Files (x86)\Common Files\microsoft shared\Phone Tools\CoreCon\10.0\Bin\Microsoft.Smartdevice.Connectivity.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/Program.cs b/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/Program.cs
deleted file mode 100644
index 2e70187..0000000
--- a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/Program.cs
+++ /dev/null
@@ -1,235 +0,0 @@
-﻿/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Microsoft.SmartDevice.Connectivity;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.IO;
-using System.Xml.XPath;
-using System.Xml;
-using System.Xml.Linq;
-
-
-namespace CordovaDeploy
-{
-
-    class DeployTool
-    {
-
-        static void Usage()
-        {
-            Log("Usage: CordovaDeploy [ -devices  BuildOutputPath -d:DeviceIndex ]");
-            Log("    -devices : lists the devices and exits");
-            Log("    BuildOutputPath : path to the built application, typically Bin/Debug/ or Bin/Release/");
-            Log("    -d : index of the device to deploy, default is 0 ");
-            Log("examples:");
-            Log("  CordovaDeploy -devices");
-            Log("  CordovaDeploy Bin/Debug");
-            Log("  CordovaDeploy Bin/Release -d:1");
-
-        }
-
-        static void ReadWait()
-        {
-            //Console.WriteLine("\nPress ENTER to continue...");
-            //Console.Read();
-        }
-
-        static void Log(string msg, bool error = false)
-        {
-            Debug.WriteLine(msg);
-            if (error)
-            {
-                Console.Error.WriteLine(msg);
-            }
-            else
-            {
-                Console.Out.WriteLine(msg);
-            }
-        }
-
-        static Guid ReadAppId(string root)
-        {
-            Guid appID = Guid.Empty;
-            string manifestFilePath = root + @"\Properties\WMAppManifest.xml";
-
-            if (File.Exists(manifestFilePath))
-            {
-                XDocument xdoc = XDocument.Load(manifestFilePath);
-                var appNode = xdoc.Root.Descendants("App").FirstOrDefault();
-                if (appNode != null)
-                {
-                    string guidStr = appNode.Attribute("ProductID").Value;
-                    appID = new Guid(guidStr);
-                }
-                else
-                {
-                    Log(string.Format("Unable to find appID, expected to find an App.ProductID property defined in the file {0}", manifestFilePath), true);
-                }
-            }
-            else
-            {
-                Log(string.Format("Error: the file {0} does not exist", manifestFilePath), true);
-            }
-
-
-            return appID;
-        }
-
-
-
-        static void ListDevices()
-        {
-            // Get CoreCon WP7 SDK
-            DatastoreManager dsmgrObj = new DatastoreManager(1033);
-            Platform WP7SDK = dsmgrObj.GetPlatforms().Single(p => p.Name == "Windows Phone 7");
-            Collection<Device> devices = WP7SDK.GetDevices();
-            for (int index = 0; index < devices.Count; index++)
-            {
-                Device d = devices[index];
-                string info = string.Format("{0} : {1} : {2}", index.ToString(), d.Id, d.Name);
-                Log(info);
-            }
-        }
-
-        static void Main(string[] args)
-        {
-            int deviceIndex = 0;
-
-            string iconFilePath = "";
-            string xapFilePath = "";
-            Guid appID = Guid.Empty;
-
-            string root = Directory.GetCurrentDirectory();
-
-            if (args.Length < 1)
-            {
-                Usage();
-                ReadWait();
-                return;
-            }
-            else if (args[0] == "-devices")
-            {
-                ListDevices();
-                return;
-            }
-            else if (args.Length > 1 && args[1].StartsWith("-d:"))
-            {
-                deviceIndex = int.Parse(args[1].Substring(3));
-            }
-
-
-            if (Directory.Exists(args[0]))
-            {
-                DirectoryInfo info = new DirectoryInfo(args[0]);
-                root = info.FullName;
-            }
-
-            appID = ReadAppId(root);
-            if (appID == Guid.Empty)
-            {
-                // Logging of errors is done in ReadAppId
-                return;
-            }
-
-            if (File.Exists(root + @"\ApplicationIcon.png"))
-            {
-                iconFilePath = root + @"\ApplicationIcon.png";
-            }
-            else
-            {
-                Log(string.Format("Error: could not find application icon at {0}", root + @"\ApplicationIcon.png"), true);
-                ReadWait();
-                return;
-            }
-
-            try {
-                xapFilePath = Directory.GetFiles(root + @"\Bin\Debug", "*.xap").FirstOrDefault();
-            } catch (DirectoryNotFoundException e) {
-                try {
-                    xapFilePath = Directory.GetFiles(root + @"\Bin\Release", "*.xap").FirstOrDefault();
-                } catch (DirectoryNotFoundException ex) {
-                    Log(string.Format("Error: could not find project build directoy in {0}", root), true);
-                    Log("make sure your app has been successfully built before deploying.", true);
-                }
-            }
-
-            if (string.IsNullOrEmpty(xapFilePath))
-            {
-                Log(string.Format("Error: could not find application .xap in folder {0}", root), true);
-                ReadWait();
-                return;
-            }
-
-
-            // Get CoreCon WP7 SDK
-            DatastoreManager dsmgrObj = new DatastoreManager(1033);
-            Collection<Platform> WP7SDKs = dsmgrObj.GetPlatforms();
-            Platform WP7SDK = dsmgrObj.GetPlatforms().Single(p => p.Name == "Windows Phone 7");
-
-            Collection<Device> devices = null;
-
-            devices = WP7SDK.GetDevices();
-
-            //// Get Emulator / Device
-            Device WP7Device = devices[deviceIndex];
-
-            if (WP7Device != null)
-            {
-                RemoteApplication app;
-                bool isConnected = WP7Device.IsConnected();
-
-                Debug.WriteLine(WP7Device.ToString());
-
-                if (!isConnected)
-                {
-                    try
-                    {
-                        WP7Device.Connect();
-                    }
-                    catch (Exception ex)
-                    {
-                        Log("Error: " + ex.Message, true);
-                        ReadWait();
-                        return;
-                    }
-                }
-
-                if (WP7Device.IsApplicationInstalled(appID))
-                {
-                    Log("Uninstalling XAP from " + WP7Device.Name);
-                    app = WP7Device.GetApplication(appID);
-                    app.Uninstall();
-                }
-
-                Log("Installing app on " + WP7Device.Name);
-                app = WP7Device.InstallApplication(appID, appID, "NormalApp", iconFilePath, xapFilePath);
-
-                Log("Launching app on " + WP7Device.Name);
-                app.Launch();
-
-                ReadWait();
-            }
-        }
-    }
-}
diff --git a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/Properties/AssemblyInfo.cs b/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3c26c87..0000000
--- a/templates/standalone/cordova/lib/CordovaDeploy/CordovaDeploy/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-﻿using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("CordovaDeploy")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("CordovaDeploy")]
-[assembly: AssemblyCopyright("Copyright ©  2012")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("256b11aa-d4bb-48cf-8024-7c040421fa8d")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/templates/standalone/cordova/lib/build.js b/templates/standalone/cordova/lib/build.js
deleted file mode 100644
index 1375c54..0000000
--- a/templates/standalone/cordova/lib/build.js
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject');
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-
-var args = WScript.Arguments;
-
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\cordova\\lib\\build.js').join('');
-
-// help/usage function
-function Usage() {
-    Log("");
-    Log("Usage: build [ --debug | --release ]");
-    Log("    --help    : Displays this dialog.");
-    Log("    --debug   : Cleans and builds project in debug mode.");
-    Log("    --release : Cleans and builds project in release mode.");
-    Log("examples:");
-    Log("    build ");
-    Log("    build --debug");
-    Log("    build --release");
-    Log("");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// executes a commmand in the shell
-function exec_verbose(command) {
-    //Log("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status == 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if (!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadLine();
-            Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if (!oShell.StdErr.AtEndOfStream) {
-        var line = oShell.StdErr.ReadAll();
-        Log(line, true);
-        WScript.Quit(2);
-    }
-}
-
-// checks to see if a .csproj file exists in the project root
-function is_cordova_project(path) {
-    if (fso.FolderExists(path)) {
-        var proj_folder = fso.GetFolder(path);
-        var proj_files = new Enumerator(proj_folder.Files);
-        for (;!proj_files.atEnd(); proj_files.moveNext()) {
-            if (fso.GetExtensionName(proj_files.item()) == 'csproj') {
-                return true;  
-            }
-        }
-    }
-    return false;
-}
-
-function get_solution_name(path) {
-    if (fso.FolderExists(path)) {
-        var proj_folder = fso.GetFolder(path);
-        var proj_files = new Enumerator(proj_folder.Files);
-        for (;!proj_files.atEnd(); proj_files.moveNext()) {
-            if (fso.GetExtensionName(proj_files.item()) == 'sln') {
-                return proj_files.item();
-            }
-        }
-    }
-    return null;
-}
-
-// builds the project and .xap in release mode
-function build_xap_release(path) {
-    Log("Building Cordova-WP7 Project:");
-    Log("\tConfiguration : Release");
-    Log("\tDirectory : " + path);
-    
-    wscript_shell.CurrentDirectory = path;
-    exec_verbose('msbuild ' + get_solution_name(path) + ' /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Release');
-    
-    // check if file xap was created
-    if (fso.FolderExists(path + '\\Bin\\Release')) {
-        var out_folder = fso.GetFolder(path + '\\Bin\\Release');
-        var out_files = new Enumerator(out_folder.Files);
-        for (;!out_files.atEnd(); out_files.moveNext()) {
-            if (fso.GetExtensionName(out_files.item()) == 'xap') {
-                Log("BUILD SUCCESS.");
-                return;  
-            }
-        }
-    }
-    Log('ERROR: MSBuild failed to create .xap when building cordova-wp7 for release.', true);
-    WScript.Quit(2);
-}
-
-// builds the project and .xap in debug mode
-function build_xap_debug(path) {
-    Log("Building Cordova-WP7 Project:");
-    Log("\tConfiguration : Debug");
-    Log("\tDirectory : " + path);
-    
-    wscript_shell.CurrentDirectory = path;
-    exec_verbose('msbuild ' + get_solution_name(path) + ' /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Debug');
-    
-    // check if file xap was created
-    if (fso.FolderExists(path + '\\Bin\\Debug')) {
-        var out_folder = fso.GetFolder(path + '\\Bin\\Debug');
-        var out_files = new Enumerator(out_folder.Files);
-        for (;!out_files.atEnd(); out_files.moveNext()) {
-            if (fso.GetExtensionName(out_files.item()) == 'xap') {
-                Log("BUILD SUCCESS.");
-                return;  
-            }
-        }
-    }
-    Log('ERROR: MSBuild failed to create .xap when building cordova-wp7 for debugging.', true);
-    WScript.Quit(2);
-}
-
-
-Log("");
-
-if (args.Count() > 0) {
-    // support help flags
-    if (args(0) == "--help" || args(0) == "/?" ||
-            args(0) == "help" || args(0) == "-help" || args(0) == "/help") {
-        Usage();
-        WScript.Quit(2);
-    }
-    else if (args.Count() > 1) {
-        Log("Error: Too many arguments.", true);
-        Usage();
-        WScript.Quit(2);
-    }
-    else if (fso.FolderExists(ROOT)) {
-        if (!is_cordova_project(ROOT)) {
-            Log('Error: .csproj file not found in ' + ROOT, true);
-            Log('could not build project.', true);
-            WScript.Quit(2);
-        }
-
-        if (args(0) == "--debug" || args(0) == "-d") {
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\clean');
-            build_xap_debug(ROOT);
-        }
-        else if (args(0) == "--release" || args(0) == "-r") {
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\clean');
-            build_xap_release(ROOT);
-        }
-        else {
-            Log("Error: \"" + args(0) + "\" is not recognized as a build option", true);
-            Usage();
-            WScript.Quit(2);
-        }
-    }
-    else {
-        Log("Error: Project directory not found,", true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
-else {
-    Log("WARNING: [ --debug | --release ] not specified, defaulting to debug...");
-    build_xap_debug(ROOT);
-}
diff --git a/templates/standalone/cordova/lib/clean.js b/templates/standalone/cordova/lib/clean.js
deleted file mode 100644
index f5bdbfc..0000000
--- a/templates/standalone/cordova/lib/clean.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject');
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-var args = WScript.Arguments;
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\cordova\\lib\\clean.js').join('');
-
-
-// help function
-function Usage() {
-    Log("");
-    Log("Usage: clean");
-    Log("examples:");
-    Log("    clean");
-    Log("         - deletes all generated files in project");
-    Log("");
-}
-
-//  logs to stdout or stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// cleans any generated files in the cordova project
-function clean_project(path) {
-    delete_if_exists(path + "\\obj");
-    delete_if_exists(path + "\\Bin");
-}
-
-// deletes the path element if it exists
-function delete_if_exists(path) {
-    if (fso.FolderExists(path)) {
-        fso.DeleteFolder(path);
-    }
-    else if (fso.FileExists(path)) {
-        fso.DeleteFile(path);
-    }
-}
-
-
-if (args.Count() > 0) {
-    // support help flags
-    if (args(0) == "--help" || args(0) == "/?" ||
-            args(0) == "help" || args(0) == "-help" || args(0) == "/help") {
-        Usage();
-        WScript.Quit(2);
-    }
-    else {
-        Log("Error: \"" + args(0) + "\" is not recognized as a valid option", true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
-else {
-   if (fso.FolderExists(ROOT)) {
-        Log("Cleaning cordova project...");
-        clean_project(ROOT);
-    }
-    else {
-        Log("Error: Project directory not found,", true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/deploy.js b/templates/standalone/cordova/lib/deploy.js
deleted file mode 100644
index 448fa78..0000000
--- a/templates/standalone/cordova/lib/deploy.js
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject');
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-
-var args = WScript.Arguments;
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\cordova\\lib\\deploy.js').join('');
-    // path to CordovaDeploy.exe
-var CORDOVA_DEPLOY_EXE = '\\cordova\\lib\\CordovaDeploy\\CordovaDeploy\\bin\\Debug\\CordovaDeploy.exe';
-    // path to CordovaDeploy
-var CORDOVA_DEPLOY = '\\cordova\\lib\\CordovaDeploy';
-//device_id for targeting specific device
-var device_id;
-
-//build types
-var NONE = 0,
-    DEBUG = 1,
-    RELEASE = 2,
-    NO_BUILD = 3;
-var build_type = NONE;
-
-//deploy tpyes
-var NONE = 0,
-    EMULATOR = 1,
-    DEVICE = 2,
-    TARGET = 3;
-var deploy_type = NONE;
-
-
-// help function
-function Usage() {
-    Log("");
-    Log("Usage:");
-    Log("  run [ --device || --emulator || --target=<id> ] ");
-    Log("      [ --debug || --release || --nobuild ]");
-    Log("    --device      : Deploys and runs the project on the connected device.");
-    Log("    --emulator    : [DEFAULT] Deploys and runs the project on an emulator.");
-    Log("    --target=<id> : Deploys and runs the project on the specified target.");
-    Log("    --debug       : [DEFAULT] Builds project in debug mode.");
-    Log("    --release     : Builds project in release mode.");
-    Log("    --nobuild     : Ueses pre-built xap, or errors if project is not built.");
-    Log("Examples:");
-    Log("    run");
-    Log("    run --emulator");
-    Log("    run --device");
-    Log("    run --target=7988B8C3-3ADE-488d-BA3E-D052AC9DC710");
-    Log("    run --device --release");
-    Log("    run --emulator --debug");
-    Log("");
-}
-
-// log to stdout or stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-} 
-
-var ForReading = 1, ForWriting = 2, ForAppending = 8;
-var TristateUseDefault = 2, TristateTrue = 1, TristateFalse = 0;
-
-
-// executes a commmand in the shell
-function exec(command) {
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status == 0) {
-        WScript.sleep(100);
-    }
-}
-
-// executes a commmand in the shell
-function exec_verbose(command) {
-    //Log("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status == 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if (!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadAll();
-            Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if (!oShell.StdErr.AtEndOfStream) {
-        var line = oShell.StdErr.ReadAll();
-        Log(line, true);
-        WScript.Quit(2);
-    }
-}
-
-// returns the contents of a file
-function read(filename) {
-    if (fso.FileExists(filename)) {
-        var f=fso.OpenTextFile(filename, 1,2);
-        var s=f.ReadAll();
-        f.Close();
-        return s;
-    }
-    else {
-        Log('Cannot read non-existant file : ' + filename, true);
-        WScript.Quit(2);
-    }
-    return null;
-}
-
-// builds the CordovaDeploy.exe if it does not already exist 
-function cordovaDeploy(path) {
-    if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-        return;
-    }
-
-    Log('CordovaDeploy.exe not found, attempting to build CordovaDeploy.exe...');
-
-    // build CordovaDeploy.exe
-    if (fso.FolderExists(path + '\\cordova') && fso.FolderExists(path + CORDOVA_DEPLOY) && 
-        fso.FileExists(path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln')) {
-        // delete any previously generated files
-        if (fso.FolderExists(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\obj')) {
-            fso.DeleteFolder(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\obj');
-        }
-        if (fso.FolderExists(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\Bin')) {
-            fso.DeleteFolder(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\Bin');
-        }
-        exec_verbose('msbuild ' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln');
-
-        if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-            Log('CordovaDeploy.exe compiled, SUCCESS.');
-        }
-        else {
-            Log('ERROR: MSBUILD FAILED TO COMPILE CordovaDeploy.exe', true);
-            WScript.Quit(2);
-        }
-    }
-    else {
-        Log('ERROR: CordovaDeploy.sln not found, unable to compile CordovaDeploy tool.', true);
-        WScript.Quit(2);
-    }
-}
-
-// launches project on device
-function device(path)
-{
-    cordovaDeploy(path);
-    if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-        Log('Deploying to device ...');
-        //TODO: get device ID from list-devices and deploy to first one
-        exec_verbose('%comspec% /c ' + path + CORDOVA_DEPLOY_EXE + ' ' + path + ' -d:0');
-    }
-    else
-    {
-        Log('Error: Failed to find CordovaDeploy.exe in ' + path, true);
-        Log('DEPLOY FAILED.', true);
-        WScript.Quit(2);
-    }
-}
-
-// launches project on emulator
-function emulator(path)
-{
-    cordovaDeploy(path);
-    if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-        Log('Deploying to emulator ...');
-        //TODO: get emulator ID from list-emulators and deploy to first one
-        exec_verbose('%comspec% /c ' + path + CORDOVA_DEPLOY_EXE + ' ' + path + ' -d:1');
-    }
-    else
-    {
-        Log('Error: Failed to find CordovaDeploy.exe in ' + path, true);
-        Log('DEPLOY FAILED.', true);
-        WScript.Quit(2);
-    }
-}
-
-// builds and launches the project on the specified target
-function target(path) {
-    if (!fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-        cordovaDeploy(path);
-    }
-    wscript_shell.CurrentDirectory = path + CORDOVA_DEPLOY + '\\CordovaDeploy\\bin\\Debug';
-    var cmd = 'CordovaDeploy -devices';
-    var out = wscript_shell.Exec(cmd);
-    while(out.Status == 0) {
-        WScript.Sleep(100);
-    }
-    if (!out.StdErr.AtEndOfStream) {
-        var line = out.StdErr.ReadAll();
-        Log("Error calling CordovaDeploy : ", true);
-        Log(line, true);
-        WScript.Quit(2);
-    }
-    else {
-        if (!out.StdOut.AtEndOfStream) {
-            var line = out.StdOut.ReadAll();
-            var targets = line.split('\r\n');
-            var check_id = new RegExp(device_id);
-            for (target in targets) {
-                if (targets[target].match(check_id)) {
-                    //TODO: this only gets single digit index, account for device index of 10+?
-                    var index = targets[target].substr(0,1);
-                    exec_verbose(path + CORDOVA_DEPLOY_EXE + ' ' + path + ' -d:' + index);
-                    return;
-                }
-            }
-            Log('Error : target ' + device_id + ' was not found.', true);
-            Log('DEPLOY FAILED.', true);
-            WScript.Quit(2);
-        }
-        else {
-            Log('Error : CordovaDeploy Failed to find any devices', true);
-            Log('DEPLOY FAILED.', true);
-            WScript.Quit(2);
-        }
-    }
-}
-
-function build(path) {
-    switch (build_type) {
-        case DEBUG :
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --debug');
-            break;
-        case RELEASE :
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --release');
-            break;
-        case NO_BUILD :
-            break;
-        case NONE :
-            Log("WARNING: [ --debug | --release | --nobuild ] not specified, defaulting to --debug.");
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --debug');
-            break;
-        default :
-            Log("Build option not recognized: " + build_type, true);
-            WScript.Quit(2);
-            break;
-    }
-}
-
-function run(path) {
-    switch(deploy_type) {
-        case EMULATOR :
-            build(path);
-            emulator(path);
-            break;
-        case DEVICE :
-            build(path);
-            device(path);
-            break;
-        case TARGET :
-            build(path);
-            target(path);
-            break;
-        case NONE :
-            Log("WARNING: [ --target=<ID> | --emulator | --device ] not specified, defaulting to --emulator");
-            build(path);
-            emulator(path);
-            break;
-        default :
-            Log("Deploy option not recognized: " + deploy_type, true);
-            WScript.Quit(2);
-            break;
-    }
-}
-
-
-if (args.Count() > 0) {
-    // limit args
-    if (args.Count() > 2) {
-        Log('Error: Too many arguments.', true);
-        Usage();
-        WScript.Quit(2);
-    }
-    else if (fso.FolderExists(ROOT)) {
-        // parse arguments
-        for(var i = 0; i < args.Count(); i++) {
-            if (args(i) == "--release") {
-                build_type = RELEASE;
-            }
-            else if (args(i) == "--debug") {
-                build_type = DEBUG;
-            }
-            else if (args(i) == "--nobuild") {
-                build_type = NO_BUILD;
-            }
-            else if (args(i) == "--emulator" || args(i) == "-e") {
-                deploy_type = EMULATOR;
-            }
-            else if (args(i) == "--device" || args(i) == "-d") {
-                deploy_type = DEVICE;
-            }
-            else if (args(i).substr(0,9) == "--target=") {
-                device_id = args(i).split("--target=").join("");
-                deploy_type = TARGET;
-            }
-             // support help flags
-            else if (args(0) == "--help" || args(0) == "/?" ||
-                    args(0) == "help" || args(0) == "-help" || args(0) == "/help") {
-                Usage();
-                WScript.Quit(2);
-            }
-            else {
-                Log('Error: \"' + args(0) + '\" is not recognized as a deploy option', true);
-                Usage();
-                WScript.Quit(2);
-            }
-        }
-    }
-    else {
-        Log('Error: Project directory not found,', true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
-
-// Finally run the project!
-run(ROOT);
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/install-device.bat b/templates/standalone/cordova/lib/install-device.bat
deleted file mode 100644
index 9507c36..0000000
--- a/templates/standalone/cordova/lib/install-device.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%deploy.js (
-    cscript "%full_path%deploy.js" %* --device --nobuild //nologo
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/install-emulator.bat b/templates/standalone/cordova/lib/install-emulator.bat
deleted file mode 100644
index b3ee451..0000000
--- a/templates/standalone/cordova/lib/install-emulator.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%deploy.js (
-    cscript "%full_path%deploy.js" %* --emulator --nobuild //nologo
-) ELSE (
-    ECHO. 
-    ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/list-devices.bat b/templates/standalone/cordova/lib/list-devices.bat
deleted file mode 100644
index bf4492b..0000000
--- a/templates/standalone/cordova/lib/list-devices.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%target-list.js (
-    cscript "%full_path%target-list.js" %* --devices //nologo
-) ELSE (
-    ECHO. 
-    ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/list-emulator-images.bat b/templates/standalone/cordova/lib/list-emulator-images.bat
deleted file mode 100644
index 3f571c7..0000000
--- a/templates/standalone/cordova/lib/list-emulator-images.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%target-list.js (
-    cscript "%full_path%target-list.js" %* --emulators //nologo
-) ELSE (
-    ECHO. 
-    ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/list-started-emulators.bat b/templates/standalone/cordova/lib/list-started-emulators.bat
deleted file mode 100644
index d779b5d..0000000
--- a/templates/standalone/cordova/lib/list-started-emulators.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@ECHO OFF
-ECHO Sorry, list-started-emulators is not availible yet for Windows Phone. 1>&2
-EXIT /B 1
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/log.js b/templates/standalone/cordova/lib/log.js
deleted file mode 100644
index 0b4ea7d..0000000
--- a/templates/standalone/cordova/lib/log.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject');
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-var args = WScript.Arguments;
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\cordova\\lib\\log.js').join('');
-
-
-// help function
-function Usage() {
-    Log("");
-    Log("Usage: log");
-    Log("examples:");
-    Log("    log");
-    Log("         - logs output from running application  *NOT IMPLIMENTED*");
-    Log("");
-}
-
-//  logs to stdout or stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// log output from running projects *NOT IMPLEMENTED*
-function log_output(path) {
-    Log("ERROR: Logging is not supported on Windows Phone", true);
-    WScript.Quit(1);
-}
-
-
-if (args.Count() > 0) {
-    // support help flags
-    if (args(0) == "--help" || args(0) == "/?" ||
-            args(0) == "help" || args(0) == "-help" || args(0) == "/help") {
-        Usage();
-        WScript.Quit(2);
-    }
-    else {
-        Log("Error: \"" + args(0) + "\" is not recognized as a log option.", true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
-else {
-   if (fso.FolderExists(ROOT)) {
-        log_output(ROOT);
-    }
-    else {
-        Log("Error: Project directory not found,", true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/start-emulator.bat b/templates/standalone/cordova/lib/start-emulator.bat
deleted file mode 100644
index 19983fd..0000000
--- a/templates/standalone/cordova/lib/start-emulator.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@ECHO OFF
-ECHO Sorry, start-emulator is not availible yet for Windows Phone. 1>&2
-EXIT /B 1
\ No newline at end of file
diff --git a/templates/standalone/cordova/lib/target-list.js b/templates/standalone/cordova/lib/target-list.js
deleted file mode 100644
index 805eea5..0000000
--- a/templates/standalone/cordova/lib/target-list.js
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject');
-var wscript_shell = WScript.CreateObject("WScript.Shell");
-
-var args = WScript.Arguments;
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\cordova\\lib\\target-list.js').join('');
-    // path to CordovaDeploy.exe
-var CORDOVA_DEPLOY_EXE = '\\cordova\\lib\\CordovaDeploy\\CordovaDeploy\\bin\\Debug\\CordovaDeploy.exe';
-    // path to CordovaDeploy
-var CORDOVA_DEPLOY = '\\cordova\\lib\\CordovaDeploy';
-
-// help/usage function
-function Usage() {
-    Log("");
-    Log("Usage: cscript target-list.js  [ --emulators | --devices | --started_emulators | --all ]");
-    Log("    --emulators         : List the possible target emulators availible.");
-    Log("    --devices           : List the possible target devices availible. *NOT IMPLEMENTED YET*");
-    Log("    --started_emulators : List any started emulators availible. *NOT IMPLEMENTED YET*");
-    Log("    --all               : List all devices returned by CordovaDeploy.exe -devices ");
-    Log("examples:");
-    Log("    cscript target-list.js --emulators");
-    Log("    cscript target-list.js --devices");
-    Log("    cscript target-list.js --started_emulators");
-    Log("    cscript target-list.js --all");
-    Log("");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// executes a commmand in the shell
-function exec(command) {
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status == 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print output? Naa.....
-        if (!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadAll();
-            //Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if (!oShell.StdErr.AtEndOfStream) {
-        var line = oShell.StdErr.ReadAll();
-        Log(line, true);
-        WScript.Quit(2);
-    }
-}
-
-// returns all possible targets generated by the CordovaDeploy tool
-function get_targets(path) {
-    if (!fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-        cordovaDeploy(path);
-    }
-    wscript_shell.CurrentDirectory = path + CORDOVA_DEPLOY + '\\CordovaDeploy\\bin\\Debug';
-    var cmd = 'CordovaDeploy -devices';
-    var out = wscript_shell.Exec(cmd);
-    while(out.Status == 0) {
-        WScript.Sleep(100);
-    }
-    //Check to make sure our script did not encounter an error
-    if (!out.StdErr.AtEndOfStream) {
-        var line = out.StdErr.ReadAll();
-        Log("Error calling CordovaDeploy : ", true);
-        Log(line, true);
-        WScript.Quit(2);
-    }
-    else {
-        if (!out.StdOut.AtEndOfStream) {
-            var line = out.StdOut.ReadAll();
-            var targets = line.split('\r\n');
-            //format (ID DESCRIPTION)
-            for (i in targets) {
-                // remove device index and separator colen
-                targets[i] = targets[i].replace(/\d*\s\:\s/, '').replace(/\:\s/, '');
-            }
-            return targets;
-        }
-        else {
-            Log('Error : CordovaDeploy Failed to find any devices', true);
-            WScript.Quit(2);
-        }
-    }
-}
-
-function list_targets(path) {
-    var targets = get_targets(path);
-    for (i in targets) {
-        Log(targets[i]);
-    }
-}
-
-// lists the Device returned by CordovaDeploy (NOTE: this does not indicate that a device is connected)
-function list_devices(path) {
-    var targets = get_targets(path);
-    var device_found = false;
-    for (i in targets) {
-        if (targets[i].match(/Device/)) {
-            Log(targets[i]);
-            device_found = true;
-        }
-    }
-    if (device_found) {
-        Log('');
-        Log('WARNING : This does not mean that a device is connected, make');
-        Log(' sure your device is connected before deploying to it.');
-    }
-}
-
-// lists the emulators availible to CordovaDeploy
-function list_emulator_images(path) {
-    var targets = get_targets(path);
-    for (i in targets) {
-        if (targets[i].match(/Emulator/)) {
-            Log(targets[i]);
-        }
-    }
-}
-
-// lists any started emulators *NOT IMPLEMENTED*
-function list_started_emulators(path) {
-    Log('ERROR : list-started-emulators is not supported on Windows Phone.', true);
-    WScript.Quit(1);
-}
-
-// builds the CordovaDeploy.exe if it does not already exist 
-function cordovaDeploy(path) {
-    if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-        return;
-    }
-
-    // build CordovaDeploy.exe
-    if (fso.FolderExists(path + '\\cordova') && fso.FolderExists(path + CORDOVA_DEPLOY) && 
-        fso.FileExists(path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln')) {
-        // delete any previously generated files
-        if (fso.FolderExists(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\obj")) {
-            fso.DeleteFolder(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\obj");
-        }
-        if (fso.FolderExists(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\Bin")) {
-            fso.DeleteFolder(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\Bin");
-        }
-        exec('msbuild ' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln');
-
-        if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
-            return;
-        }
-        else {
-            Log("ERROR: MSBUILD FAILED TO COMPILE CordovaDeploy.exe", true);
-            WScript.Quit(2);
-        }
-    }
-    else {
-        Log("ERROR: CordovaDeploy.sln not found, unable to compile CordovaDeploy tool.", true);
-        WScript.Quit(2);
-    }
-}
-
-
-if (args.Count() > 0) {
-    // support help flags
-    if (args(0) == "--help" || args(0) == "/?" ||
-            args(0) == "help" || args(0) == "-help" || args(0) == "/help") {
-        Usage();
-        WScript.Quit(2);
-    }
-    else if (args.Count() > 1) {
-        Log("Error: Too many arguments.", true);
-        Usage();
-        WScript.Quit(2);
-    }
-    else if (fso.FolderExists(ROOT)) {
-        if (!fso.FolderExists(ROOT + '\\cordova')) {
-            Log("Error: cordova tooling folder not found in project directory,", true);
-            Log("could not lsit targets.", true);
-            WScript.Quit(2);
-        }
-
-        if (args(0) == "--emulators" || args(0) == "-e") {
-            list_emulator_images(ROOT);
-        }
-        else if (args(0) == "--devices" || args(0) == "-d") {
-            list_devices(ROOT);
-        }
-        else if (args(0) == "--started_emulators" || args(0) == "-s") {
-            list_started_emulators(ROOT);
-        }
-        else if (args(0) == "--all" || args(0) == "-a") {
-            list_targets(ROOT);
-        }
-        else {
-            Log("Error: \"" + args(0) + "\" is not recognized as a target-list option", true);
-            Usage();
-            WScript.Quit(2);
-        }
-    }
-    else {
-        Log("Error: Project directory not found,", true);
-        Usage();
-        WScript.Quit(2);
-    }
-}
-else {
-    Log("WARNING: target list not specified, showing all targets...");
-    list_targets(ROOT);
-}
diff --git a/templates/standalone/cordova/log.bat b/templates/standalone/cordova/log.bat
deleted file mode 100644
index d34a8ab..0000000
--- a/templates/standalone/cordova/log.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@ECHO OFF
-ECHO Sorry, logging is not supported for Windows Phone. 1>&2
-EXIT /B 1
\ No newline at end of file
diff --git a/templates/standalone/cordova/run.bat b/templates/standalone/cordova/run.bat
deleted file mode 100644
index b966856..0000000
--- a/templates/standalone/cordova/run.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\deploy.js (
-        cscript "%full_path%lib\deploy.js" %* //nologo
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
-    EXIT /B 1
-)
diff --git a/templates/standalone/cordova/version.bat b/templates/standalone/cordova/version.bat
deleted file mode 100644
index 714e876..0000000
--- a/templates/standalone/cordova/version.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@ECHO OFF
-SET full_path=%~dp0
-IF EXIST "%full_path%..\VERSION" (
-    type "%full_path%..\VERSION"
-) ELSE (
-    ECHO.
-    ECHO ERROR: Could not find file VERSION in project folder
-    EXIT /B 1
-)
\ No newline at end of file
diff --git a/templates/standalone/cordovalib/BaseCommand.cs b/templates/standalone/cordovalib/BaseCommand.cs
deleted file mode 100644
index ac1d2d6..0000000
--- a/templates/standalone/cordovalib/BaseCommand.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Reflection;
-using Microsoft.Phone.Shell;
-using System.Diagnostics;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public abstract class BaseCommand : IDisposable
-    {
-        /*
-         *  All commands + plugins must extend BaseCommand, because they are dealt with as BaseCommands in CordovaView.xaml.cs
-         *  
-         **/
-
-        public event EventHandler<PluginResult> OnCommandResult;
-
-        public event EventHandler<ScriptCallback> OnCustomScript;
-
-        public string CurrentCommandCallbackId { get; set; }
-
-        public BaseCommand()
-        {
-            ResultHandlers = new Dictionary<string, EventHandler<PluginResult>>();
-            PhoneApplicationService service = PhoneApplicationService.Current;
-            service.Activated += this.OnResume;
-            service.Deactivated += this.OnPause;
-        }
-
-        protected Dictionary<string, EventHandler<PluginResult>> ResultHandlers;
-        public void AddResultHandler(string callbackId, EventHandler<PluginResult> handler)
-        {
-            ResultHandlers.Add(callbackId, handler);
-        }
-        public bool RemoveResultHandler(string callbackId)
-        {
-            return ResultHandlers.Remove(callbackId);
-        }
-
-        /*
-         *  InvokeMethodNamed will call the named method of a BaseCommand subclass if it exists and pass the variable arguments list along.
-         **/
-
-        public object InvokeMethodNamed(string callbackId, string methodName, params object[] args)
-        {
-            //Debug.WriteLine(string.Format("InvokeMethodNamed:{0} callbackId:{1}",methodName,callbackId));
-            this.CurrentCommandCallbackId = callbackId;
-            return InvokeMethodNamed(methodName, args);
-        }
-
-        public object InvokeMethodNamed(string methodName, params object[] args)
-        {
-            MethodInfo mInfo = this.GetType().GetMethod(methodName);
-
-            if (mInfo != null)
-            {
-                // every function handles DispatchCommandResult by itself
-                return mInfo.Invoke(this, args);
-            }
-
-            // actually methodName could refer to a property
-            if (args == null || args.Length == 0 ||
-               (args.Length == 1 && "undefined".Equals(args[0])))
-            {
-                PropertyInfo pInfo = this.GetType().GetProperty(methodName);
-                if (pInfo != null)
-                {
-                    object res = pInfo.GetValue(this, null);
-
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
-
-                    return res;
-                }
-            }
-
-            throw new MissingMethodException(methodName);
-
-        }
-
-        [Obsolete]
-        public void InvokeCustomScript(ScriptCallback script, bool removeHandler)
-        {
-            if (this.OnCustomScript != null)
-            {
-                this.OnCustomScript(this, script);
-                if (removeHandler)
-                {
-                    this.OnCustomScript = null;
-                }
-            }
-        }
-
-        public void DispatchCommandResult()
-        {
-            this.DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
-        }
-
-        public void DispatchCommandResult(PluginResult result, string callbackId = "")
-        {
-            if (!string.IsNullOrEmpty(callbackId)) 
-            {
-                result.CallbackId = callbackId;
-            }
-            else
-            {
-                result.CallbackId = this.CurrentCommandCallbackId;
-            }
-
-            if (ResultHandlers.ContainsKey(result.CallbackId))
-            {
-                ResultHandlers[result.CallbackId](this, result);
-            }
-            else if (this.OnCommandResult != null)
-            {
-                OnCommandResult(this, result);
-            }
-            else
-            {
-                Debug.WriteLine("Failed to locate callback for id : " + result.CallbackId);
-            }
-
-            if (!result.KeepCallback)
-            {
-                this.Dispose();
-            }
-
-        }
-
-
-        /// <summary>
-        /// Occurs when the application is being deactivated.
-        /// </summary>        
-        public virtual void OnReset() {}
-
-        /// <summary>
-        /// Occurs when the application is being loaded, and the config.xml has an autoload entry
-        /// </summary>    
-        public virtual void OnInit() {}
-
-
-        /// <summary>
-        /// Occurs when the application is being deactivated.
-        /// </summary>        
-        public virtual void OnPause(object sender, DeactivatedEventArgs e) {}
-
-        /// <summary>
-        /// Occurs when the application is being made active after previously being put
-        /// into a dormant state or tombstoned.
-        /// </summary>        
-        public virtual void OnResume(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e) {}
-
-        public void Dispose()
-        {
-            PhoneApplicationService service = PhoneApplicationService.Current;
-            service.Activated -= this.OnResume;
-            service.Deactivated -= this.OnPause;
-            this.OnCommandResult = null;
-        }
-
-        public static string GetBaseURL()
-        {
-#if CORDOVA_CLASSLIB
-            return "/WPCordovaClassLib;component/";
-#else
-            return "./";
-#endif
-        }
-    }
-
-
-
-}
diff --git a/templates/standalone/cordovalib/BrowserMouseHelper.cs b/templates/standalone/cordovalib/BrowserMouseHelper.cs
deleted file mode 100644
index acd1bcd..0000000
--- a/templates/standalone/cordovalib/BrowserMouseHelper.cs
+++ /dev/null
@@ -1,345 +0,0 @@
-﻿/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
- */
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using Microsoft.Phone.Controls;
-using System.Windows.Input;
-using System.Diagnostics;
-using System.Windows.Media;
-using System;
-using System.Collections.Generic;
-
-namespace WPCordovaClassLib
-{
-
-    /// <summary>
-    /// Suppresses pinch zoom and optionally scrolling of the WebBrowser control
-    /// </summary>
-    public class BrowserMouseHelper
-    {
-
-        /**
-         * 
-         * Full Script below, in use it is minified.
-        */
-        /*
-        private static string mouseScript =
-        @"(function(win,doc){
-            var mPro = MouseEvent.prototype;
-            var def = Object.defineProperty;
-            def( mPro, 'pageX', {
-               configurable: true,
-               get: function(){ return this.clientX }
-            });
-            def( mPro, 'pageY', {
-               configurable: true,
-               get: function(){ return this.clientY }
-            });
-
-            win.onNativeMouseEvent = function(type,x,y){
-                try {
-                    var xMod = screen.logicalXDPI / screen.deviceXDPI;
-                    var yMod = screen.logicalYDPI / screen.deviceYDPI;
-                    var evt = doc.createEvent('MouseEvents');
-                    var xPos =  doc.body.scrollLeft + Math.round(xMod * x);
-                    var yPos =  doc.body.scrollTop + Math.round(yMod * y);
-                    var element = doc.elementFromPoint(xPos,yPos);
-                    
-                    evt.initMouseEvent(type, true, true, win, 1, xPos, yPos, xPos, yPos, false, false, false, false, 0, element);
-                    evt.timeStamp = +new Date;
-                    evt.isCordovaEvent = true;
-                    
-                    var canceled = element ? !element.dispatchEvent(evt) : !doc.dispatchEvent(evt);
-                    return canceled ? 'true' : 'false';
-                }
-                catch(e) { return e;}
-            }
-        })(window,document);";
-        */
-
-        private static string MinifiedMouseScript = "(function(g,a){var c=MouseEvent.prototype,d=Object.defineProperty;d(c,'pageX',{configurable:!0,get:function(){return this.clientX}});d(c,'pageY',{configurable:!0,get:function(){return this.clientY}});g.onNativeMouseEvent=function(c,d,i)"
-        + "{try{var j=screen.logicalXDPI/screen.deviceXDPI,k=screen.logicalYDPI/screen.deviceYDPI,b=a.createEvent('MouseEvents'),e=a.body.scrollLeft+Math.round(j*d),f=a.body.scrollTop+Math.round(k*i),h=a.elementFromPoint(e,f);b.initMouseEvent(c,!0,!0,g,1,e,f,e,f,!1,!1,!1,!1,0,"
-        + "h);b.timeStamp=+new Date;b.isCordovaEvent=!0;return(h?!h.dispatchEvent(b):!a.dispatchEvent(b))?'true':'false'}catch(l){return l}}})(window,document);";
-
-
-        private WebBrowser _browser;
-
-        /// <summary>
-        /// Gets or sets whether to suppress the scrolling of
-        /// the WebBrowser control;
-        /// </summary>
-        public bool ScrollDisabled { get; set; }
-
-        private bool userScalable = true;
-        private double maxScale = 2.0;
-        private double minScale = 0.5;
-        protected Border border;
-        private bool firstMouseMove = false;
-
-        /// <summary>
-        /// Represents last known mouse down position. 
-        /// Used to determine mouse move delta to avoid duplicate mouse events.
-        /// </summary>
-        private Point mouseDownPos;
-
-        /// <summary>
-        /// Represent min delta value to consider event as a mouse move. Experimental calculated.
-        /// </summary>
-        private const int MouseMoveDeltaThreshold = 10;
-
-
-        public BrowserMouseHelper(ref WebBrowser browser)
-        {
-            _browser = browser;
-            browser.Loaded += new RoutedEventHandler(browser_Loaded);
-        }
-
-        private void browser_Loaded(object sender, RoutedEventArgs e)
-        {
-            var border0 = VisualTreeHelper.GetChild(_browser, 0);
-            var border1 = VisualTreeHelper.GetChild(border0, 0);
-            var panZoom = VisualTreeHelper.GetChild(border1, 0);
-            var grid = VisualTreeHelper.GetChild(panZoom, 0);
-            border = VisualTreeHelper.GetChild(grid, 0) as Border;
-
-            if (border != null)
-            {
-                border.ManipulationStarted += Border_ManipulationStarted;
-                border.ManipulationDelta += Border_ManipulationDelta;
-                border.ManipulationCompleted += Border_ManipulationCompleted;
-                border.DoubleTap += Border_DoubleTap;
-                border.Tap += Border_Tap;
-                border.Hold += Border_Hold;
-                border.MouseLeftButtonDown += Border_MouseLeftButtonDown;
-            }
-
-            _browser.LoadCompleted += Browser_LoadCompleted;
-
-        }
-
-
-
-
-        void ParseViewportMeta()
-        {
-            string metaScript = "(function() { return document.querySelector('meta[name=viewport]').content; })()";
-
-            try
-            {
-                string metaContent = _browser.InvokeScript("eval", new string[] { metaScript }) as string;
-                string[] arr = metaContent.Split(new[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
-                Dictionary<string, string> metaDictionary = new Dictionary<string, string>();
-                foreach (string val in arr)
-                {
-                    string[] keyVal = val.Split('=');
-                    metaDictionary.Add(keyVal[0], keyVal[1]);
-                }
-
-                this.userScalable = false; // reset to default
-                if (metaDictionary.ContainsKey("user-scalable"))
-                {
-                    this.userScalable = metaDictionary["user-scalable"] == "yes";
-                }
-
-                this.maxScale = 2.0;// reset to default
-                if (metaDictionary.ContainsKey("maximum-scale"))
-                {
-                    this.maxScale = double.Parse(metaDictionary["maximum-scale"]);
-                }
-
-                this.minScale = 0.5;// reset to default
-                if (metaDictionary.ContainsKey("minimum-scale"))
-                {
-                    this.minScale = double.Parse(metaDictionary["minimum-scale"]);
-                }
-            }
-            catch (Exception)
-            {
-
-            }
-        }
-
-        void Browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            ParseViewportMeta();
-
-            try
-            {
-                _browser.InvokeScript("execScript", MinifiedMouseScript);
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("BrowserHelper Failed to install mouse script in WebBrowser");
-            }
-        }
-
-        bool InvokeSimulatedMouseEvent(string eventName, Point pos)
-        {
-            bool bCancelled = false;
-            try
-            {
-                string strCancelled = _browser.InvokeScript("onNativeMouseEvent", new string[] { eventName, pos.X.ToString(), pos.Y.ToString() }) as string;
-                if (bool.TryParse(strCancelled, out bCancelled))
-                {
-                    return bCancelled;
-                }
-            }
-            catch (Exception)
-            {
-                // script error
-            }
-
-            return bCancelled;
-        }
-
-        #region Hold
-
-        void Border_Hold(object sender, GestureEventArgs e)
-        {
-            //Debug.WriteLine("Border_Hold");
-            e.Handled = true;
-        }
-
-        #endregion
-
-        #region DoubleTap
-
-        void Border_DoubleTap(object sender, GestureEventArgs e)
-        {
-            //Debug.WriteLine("Border_DoubleTap");
-            e.Handled = true;
-        }
-
-        #endregion
-
-        #region Tap
-
-        void Border_Tap(object sender, GestureEventArgs e)
-        {
-            // prevents generating duplicated mouse events
-            // firstMouseMove == FALSE means we already handled this situation and generated mouse events
-            e.Handled = !this.firstMouseMove;
-        }
-        #endregion
-
-        #region MouseEvents
-
-        void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
-        {
-            //Debug.WriteLine("Border_MouseLeftButtonDown");
-            border.MouseMove += new MouseEventHandler(Border_MouseMove);
-            border.MouseLeftButtonUp += new MouseButtonEventHandler(Border_MouseLeftButtonUp);
-
-            this.mouseDownPos = e.GetPosition(_browser);
-            // don't fire the down event until we know if this is a 'move' or not
-            firstMouseMove = true;
-        }
-        //
-        void Border_MouseMove(object sender, MouseEventArgs e)
-        {
-            //Debug.WriteLine("Border_MouseMove");
-            Point pos = e.GetPosition(_browser);
-            // only the return value from the first mouse move event should be used to determine if scrolling is prevented.
-            if (firstMouseMove)
-            {
-                // even for simple tap there are situations where ui control generates move with some little delta value
-                // we should avoid such situations allowing to browser control generate native js mousedown/up/click events
-                if (Math.Abs(pos.X - mouseDownPos.X) + Math.Abs(pos.Y - mouseDownPos.Y) <= MouseMoveDeltaThreshold)
-                {
-                    return;
-                }
-
-                InvokeSimulatedMouseEvent("mousedown", pos);
-                firstMouseMove = false;
-                ScrollDisabled = InvokeSimulatedMouseEvent("mousemove", pos);
-            }
-            else
-            {
-                InvokeSimulatedMouseEvent("mousemove", pos);
-            }
-
-        }
-
-        void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
-        {
-            //Debug.WriteLine("Border_MouseLeftButtonUp");
-            border.MouseMove -= new MouseEventHandler(Border_MouseMove);
-            border.MouseLeftButtonUp -= new MouseButtonEventHandler(Border_MouseLeftButtonUp);
-            // if firstMouseMove is false, then we have sent our simulated mousedown, so we should also send a matching mouseup 
-            if (!firstMouseMove)
-            {
-                Point pos = e.GetPosition(_browser);
-                e.Handled = InvokeSimulatedMouseEvent("mouseup", pos);
-            }
-            ScrollDisabled = false;
-        }
-
-
-        #endregion
-
-        #region ManipulationEvents
-
-        void Border_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
-        {
-            //Debug.WriteLine("Border_ManipulationStarted");
-
-            if (ScrollDisabled)
-            {
-                e.Handled = true;
-                e.Complete();
-            }
-        }
-
-        private void Border_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
-        {
-            //Debug.WriteLine("Border_ManipulationDelta");
-            // optionally suppress zoom
-            if ((ScrollDisabled || !userScalable) && (e.DeltaManipulation.Scale.X != 0.0 || e.DeltaManipulation.Scale.Y != 0.0))
-            {
-                e.Handled = true;
-                e.Complete();
-            }
-            // optionally suppress scrolling
-            if (ScrollDisabled && (e.DeltaManipulation.Translation.X != 0.0 || e.DeltaManipulation.Translation.Y != 0.0))
-            {
-                e.Handled = true;
-                e.Complete();
-            }
-        }
-
-        private void Border_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
-        {
-            //Debug.WriteLine("Border_ManipulationCompleted");
-            // suppress zoom
-            if (!userScalable && e.FinalVelocities != null)
-            {
-                if (e.FinalVelocities.ExpansionVelocity.X != 0.0 ||
-                   e.FinalVelocities.ExpansionVelocity.Y != 0.0)
-                {
-                    e.Handled = true;
-                }
-            }
-        }
-
-
-        #endregion
-
-    }
-}
diff --git a/templates/standalone/cordovalib/CommandFactory.cs b/templates/standalone/cordovalib/CommandFactory.cs
deleted file mode 100644
index 893ce80..0000000
--- a/templates/standalone/cordovalib/CommandFactory.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Collections.Generic;
-using WPCordovaClassLib.Cordova.Commands;
-using System.Reflection;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Provides functionality to create phone gap command by name.
-    /// </summary>
-    public static class CommandFactory
-    {
-        /// <summary>
-        /// Represents predefined namespace name for custom plugins
-        /// </summary>
-        private static readonly string CustomPluginNamespacePrefix = "Cordova.Extension.Commands.";
-
-        private static readonly string BaseCommandNamespacePrefix = "WPCordovaClassLib.Cordova.Commands.";
-
-        /// <summary>
-        /// Cache instantiated commands in a map.
-        /// </summary>
-
-        private static Dictionary<string, BaseCommand> commandMap = new Dictionary<string, BaseCommand>();
-
-        /// <summary>
-        /// Creates command using command class name. Returns null for unknown commands.
-        /// </summary>
-        /// <param name="service">Command class name, for example Device or Notification</param>
-        /// <returns>Command class instance or null</returns>
-        public static BaseCommand CreateByServiceName(string service)
-        {
-
-            if (string.IsNullOrEmpty(service))
-            {
-                throw new ArgumentNullException("service", "service to create can't be null");
-            }
-
-            if (!commandMap.ContainsKey(service))
-            {
-
-                Type t = Type.GetType(BaseCommandNamespacePrefix + service);
-
-                // custom plugin could be defined in own namespace and assembly
-                if (t == null)
-                {
-                    string serviceFullName = service.Contains(".") ? service : CustomPluginNamespacePrefix + service;
-
-                    foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
-                    {
-                        // in this case service name represents full type name including namespace
-                        t = a.GetType(serviceFullName);
-
-                        if (t == null) // try the Commands Namespace
-                        {
-                            t = a.GetType(BaseCommandNamespacePrefix + service);
-                        }
-
-                        if (t != null)
-                        {
-                            break;
-                        }
-                    }
-
-                }
-
-                // unknown command, still didn't find it
-                if (t == null)
-                {
-                    Debug.WriteLine("Unable to locate command :: " + service);
-                    return null;
-                }
-
-                commandMap[service] = Activator.CreateInstance(t) as BaseCommand;
-            }
-
-            return commandMap[service];
-        }
-
-        public static void ResetAllCommands()
-        {
-            foreach (BaseCommand bc in commandMap.Values)
-            {
-                bc.OnReset();
-            }
-        }
-    }
-}
diff --git a/templates/standalone/cordovalib/ConfigHandler.cs b/templates/standalone/cordovalib/ConfigHandler.cs
deleted file mode 100644
index 31934c1..0000000
--- a/templates/standalone/cordovalib/ConfigHandler.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Windows;
-using System.Windows.Resources;
-using System.Xml.Linq;
-
-namespace WPCordovaClassLib.CordovaLib
-{
-    class ConfigHandler
-    {
-        public class PluginConfig
-        {
-            public PluginConfig(string name, bool autoLoad = false)
-            {
-                Name = name;
-                isAutoLoad = autoLoad;
-            }
-            public string Name;
-            public bool isAutoLoad;
-        }
-
-        protected Dictionary<string, PluginConfig> AllowedPlugins;
-        protected List<string> AllowedDomains;
-        protected Dictionary<string, string> Preferences;
-
-        public string ContentSrc { get; private set; }
-
-        protected bool AllowAllDomains = false;
-        protected bool AllowAllPlugins = false;
-
-        public ConfigHandler()
-        {
-            AllowedPlugins = new Dictionary<string, PluginConfig>();
-            AllowedDomains = new List<string>();
-            Preferences = new Dictionary<string, string>();
-        }
-
-        public string GetPreference(string key)
-        {
-            return Preferences[key];
-        }
-
-        protected static string[] AllowedSchemes = {"http","https","ftp","ftps"};
-        protected bool SchemeIsAllowed(string scheme)
-        {
-            return AllowedSchemes.Contains(scheme);
-        }
-
-        protected string PathAndQuery(Uri uri)
-        {
-            string result = uri.LocalPath;
-            if (uri.Query.Length > 0)
-            {
-                result +=  uri.Query;
-            }
-            return result;
-        }
-
-        protected void AddWhiteListEntry(string origin, bool allowSubdomains)
-        {
-
-            if (origin == "*")
-            {
-                AllowAllDomains = true;
-            }
-
-            if (AllowAllDomains)
-            {
-                return;
-            }
-
-            string hostMatchingRegex = "";
-            string hostName;
-
-            try
-            {
-
-                Uri uri = new Uri(origin.Replace("*", "replaced-text"), UriKind.Absolute);
-
-                string tempHostName = uri.Host.Replace("replaced-text", "*");
-                //if (uri.HostNameType == UriHostNameType.Dns){}        
-                // starts with wildcard match - we make the first '.' optional (so '*.org.apache.cordova' will match 'org.apache.cordova')
-                if (tempHostName.StartsWith("*."))
-                {    //"(\\s{0}|*.)"
-                    hostName = @"\w*.*" + tempHostName.Substring(2).Replace(".", @"\.").Replace("*", @"\w*");
-                }
-                else
-                {
-                    hostName = tempHostName.Replace(".", @"\.").Replace("*", @"\w*");
-                }
-
-                //  "^https?://"
-                hostMatchingRegex = uri.Scheme + "://" + hostName + PathAndQuery(uri);
-                //Debug.WriteLine("Adding regex :: " + hostMatchingRegex);
-                AllowedDomains.Add(hostMatchingRegex);
-
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("Invalid Whitelist entry (probably missing the protocol):: " + origin);
-            }
-
-        }
-
-        /**   
-         
-         An access request is granted for a given URI if there exists an item inside the access-request list such that:
-
-            - The URI's scheme component is the same as scheme; and
-            - if subdomains is false or if the URI's host component is not a domain name (as defined in [RFC1034]), the URI's host component is the same as host; or
-            - if subdomains is true, the URI's host component is either the same as host, or is a subdomain of host (as defined in [RFC1034]); and
-            - the URI's port component is the same as port.
-         
-         **/
-
-        public bool URLIsAllowed(string url)
-        {
-            // easy case first
-            if (AllowAllDomains )
-            {
-                return true;
-            }
-            else
-            {
-                // start simple
-                Uri uri = new Uri(url,UriKind.RelativeOrAbsolute);
-                if (uri.IsAbsoluteUri)
-                {
-                    if (this.SchemeIsAllowed(uri.Scheme))
-                    {
-                        // additional test because our pattern will always have a trailing '/'
-                        string matchUrl = url;
-                        if (PathAndQuery(uri) == "/")
-                        {
-                            matchUrl = url + "/";
-                        }
-                        foreach (string pattern in AllowedDomains)
-                        {
-                            if (Regex.IsMatch(matchUrl, pattern))
-                            {
-                                // make sure it is at the start, and not part of the query string
-                                // special case :: http://some.other.domain/page.html?x=1&g=http://build.apache.org/
-                                if ( Regex.IsMatch(uri.Scheme + "://" +  uri.Host + "/", pattern) ||
-                                     (!Regex.IsMatch(PathAndQuery(uri), pattern)))
-                                {
-                                    return true;
-                                }
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        public bool IsPluginAllowed(string key)
-        {
-            return AllowAllPlugins || AllowedPlugins.Keys.Contains(key);
-        }
-
-        private void LoadPluginFeatures(XDocument document)
-        {
-            var plugins = from results in document.Descendants("plugin")
-                          select new
-                          {
-                              name = (string)results.Attribute("name"),
-                              autoLoad = results.Attribute("onload")
-                          };
-
-            foreach (var plugin in plugins)
-            {
-                Debug.WriteLine("Warning: Deprecated use of <plugin> by plugin : " + plugin.name);
-                PluginConfig pConfig = new PluginConfig(plugin.name, plugin.autoLoad != null && plugin.autoLoad.Value == "true");
-                if (pConfig.Name == "*")
-                {
-                    AllowAllPlugins = true;
-                    // break; wait, don't, some still could be autoload
-                }
-                else
-                {
-                    AllowedPlugins[pConfig.Name] = pConfig;
-                }
-            }
-
-            var features = document.Descendants("feature");
-
-
-            foreach (var feature in features)
-            {
-                var name = feature.Attribute("name");
-                var values = from results in feature.Descendants("param")
-                             where ((string)results.Attribute("name") == "wp-package")
-                             select results;
-
-                var value = values.FirstOrDefault();
-                if (value != null)
-                {
-                    string key = (string)value.Attribute("value");
-                    Debug.WriteLine("Adding feature.value=" + key);
-                    var onload = value.Attribute("onload");
-                    PluginConfig pConfig = new PluginConfig(key, onload != null && onload.Value == "true");
-                    AllowedPlugins[key] = pConfig;
-                }
-            }
-        }
-
-        public void LoadAppPackageConfig()
-        {
-            StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("config.xml", UriKind.Relative));
-
-            if (streamInfo != null)
-            {
-                StreamReader sr = new StreamReader(streamInfo.Stream);
-                //This will Read Keys Collection for the xml file
-                XDocument document = XDocument.Parse(sr.ReadToEnd());
-
-                LoadPluginFeatures(document);
-
-                var preferences = from results in document.Descendants("preference")
-                                  select new
-                                  {
-                                      name = (string)results.Attribute("name"),
-                                      value = (string)results.Attribute("value")
-                                  };
-
-                foreach (var pref in preferences)
-                {
-                    Preferences[pref.name] = pref.value;
-                    Debug.WriteLine("pref" + pref.name + ", " + pref.value);
-                }
-
-                var accessList = from results in document.Descendants("access")
-                                 select new
-                                 {
-                                     origin = (string)results.Attribute("origin"),
-                                     subdomains = (string)results.Attribute("subdomains") == "true"
-                                 };
-
-                foreach (var accessElem in accessList)
-                {
-                    AddWhiteListEntry(accessElem.origin, accessElem.subdomains);
-                }
-
-                var contentsTag = document.Descendants("content").FirstOrDefault();
-                if (contentsTag != null)
-                {
-                    var src = contentsTag.Attribute("src");
-                    ContentSrc = (string)src.Value;
-                }
-            }
-            else
-            {
-                // no config.xml, allow all
-                AllowAllDomains = true;
-                AllowAllPlugins = true;
-            }
-        }
-    }
-}
diff --git a/templates/standalone/cordovalib/CordovaCommandCall.cs b/templates/standalone/cordovalib/CordovaCommandCall.cs
deleted file mode 100644
index 810f5e2..0000000
--- a/templates/standalone/cordovalib/CordovaCommandCall.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Linq;
-using System.Collections.Generic;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Represents Cordova native command call: action callback, etc
-    /// </summary>
-    public class CordovaCommandCall
-    {
-        public String Service { get; private set; }
-        public String Action { get; private set; }
-        public String CallbackId { get; private set; }
-        public String Args { get; private set; }
-
-        /// <summary>
-        /// Retrieves command call parameters and creates wrapper for them
-        /// </summary>
-        /// <param name="commandStr">Command string in the form 'service/action/callback/args'</param>
-        /// <returns>New class instance or null of string does not represent Cordova command</returns>
-        public static CordovaCommandCall Parse(string commandStr)
-        {
-            if (string.IsNullOrEmpty(commandStr))
-            {
-                return null;
-            }
-
-            string[] split = commandStr.Split('/');
-            if (split.Length < 3)
-            {
-                return null;
-            }
-
-            CordovaCommandCall commandCallParameters = new CordovaCommandCall();
-            commandCallParameters.Service = split[0];
-            commandCallParameters.Action = split[1];
-            commandCallParameters.CallbackId = split[2];
-
-            try
-            {
-                string arg = split.Length <= 3 ? "[]" : String.Join("/", split.Skip(3));
-                if (!arg.StartsWith("[")) // save the exception
-                {
-                    arg = string.Format("[{0}]", arg);
-                }
-                List<string> args = JSON.JsonHelper.Deserialize<List<string>>(arg);
-                args.Add(commandCallParameters.CallbackId);
-                commandCallParameters.Args = JSON.JsonHelper.Serialize(args.ToArray());
-            }
-            catch (Exception)
-            {
-                return null; 
-            }
-            // sanity check for illegal names
-            // was failing with ::
-            // CordovaCommandResult :: 1, Device1, {"status":1,"message":"{\"name\":\"XD.....
-            if (commandCallParameters.Service.IndexOfAny(new char[] { '@', ':', ',', '!', ' ' }) > -1)
-            {
-                return null;
-            }
-
-            return commandCallParameters;
-        }
-
-
-        /// <summary>
-        /// Private ctr to disable class creation.
-        /// New class instance must be initialized via CordovaCommandCall.Parse static method.
-        /// </summary>
-        private CordovaCommandCall() { }
-
-
-    }
-}
diff --git a/templates/standalone/cordovalib/CordovaView.xaml b/templates/standalone/cordovalib/CordovaView.xaml
deleted file mode 100644
index b993d97..0000000
--- a/templates/standalone/cordovalib/CordovaView.xaml
+++ /dev/null
@@ -1,65 +0,0 @@
-﻿<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.  
--->
-<UserControl x:Class="WPCordovaClassLib.CordovaView"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    mc:Ignorable="d"
-    FontFamily="{StaticResource PhoneFontFamilyNormal}"
-    FontSize="{StaticResource PhoneFontSizeNormal}"
-    Foreground="{StaticResource PhoneForegroundBrush}"
-    d:DesignHeight="480" d:DesignWidth="480" 
-    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone">
-    
-    <Grid x:Name="LayoutRoot" Background="Transparent">
-        
-        <phone:WebBrowser x:Name="CordovaBrowser" 
-                          Opacity="0"
-                          HorizontalAlignment="Stretch"  
-                          VerticalAlignment="Stretch" 
-                          IsScriptEnabled="True" 
-                          Foreground="White"
-                          Background="Black"
-                          Navigated="GapBrowser_Navigated" 
-                          Loaded="GapBrowser_Loaded" 
-                          Unloaded="GapBrowser_Unloaded" 
-                          ScriptNotify="GapBrowser_ScriptNotify" 
-                          LoadCompleted="GapBrowser_LoadCompleted" 
-                          Navigating="GapBrowser_Navigating" 
-                          NavigationFailed="GapBrowser_NavigationFailed" 
-                          IsGeolocationEnabled="True">
-            <phone:WebBrowser.Projection>
-                <PlaneProjection x:Name="BrowserProjector" CenterOfRotationX="0" RotationY="-180"/>
-            </phone:WebBrowser.Projection>
-            <phone:WebBrowser.Resources>
-                <Storyboard x:Name="RotateIn" BeginTime="0:0:0.5">
-                    <DoubleAnimation
-                        Storyboard.TargetName="BrowserProjector"
-                        Storyboard.TargetProperty="RotationY"
-                        To="0" Duration="0:0:0.6"/>
-                </Storyboard>
-            </phone:WebBrowser.Resources>
-
-        </phone:WebBrowser>
-        
-    </Grid>
-</UserControl>
-
-    
diff --git a/templates/standalone/cordovalib/CordovaView.xaml.cs b/templates/standalone/cordovalib/CordovaView.xaml.cs
deleted file mode 100644
index d57249a..0000000
--- a/templates/standalone/cordovalib/CordovaView.xaml.cs
+++ /dev/null
@@ -1,497 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-using System.IO.IsolatedStorage;
-using System.Windows.Resources;
-using System.Windows.Interop;
-using System.Runtime.Serialization.Json;
-using System.IO;
-using System.ComponentModel;
-using System.Xml.Linq;
-using WPCordovaClassLib.Cordova.Commands;
-using System.Diagnostics;
-using System.Text;
-using WPCordovaClassLib.Cordova;
-using System.Threading;
-using Microsoft.Phone.Shell;
-using WPCordovaClassLib.Cordova.JSON;
-using WPCordovaClassLib.CordovaLib;
-
-
-
-namespace WPCordovaClassLib
-{
-    public partial class CordovaView : UserControl
-    {
-
-        /// <summary>
-        /// Indicates whether web control has been loaded and no additional initialization is needed.
-        /// Prevents data clearing during page transitions.
-        /// </summary>
-        private bool IsBrowserInitialized = false;
-
-        /// <summary>
-        /// Set when the user attaches a back button handler inside the WebBrowser
-        /// </summary>
-        private bool OverrideBackButton = false;
-
-        /// <summary>
-        /// Sentinel to keep track of page changes as a result of the hardware back button
-        /// Set to false when the back-button is pressed, which calls js window.history.back()
-        /// If the page changes as a result of the back button the event is cancelled.
-        /// </summary>
-        private bool PageDidChange = false;
-
-        private static string AppRoot = "/app/";
-
-
-        /// <summary>
-        /// Handles native api calls
-        /// </summary>
-        private NativeExecution nativeExecution;
-
-        protected BrowserMouseHelper bmHelper;
-
-        protected DOMStorageHelper domStorageHelper;
-        protected OrientationHelper orientationHelper;
-
-        private ConfigHandler configHandler;
-
-        public System.Windows.Controls.Grid _LayoutRoot
-        {
-            get
-            {
-                return ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
-            }
-        }
-
-        public WebBrowser Browser
-        {
-            get
-            {
-                return CordovaBrowser;
-            }
-        }
-
-        /*
-         * Setting StartPageUri only has an effect if called before the view is loaded.
-         **/
-        protected Uri _startPageUri = null;
-        public Uri StartPageUri
-        {
-            get
-            {
-                if (_startPageUri == null)
-                {
-                    // default
-                    return new Uri(AppRoot + "www/index.html", UriKind.Relative);
-                }
-                else
-                {
-                    return _startPageUri;
-                }
-            }
-            set
-            {
-                if (!this.IsBrowserInitialized)
-                {
-                    _startPageUri = value;
-                }
-            }
-        }
-
-        public CordovaView()
-        {
-
-            InitializeComponent();
-
-            if (DesignerProperties.IsInDesignTool)
-            {
-                return;
-            }
-
-
-            StartupMode mode = PhoneApplicationService.Current.StartupMode;
-
-            if (mode == StartupMode.Launch)
-            {
-                PhoneApplicationService service = PhoneApplicationService.Current;
-                service.Activated += new EventHandler<Microsoft.Phone.Shell.ActivatedEventArgs>(AppActivated);
-                service.Launching += new EventHandler<LaunchingEventArgs>(AppLaunching);
-                service.Deactivated += new EventHandler<DeactivatedEventArgs>(AppDeactivated);
-                service.Closing += new EventHandler<ClosingEventArgs>(AppClosing);
-            }
-            else
-            {
-
-            }
-
-            configHandler = new ConfigHandler();
-            configHandler.LoadAppPackageConfig();
-
-            if (configHandler.ContentSrc != null)
-            {
-                if (Uri.IsWellFormedUriString(configHandler.ContentSrc, UriKind.Absolute))
-                {
-                    this.StartPageUri = new Uri(configHandler.ContentSrc, UriKind.Absolute);
-                }
-                else
-                {
-                    this.StartPageUri = new Uri(AppRoot + "www/" + configHandler.ContentSrc, UriKind.Relative);
-                }
-            }  
-
-            // initializes native execution logic
-            nativeExecution = new NativeExecution(ref this.CordovaBrowser);
-            bmHelper = new BrowserMouseHelper(ref this.CordovaBrowser);
-        }
-
-
-
-        void AppClosing(object sender, ClosingEventArgs e)
-        {
-            //Debug.WriteLine("AppClosing");
-        }
-
-        void AppDeactivated(object sender, DeactivatedEventArgs e)
-        {
-            Debug.WriteLine("INFO: AppDeactivated");
-
-            try
-            {
-                CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('pause');" });
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("ERROR: Pause event error");
-            }
-        }
-
-        void AppLaunching(object sender, LaunchingEventArgs e)
-        {
-            //Debug.WriteLine("INFO: AppLaunching");
-        }
-
-        void AppActivated(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
-        {
-            Debug.WriteLine("INFO: AppActivated");
-            try
-            {
-                CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('resume');" });
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("ERROR: Resume event error");
-            }
-        }
-
-        void GapBrowser_Loaded(object sender, RoutedEventArgs e)
-        {
-            if (DesignerProperties.IsInDesignTool)
-            {
-                return;
-            }
-
-            // prevents refreshing web control to initial state during pages transitions
-            if (this.IsBrowserInitialized) return;
-
-
-
-            this.domStorageHelper = new DOMStorageHelper(this.CordovaBrowser);
-
-            try
-            {
-
-                // Before we possibly clean the ISO-Store, we need to grab our generated UUID, so we can rewrite it after.
-                string deviceUUID = "";
-
-                using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    try
-                    {
-                        IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
-
-                        using (StreamReader reader = new StreamReader(fileStream))
-                        {
-                            deviceUUID = reader.ReadLine();
-                        }
-                    }
-                    catch (Exception /*ex*/)
-                    {
-                        deviceUUID = Guid.NewGuid().ToString();
-                    }
-
-                    Debug.WriteLine("Updating IsolatedStorage for APP:DeviceID :: " + deviceUUID);
-                    IsolatedStorageFileStream file = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Create, FileAccess.Write, appStorage);
-                    using (StreamWriter writeFile = new StreamWriter(file))
-                    {
-                        writeFile.WriteLine(deviceUUID);
-                        writeFile.Close();
-                    }
-
-                }
-
-                StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("CordovaSourceDictionary.xml", UriKind.Relative));
-
-                if (streamInfo != null)
-                {
-                    StreamReader sr = new StreamReader(streamInfo.Stream);
-                    //This will Read Keys Collection for the xml file
-
-                    XDocument document = XDocument.Parse(sr.ReadToEnd());
-
-                    var files = from results in document.Descendants("FilePath")
-                                select new
-                                {
-                                    path = (string)results.Attribute("Value")
-                                };
-                    StreamResourceInfo fileResourceStreamInfo;
-
-                    using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-
-                        foreach (var file in files)
-                        {
-                            fileResourceStreamInfo = Application.GetResourceStream(new Uri(file.path, UriKind.Relative));
-
-                            if (fileResourceStreamInfo != null)
-                            {
-                                using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
-                                {
-                                    byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
-                                    string strBaseDir = AppRoot + file.path.Substring(0, file.path.LastIndexOf(System.IO.Path.DirectorySeparatorChar));
-
-                                    if (!appStorage.DirectoryExists(strBaseDir))
-                                    {
-                                        Debug.WriteLine("INFO: Creating Directory :: " + strBaseDir);
-                                        appStorage.CreateDirectory(strBaseDir);
-                                    }
-
-                                    // This will truncate/overwrite an existing file, or 
-                                    using (IsolatedStorageFileStream outFile = appStorage.OpenFile(AppRoot + file.path, FileMode.Create))
-                                    {
-                                        Debug.WriteLine("INFO: Writing data for " + AppRoot + file.path + " and length = " + data.Length);
-                                        using (var writer = new BinaryWriter(outFile))
-                                        {
-                                            writer.Write(data);
-                                        }
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                Debug.WriteLine("ERROR: Failed to write file :: " + file.path + " did you forget to add it to the project?");
-                            }
-                        }
-                    }
-                }
-
-                CordovaBrowser.Navigate(StartPageUri);
-                IsBrowserInitialized = true;
-                AttachHardwareButtonHandlers();
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine("ERROR: Exception in GapBrowser_Loaded :: {0}", ex.Message);
-            }
-        }
-
-        void AttachHardwareButtonHandlers()
-        {
-            PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-            if (frame != null)
-            {
-                PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
-                if (page != null)
-                {
-                    page.BackKeyPress += new EventHandler<CancelEventArgs>(page_BackKeyPress);
-
-                    this.orientationHelper = new OrientationHelper(this.CordovaBrowser, page);
-
-                }
-            }
-        }
-
-        void page_BackKeyPress(object sender, CancelEventArgs e)
-        {
-
-            if (OverrideBackButton)
-            {
-                try
-                {
-                    CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('backbutton');" });
-                    e.Cancel = true;
-                }
-                catch (Exception ex)
-                {
-                    Console.WriteLine("Exception while invoking backbutton into cordova view: " + ex.Message);
-                }
-            }
-            else
-            {
-                try
-                {
-                    PageDidChange = false;
-
-                    Uri uriBefore = this.Browser.Source;
-                    // calling js history.back with result in a page change if history was valid.
-                    CordovaBrowser.InvokeScript("eval", new string[] { "(function(){window.history.back();})()" });
-
-                    Uri uriAfter = this.Browser.Source;
-
-                    e.Cancel = PageDidChange || (uriBefore != uriAfter);
-                }
-                catch (Exception)
-                {
-                    e.Cancel = false; // exit the app ... ?
-                }
-            }
-        }
-
-        void GapBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            string nativeReady = "(function(){ cordova.require('cordova/channel').onNativeReady.fire()})();";
-
-            try
-            {
-                CordovaBrowser.InvokeScript("eval", new string[] { nativeReady });
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine("Error calling js to fire nativeReady event. Did you include cordova-x.x.x.js in your html script tag?");
-            }
-
-            if (this.CordovaBrowser.Opacity < 1)
-            {
-                this.CordovaBrowser.Opacity = 1;
-                RotateIn.Begin();
-            }
-        }
-
-
-        void GapBrowser_Navigating(object sender, NavigatingEventArgs e)
-        {
-            if (!configHandler.URLIsAllowed(e.Uri.ToString()))
-            {
-                e.Cancel = true;
-                return;
-            }
-
-            this.PageDidChange = true;
-            // Debug.WriteLine("GapBrowser_Navigating to :: " + e.Uri.ToString());
-            this.nativeExecution.ResetAllCommands();
-
-            // TODO: check whitelist / blacklist
-            // NOTE: Navigation can be cancelled by setting :        e.Cancel = true;
-        }
-
-        /*
-         *  This method does the work of routing commands
-         *  NotifyEventArgs.Value contains a string passed from JS 
-         *  If the command already exists in our map, we will just attempt to call the method(action) specified, and pass the args along
-         *  Otherwise, we create a new instance of the command, add it to the map, and call it ...
-         *  This method may also receive JS error messages caught by window.onerror, in any case where the commandStr does not appear to be a valid command
-         *  it is simply output to the debugger output, and the method returns.
-         * 
-         **/
-        void GapBrowser_ScriptNotify(object sender, NotifyEventArgs e)
-        {
-            string commandStr = e.Value;
-
-            if (commandStr.IndexOf("DOMStorage") == 0)
-            {
-                this.domStorageHelper.HandleStorageCommand(commandStr);
-                return;
-            }
-            else if (commandStr.IndexOf("Orientation") == 0)
-            {
-                this.orientationHelper.HandleCommand(commandStr);
-                return;
-            }
-
-            CordovaCommandCall commandCallParams = CordovaCommandCall.Parse(commandStr);
-
-            if (commandCallParams == null)
-            {
-                // ERROR
-                Debug.WriteLine("ScriptNotify :: " + commandStr);
-            }
-            else if (commandCallParams.Service == "CoreEvents")
-            {
-                switch (commandCallParams.Action.ToLower())
-                {
-                    case "overridebackbutton":
-                        string arg0 = JsonHelper.Deserialize<string[]>(commandCallParams.Args)[0];
-                        this.OverrideBackButton = (arg0 != null && arg0.Length > 0 && arg0.ToLower() == "true"); 
-                        break;
-                }
-            }
-            else
-            {
-                if (configHandler.IsPluginAllowed(commandCallParams.Service))
-                {
-                    nativeExecution.ProcessCommand(commandCallParams);
-                }
-                else
-                {
-                    Debug.WriteLine("Error::Plugin not allowed in config.xml. " + commandCallParams.Service);
-                }
-            }
-        }
-
-        public void LoadPage(string url)
-        {
-            try 
-            {
-                Uri newLoc = new Uri(url,UriKind.RelativeOrAbsolute);
-                CordovaBrowser.Navigate(newLoc);
-            }
-            catch(Exception)
-            {
-
-            }
-        }
-
-        private void GapBrowser_Unloaded(object sender, RoutedEventArgs e)
-        {
-
-        }
-
-        private void GapBrowser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
-        {
-            Debug.WriteLine("GapBrowser_NavigationFailed :: " + e.Uri.ToString());
-        }
-
-        private void GapBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            Debug.WriteLine("GapBrowser_Navigated :: " + e.Uri.ToString());
-        }
-
-
-    }
-}
diff --git a/templates/standalone/cordovalib/DOMStorageHelper.cs b/templates/standalone/cordovalib/DOMStorageHelper.cs
deleted file mode 100644
index f57bae4..0000000
--- a/templates/standalone/cordovalib/DOMStorageHelper.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.IO.IsolatedStorage;
-using System.Collections.Generic;
-using Microsoft.Phone.Controls;
-using System.Linq;
-using WPCordovaClassLib.Cordova.JSON;
-
-/*
- * Translates DOMStorage API between JS and Isolated Storage
- * Missing pieces : QUOTA_EXCEEDED_ERR  + StorageEvent  
- * */
-
-namespace WPCordovaClassLib
-{
-    public class DOMStorageHelper
-    {
-        protected WebBrowser webBrowser1;
-
-        public DOMStorageHelper(WebBrowser gapBrowser)
-        {
-            this.webBrowser1 = gapBrowser;
-            // always clear session at creation
-            UserSettings["sessionStorage"] = new Dictionary<string, string>();
-
-            if (!UserSettings.Contains("localStorage"))
-            {
-                UserSettings["localStorage"] = new Dictionary<string, string>();
-                UserSettings.Save();
-            }
-            Application.Current.Exit += new EventHandler(OnAppExit);
-        }
-
-        void OnAppExit(object sender, EventArgs e)
-        {
-            UserSettings.Remove("sessionStorage");
-            UserSettings.Save();
-        }
-
-        protected IsolatedStorageSettings UserSettings
-        {
-            get
-            {
-                return IsolatedStorageSettings.ApplicationSettings;
-            }
-        }
-
-        protected Dictionary<string, string> getStorageByType(string type)
-        {
-            if (!UserSettings.Contains(type))
-            {
-                UserSettings[type] = new Dictionary<string, string>();
-                UserSettings.Save();
-            }
-            return UserSettings[type] as Dictionary<string, string>;
-        }
-
-
-        public void HandleStorageCommand(string commandStr)
-        {
-
-            string[] split = commandStr.Split('/');
-            if (split.Length > 3)
-            {
-                string api = split[0];
-                string type = split[1]; // localStorage || sessionStorage
-                string command = split[2];
-                string param = split[3];
-
-                Dictionary<string, string> currentStorage = getStorageByType(type);
-
-                switch (command)
-                {
-                    case "get":
-                        {
-
-                            if (currentStorage.Keys.Contains(param))
-                            {
-                                string value = currentStorage[param];
-                                webBrowser1.InvokeScript("execScript", "window." + type + ".onResult('" + param + "','" + value + "');");
-                            }
-                            else
-                            {
-                                webBrowser1.InvokeScript("execScript", "window." + type + ".onResult('" + param + "');");
-                            }
-
-                        }
-                        break;
-                    case "load":
-                        {
-                            string[] keys = currentStorage.Keys.ToArray();
-                            string jsonString = JsonHelper.Serialize(keys);
-                            string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            webBrowser1.InvokeScript("execScript", callbackJS);
-                        }
-                        break;
-                    case "set":
-                        {
-                            // TODO: check that length is not out of bounds
-                            currentStorage[param] = split[4];
-                            UserSettings.Save();
-                            string[] keys = currentStorage.Keys.ToArray();
-                            string jsonString = JsonHelper.Serialize(keys);
-                            string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            webBrowser1.InvokeScript("execScript", callbackJS);
-                        }
-                        break;
-                    case "remove":
-                        currentStorage.Remove(param);
-                        UserSettings.Save();
-                        break;
-                    case "clear":
-                        currentStorage = new Dictionary<string, string>();
-                        UserSettings[type] = currentStorage;
-                        UserSettings.Save();
-                        break;
-                }
-
-            }
-
-        }
-    }
-}
diff --git a/templates/standalone/cordovalib/ImageExifHelper.cs b/templates/standalone/cordovalib/ImageExifHelper.cs
deleted file mode 100644
index 62b6462..0000000
--- a/templates/standalone/cordovalib/ImageExifHelper.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
- 
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows.Media.Imaging;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class ImageExifOrientation
-    {
-        public const int Portrait = 1;
-        public const int PortraitUpsideDown = 3;
-        public const int LandscapeLeft = 6;
-        public const int LandscapeRight = 8;
-    }
-
-    public class ImageExifHelper
-    {
-
-        public static Stream RotateStream(Stream stream, int angle)
-        {
-            stream.Position = 0;
-            if (angle % 90 != 0 || angle < 0)
-            {
-                throw new ArgumentException();
-            }
-            if (angle % 360 == 0)
-            {
-                return stream;
-            }
-
-            angle = angle % 360;
-
-            BitmapImage bitmap = new BitmapImage();
-            bitmap.SetSource(stream);
-            WriteableBitmap wbSource = new WriteableBitmap(bitmap);
-
-            WriteableBitmap wbTarget = null;
-
-            int srcPixelWidth = wbSource.PixelWidth;
-            int srcPixelHeight = wbSource.PixelHeight;
-
-            if (angle % 180 == 0)
-            {
-                wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
-            }
-            else
-            {
-                wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
-            }
-
-            int destPixelWidth = wbTarget.PixelWidth;
-            int[] srcPxls = wbSource.Pixels;
-            int[] destPxls = wbTarget.Pixels;
-
-            // this ugly if/else is to avoid a conditional check for every pixel
-            if (angle == 90)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-            else if (angle == 180)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-            else if (angle == 270)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-
-            MemoryStream targetStream = new MemoryStream();
-            wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
-            return targetStream;
-        }
-
-        public static int getImageOrientationFromStream(Stream imgStream)
-        {
-
-            // 0xFFD8 : jpgHeader
-            // 0xFFE1 :
-            // 0x???? : length of exif data
-            // 0x????, 0x???? : Chars 'E','x','i','f'
-            // 0x0000 : 2 empty bytes
-            // <== mark beginning of tags SIZE:ID:VALUE
-            // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determines littleEndian-ness
-            // 0x002A : marker value
-            // 0x???? : offset to the Image File Data
-
-            // XXXX possible space before actual tag data ... we skip to mark + offset
-
-            // 0x???? number of exif tags present
-
-            // make sure we are at the beginning
-            imgStream.Seek(0, SeekOrigin.Begin);
-            BinaryReader reader = new BinaryReader(imgStream);
-
-            byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
-
-            byte start = reader.ReadByte(); // 0xFF
-            byte index = reader.ReadByte(); // 0xE1
-
-            while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
-            {
-                // Get the data length
-                ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-                // skip along
-                reader.ReadBytes(dLen - 2);
-                start = reader.ReadByte();
-                index = reader.ReadByte();
-            }
-
-            // It's only success if we found the 0xFFE1 marker
-            if (start != 0xFF || index != 0xE1)
-            {
-                //   throw new Exception("Could not find Exif data block");
-                Debug.WriteLine("Did not find EXIF data");
-                return 0;
-            }
-
-            // read 2 byte length of EXIF data
-            ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            String exif = ""; // build the string
-            for (var n = 0; n < 4; n++)
-            {
-                exif += reader.ReadChar();
-            }
-            if (exif != "Exif")
-            {
-                // did not find exif data ...
-                Debug.WriteLine("Did not find EXIF data");
-                return 0;
-            }
-
-            // read 2 empty bytes
-            //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            reader.ReadBytes(2);
-
-            long headerMark = reader.BaseStream.Position; // where are we now <==
-
-            //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
-            reader.ReadBytes(2); // 'II' or 'MM', but we don't care
-
-            if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
-            {
-                Debug.WriteLine("Error in data != 0x002A");
-                return 0;
-            }
-
-            // Get the offset to the IFD (image file directory)
-            ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-
-            imgStream.Position = headerMark + imgOffset;
-            ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            for (ushort x = 0; x < tagCount; x++)
-            {
-                // Orientation = 0x112, aka 274
-                if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
-                {
-                    ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-                    // don't care ..
-                    uint comps = reader.ReadUInt32();
-                    byte[] tagData = reader.ReadBytes(4);
-                    int orientation = (int)tagData[0];
-                    Debug.WriteLine("orientation = " + orientation.ToString());
-                    return orientation;
-                    // 6 means rotate clockwise 90 deg
-                    // 8 means rotate counter-clockwise 90 deg
-                    // 1 means all is good
-                    // 3 means flip vertical
-                }
-                // skip to the next item, 12 bytes each
-                reader.BaseStream.Seek(10, SeekOrigin.Current);
-            }
-            return 0;
-        }
-
-    }
-}
diff --git a/templates/standalone/cordovalib/JSON/JsonHelper.cs b/templates/standalone/cordovalib/JSON/JsonHelper.cs
deleted file mode 100644
index 44511f6..0000000
--- a/templates/standalone/cordovalib/JSON/JsonHelper.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Runtime.Serialization.Json;
-using System.IO;
-using System.Collections.Generic;
-using System.Text;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.JSON
-{
-    /// <summary>
-    /// Provides JSON serialization/deserialization functionality.
-    /// </summary>
-    public static class JsonHelper
-    {
-        /// <summary>
-        /// Serializes object to JSON string representation
-        /// </summary>
-        /// <param name="obj">object to serialize</param>
-        /// <returns>JSON representation of the object. Returns 'null' string for null passed as argument</returns>
-        public static string Serialize(object obj)
-        {
-            if (obj == null)
-            {
-                return "null";
-            }
-
-            DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
-
-            MemoryStream ms = new MemoryStream();
-            ser.WriteObject(ms, obj);
-
-            ms.Position = 0;
-
-            string json = String.Empty;
-
-            using (StreamReader sr = new StreamReader(ms))
-            {
-                json = sr.ReadToEnd();
-            }
-
-            ms.Close();
-
-            return json;
-
-        }
-
-        /// <summary>
-        /// Parses json string to object instance
-        /// </summary>
-        /// <typeparam name="T">type of the object</typeparam>
-        /// <param name="json">json string representation of the object</param>
-        /// <returns>Deserialized object instance</returns>
-        public static T Deserialize<T>(string json)
-        {
-            DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
-            object result = null;
-            try
-            {
-                using (MemoryStream mem = new MemoryStream(Encoding.UTF8.GetBytes(json)))
-                {
-                    result = deserializer.ReadObject(mem);
-                }
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine(ex.Message);
-                Debug.WriteLine("Failed to deserialize " + typeof(T) + " with JSON value :: " + json);
-            }
-
-            return (T)result;
-
-        }
-    }
-}
diff --git a/templates/standalone/cordovalib/NativeExecution.cs b/templates/standalone/cordovalib/NativeExecution.cs
deleted file mode 100644
index af6b207..0000000
--- a/templates/standalone/cordovalib/NativeExecution.cs
+++ /dev/null
@@ -1,246 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Diagnostics;
-using System.Threading;
-using Microsoft.Devices;
-using Microsoft.Phone.Controls;
-using WPCordovaClassLib.Cordova.Commands;
-using System.Windows;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Implements logic to execute native command and return result back.
-    /// All commands are executed asynchronous.
-    /// </summary>
-    public class NativeExecution
-    {
-        /// <summary>
-        /// Reference to web part where application is hosted
-        /// </summary>
-        private readonly WebBrowser webBrowser;
-
-        /// <summary>
-        /// Creates new instance of a NativeExecution class. 
-        /// </summary>
-        /// <param name="browser">Reference to web part where application is hosted</param>
-        public NativeExecution(ref WebBrowser browser)
-        {
-            if (browser == null)
-            {
-                throw new ArgumentNullException("browser");
-            }
-
-            this.webBrowser = browser;
-        }
-
-        /// <summary>
-        /// Returns where application is running on emulator
-        /// </summary>
-        /// <returns>True if running on emulator, otherwise False</returns>
-        public static bool IsRunningOnEmulator()
-        {
-            return Microsoft.Devices.Environment.DeviceType == DeviceType.Emulator;
-        }
-
-        public void ResetAllCommands()
-        {
-            CommandFactory.ResetAllCommands();
-        }
-
-        public void AutoLoadCommand(string commandService)
-        {
-            BaseCommand bc = CommandFactory.CreateByServiceName(commandService);
-            if (bc != null)
-            {
-                bc.OnInit();
-            }
-
-        }
-
-        /// <summary>
-        /// Executes command and returns result back.
-        /// </summary>
-        /// <param name="commandCallParams">Command to execute</param>
-        public void ProcessCommand(CordovaCommandCall commandCallParams)
-        {
-
-            if (commandCallParams == null)
-            {
-                throw new ArgumentNullException("commandCallParams");
-            }
-
-            try
-            {
-                BaseCommand bc = CommandFactory.CreateByServiceName(commandCallParams.Service);
-
-                if (bc == null)
-                {
-                    this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION));
-                    return;
-                }
-
-                EventHandler<PluginResult> OnCommandResultHandler = delegate(object o, PluginResult res)
-                {
-                    if (res.CallbackId == null || res.CallbackId == commandCallParams.CallbackId)
-                    {
-                        this.OnCommandResult(commandCallParams.CallbackId, res);
-                        if (!res.KeepCallback)
-                        {
-                            bc.RemoveResultHandler(commandCallParams.CallbackId);
-                        }
-                    }
-                };
-
-                //bc.OnCommandResult += OnCommandResultHandler;
-                bc.AddResultHandler(commandCallParams.CallbackId, OnCommandResultHandler);
-
-                EventHandler<ScriptCallback> OnCustomScriptHandler = delegate(object o, ScriptCallback script)
-                {
-                    this.InvokeScriptCallback(script);
-                };
-
-                bc.OnCustomScript += OnCustomScriptHandler;
-
-                ThreadStart methodInvokation = () =>
-                {
-                    try
-                    {
-                        bc.InvokeMethodNamed(commandCallParams.CallbackId,commandCallParams.Action, commandCallParams.Args);
-                    }
-                    catch (Exception ex)
-                    {
-                        Debug.WriteLine("ERROR: Exception in ProcessCommand :: " + ex.Message);
-                        bc.RemoveResultHandler(commandCallParams.CallbackId);
-                        bc.OnCustomScript -= OnCustomScriptHandler;
-
-                        Debug.WriteLine("ERROR: failed to InvokeMethodNamed :: " + commandCallParams.Action + " on Object :: " + commandCallParams.Service);
-                        this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.INVALID_ACTION));
-                        return;
-                    }
-                };
-
-                if ((bc is File) || (bc is Accelerometer))
-                {
-                    // Due to some issues with the IsolatedStorage in current version of WP8 SDK we have to run all File Api commands synchronously.
-                    // TODO: test this in WP8 RTM
-                    methodInvokation.Invoke();
-                }
-                else
-                {
-                    new Thread(methodInvokation).Start();
-                }
-
-
-            }
-            catch (Exception ex)
-            {
-                // ERROR
-                Debug.WriteLine(String.Format("ERROR: Unable to execute command :: {0}:{1}:{3} ",
-                    commandCallParams.Service, commandCallParams.Action, ex.Message));
-
-                this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.ERROR));
-                return;
-            }
-        }
-
-        /// <summary>
-        /// Handles command execution result.
-        /// </summary>
-        /// <param name="callbackId">Command callback identifier on client side</param>
-        /// <param name="result">Execution result</param>
-        private void OnCommandResult(string callbackId, PluginResult result)
-        {
-            #region  args checking
-
-            if (result == null)
-            {
-                Debug.WriteLine("ERROR: OnCommandResult missing result argument");
-                return;
-            }
-
-            if (String.IsNullOrEmpty(callbackId))
-            {
-                Debug.WriteLine("ERROR: OnCommandResult missing callbackId argument");
-                return;
-            }
-
-            if (!String.IsNullOrEmpty(result.CallbackId) && callbackId != result.CallbackId)
-            {
-                Debug.WriteLine("Multiple Overlapping Results :: " + result.CallbackId + " :: " + callbackId);
-                return;
-            }
-
-            #endregion
-
-            string jsonResult = result.ToJSONString();
-
-            string callback;
-            string args = string.Format("('{0}',{1});", callbackId, jsonResult);
-
-            if (result.Result == PluginResult.Status.NO_RESULT ||
-               result.Result == PluginResult.Status.OK)
-            {
-                callback = @"(function(callbackId,args) {
-                try { args.message = JSON.parse(args.message); } catch (ex) { }
-                cordova.callbackSuccess(callbackId,args);
-                })" + args;
-            }
-            else
-            {
-                callback = @"(function(callbackId,args) {
-                try { args.message = JSON.parse(args.message); } catch (ex) { }
-                cordova.callbackError(callbackId,args);
-                })" + args;
-            }
-            this.InvokeScriptCallback(new ScriptCallback("eval", new string[] { callback }));
-
-        }
-
-        /// <summary>
-        /// Executes client java script
-        /// </summary>
-        /// <param name="script">Script to execute on client side</param>
-        private void InvokeScriptCallback(ScriptCallback script)
-        {
-            if (script == null)
-            {
-                throw new ArgumentNullException("script");
-            }
-
-            if (String.IsNullOrEmpty(script.ScriptName))
-            {
-                throw new ArgumentNullException("ScriptName");
-            }
-
-            //Debug.WriteLine("INFO:: About to invoke ::" + script.ScriptName + " with args ::" + script.Args[0]);
-            this.webBrowser.Dispatcher.BeginInvoke((ThreadStart)delegate()
-            {
-                try
-                {
-                    //Debug.WriteLine("INFO:: InvokingScript::" + script.ScriptName + " with args ::" + script.Args[0]);
-                    this.webBrowser.InvokeScript(script.ScriptName, script.Args);
-                }
-                catch (Exception ex)
-                {
-                    Debug.WriteLine("ERROR: Exception in InvokeScriptCallback :: " + ex.Message);
-                }
-
-            });
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/templates/standalone/cordovalib/OrientationHelper.cs b/templates/standalone/cordovalib/OrientationHelper.cs
deleted file mode 100644
index 81a329e..0000000
--- a/templates/standalone/cordovalib/OrientationHelper.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using Microsoft.Phone.Controls;
-
-namespace WPCordovaClassLib.Cordova
-{
-    public class OrientationHelper
-    {
-        protected WebBrowser gapBrowser;
-        protected PhoneApplicationPage page;
-        // private PageOrientation CurrentOrientation = PageOrientation.PortraitUp;
-        //private PageOrientation[] SupportedOrientations; // TODO:
-
-        public OrientationHelper(WebBrowser gapBrowser, PhoneApplicationPage gapPage)
-        {
-            this.gapBrowser = gapBrowser;
-            page = gapPage;
-
-            page.OrientationChanged += new EventHandler<OrientationChangedEventArgs>(page_OrientationChanged);
-            gapBrowser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(gapBrowser_LoadCompleted);
-
-
-        }
-
-        void gapBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            int i = 0;
-
-            switch (this.page.Orientation)
-            {
-                case PageOrientation.Portrait: // intentional fall through
-                case PageOrientation.PortraitUp:
-                    i = 0;
-                    break;
-                case PageOrientation.PortraitDown:
-                    i = 180;
-                    break;
-                case PageOrientation.Landscape: // intentional fall through
-                case PageOrientation.LandscapeLeft:
-                    i = -90;
-                    break;
-                case PageOrientation.LandscapeRight:
-                    i = 90;
-                    break;
-            }
-            // Cordova.fireEvent('orientationchange', window);
-            string jsCallback = String.Format("window.orientation = {0};", i);
-
-            try
-            {
-                gapBrowser.InvokeScript("execScript", jsCallback);
-            }
-            catch (Exception)
-            {
-            }
-        }
-
-        void page_OrientationChanged(object sender, OrientationChangedEventArgs e)
-        {
-            int i = 0;
-
-            switch (e.Orientation)
-            {
-                case PageOrientation.Portrait: // intentional fall through
-                case PageOrientation.PortraitUp:
-                    i = 0;
-                    break;
-                case PageOrientation.PortraitDown:
-                    i = 180;
-                    break;
-                case PageOrientation.Landscape: // intentional fall through
-                case PageOrientation.LandscapeLeft:
-                    i = -90;
-                    break;
-                case PageOrientation.LandscapeRight:
-                    i = 90;
-                    break;
-            }
-            // Cordova.fireEvent('orientationchange', window);
-            string jsCallback = String.Format("window.orientation = {0};", i);
-
-            try
-            {
-
-                gapBrowser.InvokeScript("execScript", jsCallback);
-
-                jsCallback = "var evt = document.createEvent('HTMLEvents');";
-                jsCallback += "evt.initEvent( 'orientationchange', true, false );";
-                jsCallback += "window.dispatchEvent(evt);";
-                jsCallback += "if(window.onorientationchange){window.onorientationchange(evt);}";
-
-                gapBrowser.InvokeScript("execScript", jsCallback);
-            }
-            catch (Exception)
-            {
-            }
-        }
-
-        public void HandleCommand(string commandStr)
-        {
-
-        }
-    }
-
-
-}
diff --git a/templates/standalone/cordovalib/PluginResult.cs b/templates/standalone/cordovalib/PluginResult.cs
deleted file mode 100644
index 00017d2..0000000
--- a/templates/standalone/cordovalib/PluginResult.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-﻿/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Text;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Represents command execution result
-    /// </summary>
-    public class PluginResult : EventArgs
-    {
-        /// <summary>
-        /// Predefined resultant messages
-        /// </summary>
-        public static string[] StatusMessages = new string[] 
-		{
-			"No result",
-			"OK",
-			"Class not found",
-			"Illegal access",
-			"Instantiation error",
-			"Malformed url",
-			"IO error",
-			"Invalid action",
-			"JSON error",
-			"Error"
-		};
-
-        /// <summary>
-        /// Possible command results status codes
-        /// </summary>
-        public enum Status : int
-        {
-            NO_RESULT = 0,
-            OK,
-            CLASS_NOT_FOUND_EXCEPTION,
-            ILLEGAL_ACCESS_EXCEPTION,
-            INSTANTIATION_EXCEPTION,
-            MALFORMED_URL_EXCEPTION,
-            IO_EXCEPTION,
-            INVALID_ACTION,
-            JSON_EXCEPTION,
-            ERROR
-        };
-
-        public Status Result { get; private set; }
-        public string Message { get; set; }
-        public bool KeepCallback { get; set; }
-        public string CallbackId { get; set; }
-
-        /// <summary>
-        /// Whether command succeded or not
-        /// </summary>
-        public bool IsSuccess
-        {
-            get
-            {
-                return this.Result == Status.OK || this.Result == Status.NO_RESULT;
-            }
-        }
-
-        /// <summary>
-        /// Creates new instance of the PluginResult class.
-        /// </summary>
-        /// <param name="status">Execution result</param>
-        public PluginResult(Status status)
-            : this(status, PluginResult.StatusMessages[(int)status])
-        {
-        }
-
-        /// <summary>
-        /// Creates new instance of the PluginResult class.
-        /// </summary>
-        /// <param name="status">Execution result</param>
-        /// <param name="message">The message</param>
-        public PluginResult(Status status, object message)
-        {
-            this.Result = status;
-            this.Message = JSON.JsonHelper.Serialize(message);
-        }
-
-        public string ToJSONString()
-        {
-            string res = String.Format("\"status\":{0},\"message\":{1},\"keepCallback\":{2}",
-                (int)this.Result,
-                this.Message,
-                this.KeepCallback.ToString().ToLower());
-
-            res = "{" + res + "}";
-            return res;
-
-        }
-
-        [Obsolete]
-        public string ToCallbackString(string callbackId, string successCallback, string errorCallback)
-        {
-            if (this.IsSuccess)
-            {
-                StringBuilder buf = new StringBuilder("");
-                buf.Append(String.Format("{0}('{1}',{2});", successCallback, callbackId, this.ToJSONString()));
-                return buf.ToString();
-            }
-            else
-            {
-                return String.Format("{0}('{1}',{2});", errorCallback, callbackId, this.ToJSONString());
-            }
-        }
-
-        public override String ToString()
-        {
-            return this.ToJSONString();
-        }
-
-    }
-
-}
diff --git a/templates/standalone/cordovalib/ScriptCallback.cs b/templates/standalone/cordovalib/ScriptCallback.cs
deleted file mode 100644
index 7878134..0000000
--- a/templates/standalone/cordovalib/ScriptCallback.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-﻿/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License. 
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using WPCordovaClassLib.Cordova.JSON;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Represents client script function to execute
-    /// </summary>
-    public class ScriptCallback : EventArgs
-    {
-        /// <summary>
-        /// The scripting function to execute.
-        /// </summary>
-        public string ScriptName { get; private set; }
-
-        /// <summary>
-        /// A variable number of strings to pass to the function as parameters.
-        /// </summary>
-        public string[] Args { get; private set; }
-
-        /// <summary>
-        /// Creates new instance of a ScriptCallback class.
-        /// </summary>
-        /// <param name="function">The scripting function to execute</param>
-        /// <param name="args">A variable number of strings to pass to the function as parameters</param>
-        public ScriptCallback(string function, string[] args)
-        {
-            this.ScriptName = function;
-            this.Args = args;
-        }
-
-        /// <summary>
-        /// Creates new instance of a ScriptCallback class.
-        /// </summary>
-        /// <param name="function">The scripting function to execute</param>
-        /// <param name="id">The id argument</param>
-        /// <param name="msg">The message argument</param>
-        /// <param name="value">The value argument</param>
-        public ScriptCallback(string function, string id, object msg, object value)
-        {
-            this.ScriptName = function;
-
-            String arg = String.Format("{{\"id\": {0}, \"msg\": {1}, \"value\": {2}}}",
-                 JsonHelper.Serialize(id), JsonHelper.Serialize(msg), JsonHelper.Serialize(value));
-
-            this.Args = new string[] { arg };
-        }
-
-
-    }
-}
diff --git a/templates/standalone/cordovalib/resources/notification-beep.wav b/templates/standalone/cordovalib/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
--- a/templates/standalone/cordovalib/resources/notification-beep.wav
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/resources/notification-beep.wav b/templates/standalone/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
--- a/templates/standalone/resources/notification-beep.wav
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/www/cordova.js b/templates/standalone/www/cordova.js
deleted file mode 100644
index bb348e1..0000000
--- a/templates/standalone/www/cordova.js
+++ /dev/null
@@ -1,6791 +0,0 @@
-﻿// Platform: windowsphone
-// 2.9.0rc1-0-g002f33d
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
-     http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-;(function() {
-var CORDOVA_JS_BUILD_LABEL = '2.9.0rc1-0-g002f33d';
-// file: lib/scripts/require.js
-
-var require,
-    define;
-
-(function () {
-    var modules = {},
-    // Stack of moduleIds currently being built.
-        requireStack = [],
-    // Map of module ID -> index into requireStack of modules currently being built.
-        inProgressModules = {},
-        SEPERATOR = ".";
-
-
-
-    function build(module) {
-        var factory = module.factory,
-            localRequire = function (id) {
-                var resultantId = id;
-                //Its a relative path, so lop off the last portion and add the id (minus "./")
-                if (id.charAt(0) === ".") {
-                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
-                }
-                return require(resultantId);
-            };
-        module.exports = {};
-        delete module.factory;
-        factory(localRequire, module.exports, module);
-        return module.exports;
-    }
-
-    require = function (id) {
-        if (!modules[id]) {
-            throw "module " + id + " not found";
-        } else if (id in inProgressModules) {
-            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
-            throw "Cycle in require graph: " + cycle;
-        }
-        if (modules[id].factory) {
-            try {
-                inProgressModules[id] = requireStack.length;
-                requireStack.push(id);
-                return build(modules[id]);
-            } finally {
-                delete inProgressModules[id];
-                requireStack.pop();
-            }
-        }
-        return modules[id].exports;
-    };
-
-    define = function (id, factory) {
-        if (modules[id]) {
-            throw "module " + id + " already defined";
-        }
-
-        modules[id] = {
-            id: id,
-            factory: factory
-        };
-    };
-
-    define.remove = function (id) {
-        delete modules[id];
-    };
-
-    define.moduleMap = modules;
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
-    module.exports.require = require;
-    module.exports.define = define;
-}
-
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-
-
-var channel = require('cordova/channel');
-
-/**
- * Listen for DOMContentLoaded and notify our channel subscribers.
- */
-document.addEventListener('DOMContentLoaded', function() {
-    channel.onDOMContentLoaded.fire();
-}, false);
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
-    channel.onDOMContentLoaded.fire();
-}
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
-    windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof documentEventHandlers[e] != 'undefined') {
-        documentEventHandlers[e].subscribe(handler);
-    } else {
-        m_document_addEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof windowEventHandlers[e] != 'undefined') {
-        windowEventHandlers[e].subscribe(handler);
-    } else {
-        m_window_addEventListener.call(window, evt, handler, capture);
-    }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof documentEventHandlers[e] != "undefined") {
-        documentEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_document_removeEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof windowEventHandlers[e] != "undefined") {
-        windowEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_window_removeEventListener.call(window, evt, handler, capture);
-    }
-};
-
-function createEvent(type, data) {
-    var event = document.createEvent('Events');
-    event.initEvent(type, false, false);
-    if (data) {
-        for (var i in data) {
-            if (data.hasOwnProperty(i)) {
-                event[i] = data[i];
-            }
-        }
-    }
-    return event;
-}
-
-if(typeof window.console === "undefined") {
-    window.console = {
-        log:function(){}
-    };
-}
-
-var cordova = {
-    define:define,
-    require:require,
-    /**
-     * Methods to add/remove your own addEventListener hijacking on document + window.
-     */
-    addWindowEventHandler:function(event) {
-        return (windowEventHandlers[event] = channel.create(event));
-    },
-    addStickyDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.createSticky(event));
-    },
-    addDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.create(event));
-    },
-    removeWindowEventHandler:function(event) {
-        delete windowEventHandlers[event];
-    },
-    removeDocumentEventHandler:function(event) {
-        delete documentEventHandlers[event];
-    },
-    /**
-     * Retrieve original event handlers that were replaced by Cordova
-     *
-     * @return object
-     */
-    getOriginalHandlers: function() {
-        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
-        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
-    },
-    /**
-     * Method to fire event from native code
-     * bNoDetach is required for events which cause an exception which needs to be caught in native code
-     */
-    fireDocumentEvent: function(type, data, bNoDetach) {
-        var evt = createEvent(type, data);
-        if (typeof documentEventHandlers[type] != 'undefined') {
-            if( bNoDetach ) {
-              documentEventHandlers[type].fire(evt);
-            }
-            else {
-              setTimeout(function() {
-                  // Fire deviceready on listeners that were registered before cordova.js was loaded.
-                  if (type == 'deviceready') {
-                      document.dispatchEvent(evt);
-                  }
-                  documentEventHandlers[type].fire(evt);
-              }, 0);
-            }
-        } else {
-            document.dispatchEvent(evt);
-        }
-    },
-    fireWindowEvent: function(type, data) {
-        var evt = createEvent(type,data);
-        if (typeof windowEventHandlers[type] != 'undefined') {
-            setTimeout(function() {
-                windowEventHandlers[type].fire(evt);
-            }, 0);
-        } else {
-            window.dispatchEvent(evt);
-        }
-    },
-
-    /**
-     * Plugin callback mechanism.
-     */
-    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
-    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
-    callbackId: Math.floor(Math.random() * 2000000000),
-    callbacks:  {},
-    callbackStatus: {
-        NO_RESULT: 0,
-        OK: 1,
-        CLASS_NOT_FOUND_EXCEPTION: 2,
-        ILLEGAL_ACCESS_EXCEPTION: 3,
-        INSTANTIATION_EXCEPTION: 4,
-        MALFORMED_URL_EXCEPTION: 5,
-        IO_EXCEPTION: 6,
-        INVALID_ACTION: 7,
-        JSON_EXCEPTION: 8,
-        ERROR: 9
-    },
-
-    /**
-     * Called by native code when returning successful result from an action.
-     */
-    callbackSuccess: function(callbackId, args) {
-        try {
-            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning error result from an action.
-     */
-    callbackError: function(callbackId, args) {
-        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
-        // Derive success from status.
-        try {
-            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning the result from an action.
-     */
-    callbackFromNative: function(callbackId, success, status, args, keepCallback) {
-        var callback = cordova.callbacks[callbackId];
-        if (callback) {
-            if (success && status == cordova.callbackStatus.OK) {
-                callback.success && callback.success.apply(null, args);
-            } else if (!success) {
-                callback.fail && callback.fail.apply(null, args);
-            }
-
-            // Clear callback if not expecting any more results
-            if (!keepCallback) {
-                delete cordova.callbacks[callbackId];
-            }
-        }
-    },
-    addConstructor: function(func) {
-        channel.onCordovaReady.subscribe(function() {
-            try {
-                func();
-            } catch(e) {
-                console.log("Failed to run constructor: " + e);
-            }
-        });
-    }
-};
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
-
-module.exports = cordova;
-
-});
-
-// file: lib/common/argscheck.js
-define("cordova/argscheck", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var moduleExports = module.exports;
-
-var typeMap = {
-    'A': 'Array',
-    'D': 'Date',
-    'N': 'Number',
-    'S': 'String',
-    'F': 'Function',
-    'O': 'Object'
-};
-
-function extractParamName(callee, argIndex) {
-  return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
-}
-
-function checkArgs(spec, functionName, args, opt_callee) {
-    if (!moduleExports.enableChecks) {
-        return;
-    }
-    var errMsg = null;
-    var typeName;
-    for (var i = 0; i < spec.length; ++i) {
-        var c = spec.charAt(i),
-            cUpper = c.toUpperCase(),
-            arg = args[i];
-        // Asterix means allow anything.
-        if (c == '*') {
-            continue;
-        }
-        typeName = utils.typeName(arg);
-        if ((arg === null || arg === undefined) && c == cUpper) {
-            continue;
-        }
-        if (typeName != typeMap[cUpper]) {
-            errMsg = 'Expected ' + typeMap[cUpper];
-            break;
-        }
-    }
-    if (errMsg) {
-        errMsg += ', but got ' + typeName + '.';
-        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
-        // Don't log when running jake test.
-        if (typeof jasmine == 'undefined') {
-            console.error(errMsg);
-        }
-        throw TypeError(errMsg);
-    }
-}
-
-function getValue(value, defaultValue) {
-    return value === undefined ? defaultValue : value;
-}
-
-moduleExports.checkArgs = checkArgs;
-moduleExports.getValue = getValue;
-moduleExports.enableChecks = true;
-
-
-});
-
-// file: lib/common/builder.js
-define("cordova/builder", function(require, exports, module) {
-
-var utils = require('cordova/utils');
-
-function each(objects, func, context) {
-    for (var prop in objects) {
-        if (objects.hasOwnProperty(prop)) {
-            func.apply(context, [objects[prop], prop]);
-        }
-    }
-}
-
-function clobber(obj, key, value) {
-    exports.replaceHookForTesting(obj, key);
-    obj[key] = value;
-    // Getters can only be overridden by getters.
-    if (obj[key] !== value) {
-        utils.defineGetter(obj, key, function() {
-            return value;
-        });
-    }
-}
-
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
-    if (message) {
-        utils.defineGetter(obj, key, function() {
-            console.log(message);
-            delete obj[key];
-            clobber(obj, key, value);
-            return value;
-        });
-    } else {
-        clobber(obj, key, value);
-    }
-}
-
-function include(parent, objects, clobber, merge) {
-    each(objects, function (obj, key) {
-        try {
-          var result = obj.path ? require(obj.path) : {};
-
-          if (clobber) {
-              // Clobber if it doesn't exist.
-              if (typeof parent[key] === 'undefined') {
-                  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-              } else if (typeof obj.path !== 'undefined') {
-                  // If merging, merge properties onto parent, otherwise, clobber.
-                  if (merge) {
-                      recursiveMerge(parent[key], result);
-                  } else {
-                      assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                  }
-              }
-              result = parent[key];
-          } else {
-            // Overwrite if not currently defined.
-            if (typeof parent[key] == 'undefined') {
-              assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-            } else {
-              // Set result to what already exists, so we can build children into it if they exist.
-              result = parent[key];
-            }
-          }
-
-          if (obj.children) {
-            include(result, obj.children, clobber, merge);
-          }
-        } catch(e) {
-          utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
-        }
-    });
-}
-
-/**
- * Merge properties from one object onto another recursively.  Properties from
- * the src object will overwrite existing target property.
- *
- * @param target Object to merge properties into.
- * @param src Object to merge properties from.
- */
-function recursiveMerge(target, src) {
-    for (var prop in src) {
-        if (src.hasOwnProperty(prop)) {
-            if (target.prototype && target.prototype.constructor === target) {
-                // If the target object is a constructor override off prototype.
-                clobber(target.prototype, prop, src[prop]);
-            } else {
-                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
-                    recursiveMerge(target[prop], src[prop]);
-                } else {
-                    clobber(target, prop, src[prop]);
-                }
-            }
-        }
-    }
-}
-
-exports.buildIntoButDoNotClobber = function(objects, target) {
-    include(target, objects, false, false);
-};
-exports.buildIntoAndClobber = function(objects, target) {
-    include(target, objects, true, false);
-};
-exports.buildIntoAndMerge = function(objects, target) {
-    include(target, objects, true, true);
-};
-exports.recursiveMerge = recursiveMerge;
-exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
-
-});
-
-// file: lib/common/channel.js
-define("cordova/channel", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    nextGuid = 1;
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization, as well as for custom events thereafter.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
- * onNativeReady*              Internal event that indicates the Cordova native side is ready.
- * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
- * onCordovaInfoReady*         Internal event fired when device properties are available.
- * onCordovaConnectionReady*   Internal event fired when the connection property has been set.
- * onDeviceReady*              User event fired to indicate that Cordova is ready
- * onResume                    User event fired to indicate a start/resume lifecycle event
- * onPause                     User event fired to indicate a pause lifecycle event
- * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
- * All listeners that subscribe after the event is fired will be executed right away.
- *
- * The only Cordova events that user code should register for are:
- *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
- *      pause                 App has moved to background
- *      resume                App has returned to foreground
- *
- * Listeners can be registered as:
- *      document.addEventListener("deviceready", myDeviceReadyListener, false);
- *      document.addEventListener("resume", myResumeListener, false);
- *      document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- *      window.onload
- *      window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type  String the channel name
- */
-var Channel = function(type, sticky) {
-    this.type = type;
-    // Map of guid -> function.
-    this.handlers = {};
-    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
-    this.state = sticky ? 1 : 0;
-    // Used in sticky mode to remember args passed to fire().
-    this.fireArgs = null;
-    // Used by onHasSubscribersChange to know if there are any listeners.
-    this.numHandlers = 0;
-    // Function that is called when the first listener is subscribed, or when
-    // the last listener is unsubscribed.
-    this.onHasSubscribersChange = null;
-},
-    channel = {
-        /**
-         * Calls the provided function only after all of the channels specified
-         * have been fired. All channels must be sticky channels.
-         */
-        join: function(h, c) {
-            var len = c.length,
-                i = len,
-                f = function() {
-                    if (!(--i)) h();
-                };
-            for (var j=0; j<len; j++) {
-                if (c[j].state === 0) {
-                    throw Error('Can only use join with sticky channels.');
-                }
-                c[j].subscribe(f);
-            }
-            if (!len) h();
-        },
-        create: function(type) {
-            return channel[type] = new Channel(type, false);
-        },
-        createSticky: function(type) {
-            return channel[type] = new Channel(type, true);
-        },
-
-        /**
-         * cordova Channels that must fire before "deviceready" is fired.
-         */
-        deviceReadyChannelsArray: [],
-        deviceReadyChannelsMap: {},
-
-        /**
-         * Indicate that a feature needs to be initialized before it is ready to be used.
-         * This holds up Cordova's "deviceready" event until the feature has been initialized
-         * and Cordova.initComplete(feature) is called.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        waitForInitialization: function(feature) {
-            if (feature) {
-                var c = channel[feature] || this.createSticky(feature);
-                this.deviceReadyChannelsMap[feature] = c;
-                this.deviceReadyChannelsArray.push(c);
-            }
-        },
-
-        /**
-         * Indicate that initialization code has completed and the feature is ready to be used.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        initializationComplete: function(feature) {
-            var c = this.deviceReadyChannelsMap[feature];
-            if (c) {
-                c.fire();
-            }
-        }
-    };
-
-function forceFunction(f) {
-    if (typeof f != 'function') throw "Function required as first argument!";
-}
-
-/**
- * Subscribes the given function to the channel. Any time that
- * Channel.fire is called so too will the function.
- * Optionally specify an execution context for the function
- * and a guid that can be used to stop subscribing to the channel.
- * Returns the guid.
- */
-Channel.prototype.subscribe = function(f, c) {
-    // need a function to call
-    forceFunction(f);
-    if (this.state == 2) {
-        f.apply(c || this, this.fireArgs);
-        return;
-    }
-
-    var func = f,
-        guid = f.observer_guid;
-    if (typeof c == "object") { func = utils.close(c, f); }
-
-    if (!guid) {
-        // first time any channel has seen this subscriber
-        guid = '' + nextGuid++;
-    }
-    func.observer_guid = guid;
-    f.observer_guid = guid;
-
-    // Don't add the same handler more than once.
-    if (!this.handlers[guid]) {
-        this.handlers[guid] = func;
-        this.numHandlers++;
-        if (this.numHandlers == 1) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Unsubscribes the function with the given guid from the channel.
- */
-Channel.prototype.unsubscribe = function(f) {
-    // need a function to unsubscribe
-    forceFunction(f);
-
-    var guid = f.observer_guid,
-        handler = this.handlers[guid];
-    if (handler) {
-        delete this.handlers[guid];
-        this.numHandlers--;
-        if (this.numHandlers === 0) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Calls all functions subscribed to this channel.
- */
-Channel.prototype.fire = function(e) {
-    var fail = false,
-        fireArgs = Array.prototype.slice.call(arguments);
-    // Apply stickiness.
-    if (this.state == 1) {
-        this.state = 2;
-        this.fireArgs = fireArgs;
-    }
-    if (this.numHandlers) {
-        // Copy the values first so that it is safe to modify it from within
-        // callbacks.
-        var toCall = [];
-        for (var item in this.handlers) {
-            toCall.push(this.handlers[item]);
-        }
-        for (var i = 0; i < toCall.length; ++i) {
-            toCall[i].apply(this, fireArgs);
-        }
-        if (this.state == 2 && this.numHandlers) {
-            this.numHandlers = 0;
-            this.handlers = {};
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-
-// defining them here so they are ready super fast!
-// DOM event that is received when the web page is loaded and parsed.
-channel.createSticky('onDOMContentLoaded');
-
-// Event to indicate the Cordova native side is ready.
-channel.createSticky('onNativeReady');
-
-// Event to indicate that all Cordova JavaScript objects have been created
-// and it's time to run plugin constructors.
-channel.createSticky('onCordovaReady');
-
-// Event to indicate that device properties are available
-channel.createSticky('onCordovaInfoReady');
-
-// Event to indicate that the connection property has been set.
-channel.createSticky('onCordovaConnectionReady');
-
-// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-channel.createSticky('onPluginsReady');
-
-// Event to indicate that Cordova is ready
-channel.createSticky('onDeviceReady');
-
-// Event to indicate a resume lifecycle event
-channel.create('onResume');
-
-// Event to indicate a pause lifecycle event
-channel.create('onPause');
-
-// Event to indicate a destroy lifecycle event
-channel.createSticky('onDestroy');
-
-// Channels that must fire before "deviceready" is fired.
-channel.waitForInitialization('onCordovaReady');
-channel.waitForInitialization('onCordovaConnectionReady');
-channel.waitForInitialization('onDOMContentLoaded');
-
-module.exports = channel;
-
-});
-
-// file: lib/common/commandProxy.js
-define("cordova/commandProxy", function(require, exports, module) {
-
-
-// internal map of proxy function
-var CommandProxyMap = {};
-
-module.exports = {
-
-    // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
-    add:function(id,proxyObj) {
-        console.log("adding proxy for " + id);
-        CommandProxyMap[id] = proxyObj;
-        return proxyObj;
-    },
-
-    // cordova.commandProxy.remove("Accelerometer");
-    remove:function(id) {
-        var proxy = CommandProxyMap[id];
-        delete CommandProxyMap[id];
-        CommandProxyMap[id] = null;
-        return proxy;
-    },
-
-    get:function(service,action) {
-        return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
-    }
-};
-});
-
-// file: lib/windowsphone/exec.js
-define("cordova/exec", function(require, exports, module) {
-
-var cordova = require('cordova');
-
-/**
- * Execute a cordova command.  It is up to the native side whether this action
- * is synchronous or asynchronous.  The native side can return:
- *      Synchronous: PluginResult object as a JSON string
- *      Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success    The success callback
- * @param {Function} fail       The fail callback
- * @param {String} service      The name of the service to use
- * @param {String} action       Action to be run in cordova
- * @param {String[]} [args]     Zero or more arguments to pass to the method
-
- */
-
-module.exports = function(success, fail, service, action, args) {
-
-    var callbackId = service + cordova.callbackId++;
-    if (typeof success == "function" || typeof fail == "function") {
-        cordova.callbacks[callbackId] = {success:success, fail:fail};
-    }
-    // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
-    for(var n = 0; n < args.length; n++)
-    {
-        if(typeof args[n] !== "string")
-        {
-            args[n] = JSON.stringify(args[n]);
-        }
-    }
-    var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
-    // pass it on to Notify
-    try {
-        if(window.external) {
-            window.external.Notify(command);
-        }
-        else {
-            console.log("window.external not available :: command=" + command);
-        }
-    }
-    catch(e) {
-        console.log("Exception calling native with command :: " + command + " :: exception=" + e);
-    }
-};
-
-
-});
-
-// file: lib/common/modulemapper.js
-define("cordova/modulemapper", function(require, exports, module) {
-
-var builder = require('cordova/builder'),
-    moduleMap = define.moduleMap,
-    symbolList,
-    deprecationMap;
-
-exports.reset = function() {
-    symbolList = [];
-    deprecationMap = {};
-};
-
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
-    if (!(moduleName in moduleMap)) {
-        throw new Error('Module ' + moduleName + ' does not exist.');
-    }
-    symbolList.push(strategy, moduleName, symbolPath);
-    if (opt_deprecationMessage) {
-        deprecationMap[symbolPath] = opt_deprecationMessage;
-    }
-}
-
-// Note: Android 2.3 does have Function.bind().
-exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-function prepareNamespace(symbolPath, context) {
-    if (!symbolPath) {
-        return context;
-    }
-    var parts = symbolPath.split('.');
-    var cur = context;
-    for (var i = 0, part; part = parts[i]; ++i) {
-        cur = cur[part] = cur[part] || {};
-    }
-    return cur;
-}
-
-exports.mapModules = function(context) {
-    var origSymbols = {};
-    context.CDV_origSymbols = origSymbols;
-    for (var i = 0, len = symbolList.length; i < len; i += 3) {
-        var strategy = symbolList[i];
-        var moduleName = symbolList[i + 1];
-        var symbolPath = symbolList[i + 2];
-        var lastDot = symbolPath.lastIndexOf('.');
-        var namespace = symbolPath.substr(0, lastDot);
-        var lastName = symbolPath.substr(lastDot + 1);
-
-        var module = require(moduleName);
-        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
-        var parentObj = prepareNamespace(namespace, context);
-        var target = parentObj[lastName];
-
-        if (strategy == 'm' && target) {
-            builder.recursiveMerge(target, module);
-        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
-            if (!(symbolPath in origSymbols)) {
-                origSymbols[symbolPath] = target;
-            }
-            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
-        }
-    }
-};
-
-exports.getOriginalSymbol = function(context, symbolPath) {
-    var origSymbols = context.CDV_origSymbols;
-    if (origSymbols && (symbolPath in origSymbols)) {
-        return origSymbols[symbolPath];
-    }
-    var parts = symbolPath.split('.');
-    var obj = context;
-    for (var i = 0; i < parts.length; ++i) {
-        obj = obj && obj[parts[i]];
-    }
-    return obj;
-};
-
-exports.loadMatchingModules = function(matchingRegExp) {
-    for (var k in moduleMap) {
-        if (matchingRegExp.exec(k)) {
-            require(k);
-        }
-    }
-};
-
-exports.reset();
-
-
-});
-
-// file: lib/windowsphone/platform.js
-define("cordova/platform", function(require, exports, module) {
-
-var cordova = require('cordova'),
-      exec = require('cordova/exec');
-
-module.exports = {
-    id: "windowsphone",
-    initialize:function() {
-        var modulemapper = require('cordova/modulemapper');
-
-        modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
-
-        modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
-
-        modulemapper.mapModules(window);
-
-        // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
-        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
-        backButtonChannel.onHasSubscribersChange = function() {
-            exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
-        };
-    }
-};
-
-});
-
-// file: lib/common/plugin/Acceleration.js
-define("cordova/plugin/Acceleration", function(require, exports, module) {
-
-var Acceleration = function(x, y, z, timestamp) {
-    this.x = x;
-    this.y = y;
-    this.z = z;
-    this.timestamp = timestamp || (new Date()).getTime();
-};
-
-module.exports = Acceleration;
-
-});
-
-// file: lib/common/plugin/Camera.js
-define("cordova/plugin/Camera", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    Camera = require('cordova/plugin/CameraConstants'),
-    CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
-
-var cameraExport = {};
-
-// Tack on the Camera Constants to the base camera plugin.
-for (var key in Camera) {
-    cameraExport[key] = Camera[key];
-}
-
-/**
- * Gets a picture from source defined by "options.sourceType", and returns the
- * image as defined by the "options.destinationType" option.
-
- * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
- *
- * @param {Function} successCallback
- * @param {Function} errorCallback
- * @param {Object} options
- */
-cameraExport.getPicture = function(successCallback, errorCallback, options) {
-    argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
-    options = options || {};
-    var getValue = argscheck.getValue;
-
-    var quality = getValue(options.quality, 50);
-    var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
-    var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
-    var targetWidth = getValue(options.targetWidth, -1);
-    var targetHeight = getValue(options.targetHeight, -1);
-    var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
-    var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
-    var allowEdit = !!options.allowEdit;
-    var correctOrientation = !!options.correctOrientation;
-    var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
-    var popoverOptions = getValue(options.popoverOptions, null);
-    var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
-
-    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
-                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
-
-    exec(successCallback, errorCallback, "Camera", "takePicture", args);
-    return new CameraPopoverHandle();
-};
-
-cameraExport.cleanup = function(successCallback, errorCallback) {
-    exec(successCallback, errorCallback, "Camera", "cleanup", []);
-};
-
-module.exports = cameraExport;
-
-});
-
-// file: lib/common/plugin/CameraConstants.js
-define("cordova/plugin/CameraConstants", function(require, exports, module) {
-
-module.exports = {
-  DestinationType:{
-    DATA_URL: 0,         // Return base64 encoded string
-    FILE_URI: 1,         // Return file uri (content://media/external/images/media/2 for Android)
-    NATIVE_URI: 2        // Return native uri (eg. asset-library://... for iOS)
-  },
-  EncodingType:{
-    JPEG: 0,             // Return JPEG encoded image
-    PNG: 1               // Return PNG encoded image
-  },
-  MediaType:{
-    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
-    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL
-    ALLMEDIA : 2         // allow selection from all media types
-  },
-  PictureSourceType:{
-    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
-    CAMERA : 1,          // Take picture from camera
-    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
-  },
-  PopoverArrowDirection:{
-      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
-      ARROW_DOWN : 2,
-      ARROW_LEFT : 4,
-      ARROW_RIGHT : 8,
-      ARROW_ANY : 15
-  },
-  Direction:{
-      BACK: 0,
-      FRONT: 1
-  }
-};
-
-});
-
-// file: lib/common/plugin/CameraPopoverHandle.js
-define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-/**
- * A handle to an image picker popover.
- */
-var CameraPopoverHandle = function() {
-    this.setPosition = function(popoverOptions) {
-        console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
-    };
-};
-
-module.exports = CameraPopoverHandle;
-
-});
-
-// file: lib/common/plugin/CameraPopoverOptions.js
-define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
-
-var Camera = require('cordova/plugin/CameraConstants');
-
-/**
- * Encapsulates options for iOS Popover image picker
- */
-var CameraPopoverOptions = function(x,y,width,height,arrowDir){
-    // information of rectangle that popover should be anchored to
-    this.x = x || 0;
-    this.y = y || 32;
-    this.width = width || 320;
-    this.height = height || 480;
-    // The direction of the popover arrow
-    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
-};
-
-module.exports = CameraPopoverOptions;
-
-});
-
-// file: lib/common/plugin/CaptureAudioOptions.js
-define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all audio capture operation configuration options.
- */
-var CaptureAudioOptions = function(){
-    // Upper limit of sound clips user can record. Value must be equal or greater than 1.
-    this.limit = 1;
-    // Maximum duration of a single sound clip in seconds.
-    this.duration = 0;
-};
-
-module.exports = CaptureAudioOptions;
-
-});
-
-// file: lib/common/plugin/CaptureError.js
-define("cordova/plugin/CaptureError", function(require, exports, module) {
-
-/**
- * The CaptureError interface encapsulates all errors in the Capture API.
- */
-var CaptureError = function(c) {
-   this.code = c || null;
-};
-
-// Camera or microphone failed to capture image or sound.
-CaptureError.CAPTURE_INTERNAL_ERR = 0;
-// Camera application or audio capture application is currently serving other capture request.
-CaptureError.CAPTURE_APPLICATION_BUSY = 1;
-// Invalid use of the API (e.g. limit parameter has value less than one).
-CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
-// User exited camera application or audio capture application before capturing anything.
-CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
-// The requested capture operation is not supported.
-CaptureError.CAPTURE_NOT_SUPPORTED = 20;
-
-module.exports = CaptureError;
-
-});
-
-// file: lib/common/plugin/CaptureImageOptions.js
-define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all image capture operation configuration options.
- */
-var CaptureImageOptions = function(){
-    // Upper limit of images user can take. Value must be equal or greater than 1.
-    this.limit = 1;
-};
-
-module.exports = CaptureImageOptions;
-
-});
-
-// file: lib/common/plugin/CaptureVideoOptions.js
-define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
-
-/**
- * Encapsulates all video capture operation configuration options.
- */
-var CaptureVideoOptions = function(){
-    // Upper limit of videos user can record. Value must be equal or greater than 1.
-    this.limit = 1;
-    // Maximum duration of a single video clip in seconds.
-    this.duration = 0;
-};
-
-module.exports = CaptureVideoOptions;
-
-});
-
-// file: lib/common/plugin/CompassError.js
-define("cordova/plugin/CompassError", function(require, exports, module) {
-
-/**
- *  CompassError.
- *  An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var CompassError = function(err) {
-    this.code = (err !== undefined ? err : null);
-};
-
-CompassError.COMPASS_INTERNAL_ERR = 0;
-CompassError.COMPASS_NOT_SUPPORTED = 20;
-
-module.exports = CompassError;
-
-});
-
-// file: lib/common/plugin/CompassHeading.js
-define("cordova/plugin/CompassHeading", function(require, exports, module) {
-
-var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
-  this.magneticHeading = magneticHeading;
-  this.trueHeading = trueHeading;
-  this.headingAccuracy = headingAccuracy;
-  this.timestamp = timestamp || new Date().getTime();
-};
-
-module.exports = CompassHeading;
-
-});
-
-// file: lib/common/plugin/ConfigurationData.js
-define("cordova/plugin/ConfigurationData", function(require, exports, module) {
-
-/**
- * Encapsulates a set of parameters that the capture device supports.
- */
-function ConfigurationData() {
-    // The ASCII-encoded string in lower case representing the media type.
-    this.type = null;
-    // The height attribute represents height of the image or video in pixels.
-    // In the case of a sound clip this attribute has value 0.
-    this.height = 0;
-    // The width attribute represents width of the image or video in pixels.
-    // In the case of a sound clip this attribute has value 0
-    this.width = 0;
-}
-
-module.exports = ConfigurationData;
-
-});
-
-// file: lib/common/plugin/Connection.js
-define("cordova/plugin/Connection", function(require, exports, module) {
-
-/**
- * Network status
- */
-module.exports = {
-        UNKNOWN: "unknown",
-        ETHERNET: "ethernet",
-        WIFI: "wifi",
-        CELL_2G: "2g",
-        CELL_3G: "3g",
-        CELL_4G: "4g",
-        CELL:"cellular",
-        NONE: "none"
-};
-
-});
-
-// file: lib/common/plugin/Contact.js
-define("cordova/plugin/Contact", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    ContactError = require('cordova/plugin/ContactError'),
-    utils = require('cordova/utils');
-
-/**
-* Converts primitives into Complex Object
-* Currently only used for Date fields
-*/
-function convertIn(contact) {
-    var value = contact.birthday;
-    try {
-      contact.birthday = new Date(parseFloat(value));
-    } catch (exception){
-      console.log("Cordova Contact convertIn error: exception creating date.");
-    }
-    return contact;
-}
-
-/**
-* Converts Complex objects into primitives
-* Only conversion at present is for Dates.
-**/
-
-function convertOut(contact) {
-    var value = contact.birthday;
-    if (value !== null) {
-        // try to make it a Date object if it is not already
-        if (!utils.isDate(value)){
-            try {
-                value = new Date(value);
-            } catch(exception){
-                value = null;
-            }
-        }
-        if (utils.isDate(value)){
-            value = value.valueOf(); // convert to milliseconds
-        }
-        contact.birthday = value;
-    }
-    return contact;
-}
-
-/**
-* Contains information about a single contact.
-* @constructor
-* @param {DOMString} id unique identifier
-* @param {DOMString} displayName
-* @param {ContactName} name
-* @param {DOMString} nickname
-* @param {Array.<ContactField>} phoneNumbers array of phone numbers
-* @param {Array.<ContactField>} emails array of email addresses
-* @param {Array.<ContactAddress>} addresses array of addresses
-* @param {Array.<ContactField>} ims instant messaging user ids
-* @param {Array.<ContactOrganization>} organizations
-* @param {DOMString} birthday contact's birthday
-* @param {DOMString} note user notes about contact
-* @param {Array.<ContactField>} photos
-* @param {Array.<ContactField>} categories
-* @param {Array.<ContactField>} urls contact's web sites
-*/
-var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
-    ims, organizations, birthday, note, photos, categories, urls) {
-    this.id = id || null;
-    this.rawId = null;
-    this.displayName = displayName || null;
-    this.name = name || null; // ContactName
-    this.nickname = nickname || null;
-    this.phoneNumbers = phoneNumbers || null; // ContactField[]
-    this.emails = emails || null; // ContactField[]
-    this.addresses = addresses || null; // ContactAddress[]
-    this.ims = ims || null; // ContactField[]
-    this.organizations = organizations || null; // ContactOrganization[]
-    this.birthday = birthday || null;
-    this.note = note || null;
-    this.photos = photos || null; // ContactField[]
-    this.categories = categories || null; // ContactField[]
-    this.urls = urls || null; // ContactField[]
-};
-
-/**
-* Removes contact from device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.remove = function(successCB, errorCB) {
-    argscheck.checkArgs('FF', 'Contact.remove', arguments);
-    var fail = errorCB && function(code) {
-        errorCB(new ContactError(code));
-    };
-    if (this.id === null) {
-        fail(ContactError.UNKNOWN_ERROR);
-    }
-    else {
-        exec(successCB, fail, "Contacts", "remove", [this.id]);
-    }
-};
-
-/**
-* Creates a deep copy of this Contact.
-* With the contact ID set to null.
-* @return copy of this Contact
-*/
-Contact.prototype.clone = function() {
-    var clonedContact = utils.clone(this);
-    clonedContact.id = null;
-    clonedContact.rawId = null;
-
-    function nullIds(arr) {
-        if (arr) {
-            for (var i = 0; i < arr.length; ++i) {
-                arr[i].id = null;
-            }
-        }
-    }
-
-    // Loop through and clear out any id's in phones, emails, etc.
-    nullIds(clonedContact.phoneNumbers);
-    nullIds(clonedContact.emails);
-    nullIds(clonedContact.addresses);
-    nullIds(clonedContact.ims);
-    nullIds(clonedContact.organizations);
-    nullIds(clonedContact.categories);
-    nullIds(clonedContact.photos);
-    nullIds(clonedContact.urls);
-    return clonedContact;
-};
-
-/**
-* Persists contact to device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.save = function(successCB, errorCB) {
-    argscheck.checkArgs('FFO', 'Contact.save', arguments);
-    var fail = errorCB && function(code) {
-        errorCB(new ContactError(code));
-    };
-    var success = function(result) {
-        if (result) {
-            if (successCB) {
-                var fullContact = require('cordova/plugin/contacts').create(result);
-                successCB(convertIn(fullContact));
-            }
-        }
-        else {
-            // no Entry object returned
-            fail(ContactError.UNKNOWN_ERROR);
-        }
-    };
-    var dupContact = convertOut(utils.clone(this));
-    exec(success, fail, "Contacts", "save", [dupContact]);
-};
-
-
-module.exports = Contact;
-
-});
-
-// file: lib/common/plugin/ContactAddress.js
-define("cordova/plugin/ContactAddress", function(require, exports, module) {
-
-/**
-* Contact address.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code
-* @param formatted // NOTE: not a W3C standard
-* @param streetAddress
-* @param locality
-* @param region
-* @param postalCode
-* @param country
-*/
-
-var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
-    this.id = null;
-    this.pref = (typeof pref != 'undefined' ? pref : false);
-    this.type = type || null;
-    this.formatted = formatted || null;
-    this.streetAddress = streetAddress || null;
-    this.locality = locality || null;
-    this.region = region || null;
-    this.postalCode = postalCode || null;
-    this.country = country || null;
-};
-
-module.exports = ContactAddress;
-
-});
-
-// file: lib/common/plugin/ContactError.js
-define("cordova/plugin/ContactError", function(require, exports, module) {
-
-/**
- *  ContactError.
- *  An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var ContactError = function(err) {
-    this.code = (typeof err != 'undefined' ? err : null);
-};
-
-/**
- * Error codes
- */
-ContactError.UNKNOWN_ERROR = 0;
-ContactError.INVALID_ARGUMENT_ERROR = 1;
-ContactError.TIMEOUT_ERROR = 2;
-ContactError.PENDING_OPERATION_ERROR = 3;
-ContactError.IO_ERROR = 4;
-ContactError.NOT_SUPPORTED_ERROR = 5;
-ContactError.PERMISSION_DENIED_ERROR = 20;
-
-module.exports = ContactError;
-
-});
-
-// file: lib/common/plugin/ContactField.js
-define("cordova/plugin/ContactField", function(require, exports, module) {
-
-/**
-* Generic contact field.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param type
-* @param value
-* @param pref
-*/
-var ContactField = function(type, value, pref) {
-    this.id = null;
-    this.type = (type && type.toString()) || null;
-    this.value = (value && value.toString()) || null;
-    this.pref = (typeof pref != 'undefined' ? pref : false);
-};
-
-module.exports = ContactField;
-
-});
-
-// file: lib/common/plugin/ContactFindOptions.js
-define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
-
-/**
- * ContactFindOptions.
- * @constructor
- * @param filter used to match contacts against
- * @param multiple boolean used to determine if more than one contact should be returned
- */
-
-var ContactFindOptions = function(filter, multiple) {
-    this.filter = filter || '';
-    this.multiple = (typeof multiple != 'undefined' ? multiple : false);
-};
-
-module.exports = ContactFindOptions;
-
-});
-
-// file: lib/common/plugin/ContactName.js
-define("cordova/plugin/ContactName", function(require, exports, module) {
-
-/**
-* Contact name.
-* @constructor
-* @param formatted // NOTE: not part of W3C standard
-* @param familyName
-* @param givenName
-* @param middle
-* @param prefix
-* @param suffix
-*/
-var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
-    this.formatted = formatted || null;
-    this.familyName = familyName || null;
-    this.givenName = givenName || null;
-    this.middleName = middle || null;
-    this.honorificPrefix = prefix || null;
-    this.honorificSuffix = suffix || null;
-};
-
-module.exports = ContactName;
-
-});
-
-// file: lib/common/plugin/ContactOrganization.js
-define("cordova/plugin/ContactOrganization", function(require, exports, module) {
-
-/**
-* Contact organization.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param name
-* @param dept
-* @param title
-* @param startDate
-* @param endDate
-* @param location
-* @param desc
-*/
-
-var ContactOrganization = function(pref, type, name, dept, title) {
-    this.id = null;
-    this.pref = (typeof pref != 'undefined' ? pref : false);
-    this.type = type || null;
-    this.name = name || null;
-    this.department = dept || null;
-    this.title = title || null;
-};
-
-module.exports = ContactOrganization;
-
-});
-
-// file: lib/common/plugin/Coordinates.js
-define("cordova/plugin/Coordinates", function(require, exports, module) {
-
-/**
- * This class contains position information.
- * @param {Object} lat
- * @param {Object} lng
- * @param {Object} alt
- * @param {Object} acc
- * @param {Object} head
- * @param {Object} vel
- * @param {Object} altacc
- * @constructor
- */
-var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
-    /**
-     * The latitude of the position.
-     */
-    this.latitude = lat;
-    /**
-     * The longitude of the position,
-     */
-    this.longitude = lng;
-    /**
-     * The accuracy of the position.
-     */
-    this.accuracy = acc;
-    /**
-     * The altitude of the position.
-     */
-    this.altitude = (alt !== undefined ? alt : null);
-    /**
-     * The direction the device is moving at the position.
-     */
-    this.heading = (head !== undefined ? head : null);
-    /**
-     * The velocity with which the device is moving at the position.
-     */
-    this.speed = (vel !== undefined ? vel : null);
-
-    if (this.speed === 0 || this.speed === null) {
-        this.heading = NaN;
-    }
-
-    /**
-     * The altitude accuracy of the position.
-     */
-    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
-};
-
-module.exports = Coordinates;
-
-});
-
-// file: lib/common/plugin/DirectoryEntry.js
-define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    Entry = require('cordova/plugin/Entry'),
-    FileError = require('cordova/plugin/FileError'),
-    DirectoryReader = require('cordova/plugin/DirectoryReader');
-
-/**
- * An interface representing a directory on the file system.
- *
- * {boolean} isFile always false (readonly)
- * {boolean} isDirectory always true (readonly)
- * {DOMString} name of the directory, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the directory (readonly)
- * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
- */
-var DirectoryEntry = function(name, fullPath) {
-     DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
-};
-
-utils.extend(DirectoryEntry, Entry);
-
-/**
- * Creates a new DirectoryReader to read entries from this directory
- */
-DirectoryEntry.prototype.createReader = function() {
-    return new DirectoryReader(this.fullPath);
-};
-
-/**
- * Creates or looks up a directory
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
- * @param {Flags} options to create or exclusively create the directory
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
-    argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
-    var win = successCallback && function(result) {
-        var entry = new DirectoryEntry(result.name, result.fullPath);
-        successCallback(entry);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
-};
-
-/**
- * Deletes a directory and all of it's contents
- *
- * @param {Function} successCallback is called with no parameters
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
-    argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
-};
-
-/**
- * Creates or looks up a file
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
- * @param {Flags} options to create or exclusively create the file
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
-    argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
-    var win = successCallback && function(result) {
-        var FileEntry = require('cordova/plugin/FileEntry');
-        var entry = new FileEntry(result.name, result.fullPath);
-        successCallback(entry);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
-};
-
-module.exports = DirectoryEntry;
-
-});
-
-// file: lib/common/plugin/DirectoryReader.js
-define("cordova/plugin/DirectoryReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    FileError = require('cordova/plugin/FileError') ;
-
-/**
- * An interface that lists the files and directories in a directory.
- */
-function DirectoryReader(path) {
-    this.path = path || null;
-}
-
-/**
- * Returns a list of entries from a directory.
- *
- * @param {Function} successCallback is called with a list of entries
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
-    var win = typeof successCallback !== 'function' ? null : function(result) {
-        var retVal = [];
-        for (var i=0; i<result.length; i++) {
-            var entry = null;
-            if (result[i].isDirectory) {
-                entry = new (require('cordova/plugin/DirectoryEntry'))();
-            }
-            else if (result[i].isFile) {
-                entry = new (require('cordova/plugin/FileEntry'))();
-            }
-            entry.isDirectory = result[i].isDirectory;
-            entry.isFile = result[i].isFile;
-            entry.name = result[i].name;
-            entry.fullPath = result[i].fullPath;
-            retVal.push(entry);
-        }
-        successCallback(retVal);
-    };
-    var fail = typeof errorCallback !== 'function' ? null : function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "readEntries", [this.path]);
-};
-
-module.exports = DirectoryReader;
-
-});
-
-// file: lib/common/plugin/Entry.js
-define("cordova/plugin/Entry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    FileError = require('cordova/plugin/FileError'),
-    Metadata = require('cordova/plugin/Metadata');
-
-/**
- * Represents a file or directory on the local file system.
- *
- * @param isFile
- *            {boolean} true if Entry is a file (readonly)
- * @param isDirectory
- *            {boolean} true if Entry is a directory (readonly)
- * @param name
- *            {DOMString} name of the file or directory, excluding the path
- *            leading to it (readonly)
- * @param fullPath
- *            {DOMString} the absolute full path to the file or directory
- *            (readonly)
- */
-function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
-    this.isFile = !!isFile;
-    this.isDirectory = !!isDirectory;
-    this.name = name || '';
-    this.fullPath = fullPath || '';
-    this.filesystem = fileSystem || null;
-}
-
-/**
- * Look up the metadata of the entry.
- *
- * @param successCallback
- *            {Function} is called with a Metadata object
- * @param errorCallback
- *            {Function} is called with a FileError
- */
-Entry.prototype.getMetadata = function(successCallback, errorCallback) {
-    argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
-    var success = successCallback && function(lastModified) {
-        var metadata = new Metadata(lastModified);
-        successCallback(metadata);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-
-    exec(success, fail, "File", "getMetadata", [this.fullPath]);
-};
-
-/**
- * Set the metadata of the entry.
- *
- * @param successCallback
- *            {Function} is called with a Metadata object
- * @param errorCallback
- *            {Function} is called with a FileError
- * @param metadataObject
- *            {Object} keys and values to set
- */
-Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
-    argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
-    exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
-};
-
-/**
- * Move a file or directory to a new location.
- *
- * @param parent
- *            {DirectoryEntry} the directory to which to move this entry
- * @param newName
- *            {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- *            {Function} called with the new DirectoryEntry object
- * @param errorCallback
- *            {Function} called with a FileError
- */
-Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
-    argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    // source path
-    var srcPath = this.fullPath,
-        // entry name
-        name = newName || this.name,
-        success = function(entry) {
-            if (entry) {
-                if (successCallback) {
-                    // create appropriate Entry object
-                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
-                    successCallback(result);
-                }
-            }
-            else {
-                // no Entry object returned
-                fail && fail(FileError.NOT_FOUND_ERR);
-            }
-        };
-
-    // copy
-    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Copy a directory to a different location.
- *
- * @param parent
- *            {DirectoryEntry} the directory to which to copy the entry
- * @param newName
- *            {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- *            {Function} called with the new Entry object
- * @param errorCallback
- *            {Function} called with a FileError
- */
-Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
-    argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-
-        // source path
-    var srcPath = this.fullPath,
-        // entry name
-        name = newName || this.name,
-        // success callback
-        success = function(entry) {
-            if (entry) {
-                if (successCallback) {
-                    // create appropriate Entry object
-                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
-                    successCallback(result);
-                }
-            }
-            else {
-                // no Entry object returned
-                fail && fail(FileError.NOT_FOUND_ERR);
-            }
-        };
-
-    // copy
-    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Return a URL that can be used to identify this entry.
- */
-Entry.prototype.toURL = function() {
-    // fullPath attribute contains the full URL
-    return this.fullPath;
-};
-
-/**
- * Returns a URI that can be used to identify this entry.
- *
- * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
- * @return uri
- */
-Entry.prototype.toURI = function(mimeType) {
-    console.log("DEPRECATED: Update your code to use 'toURL'");
-    // fullPath attribute contains the full URI
-    return this.toURL();
-};
-
-/**
- * Remove a file or directory. It is an error to attempt to delete a
- * directory that is not empty. It is an error to attempt to delete a
- * root directory of a file system.
- *
- * @param successCallback {Function} called with no parameters
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.remove = function(successCallback, errorCallback) {
-    argscheck.checkArgs('FF', 'Entry.remove', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(successCallback, fail, "File", "remove", [this.fullPath]);
-};
-
-/**
- * Look up the parent DirectoryEntry of this entry.
- *
- * @param successCallback {Function} called with the parent DirectoryEntry object
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.getParent = function(successCallback, errorCallback) {
-    argscheck.checkArgs('FF', 'Entry.getParent', arguments);
-    var win = successCallback && function(result) {
-        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-        var entry = new DirectoryEntry(result.name, result.fullPath);
-        successCallback(entry);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "getParent", [this.fullPath]);
-};
-
-module.exports = Entry;
-
-});
-
-// file: lib/common/plugin/File.js
-define("cordova/plugin/File", function(require, exports, module) {
-
-/**
- * Constructor.
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-
-var File = function(name, fullPath, type, lastModifiedDate, size){
-    this.name = name || '';
-    this.fullPath = fullPath || null;
-    this.type = type || null;
-    this.lastModifiedDate = lastModifiedDate || null;
-    this.size = size || 0;
-
-    // These store the absolute start and end for slicing the file.
-    this.start = 0;
-    this.end = this.size;
-};
-
-/**
- * Returns a "slice" of the file. Since Cordova Files don't contain the actual
- * content, this really returns a File with adjusted start and end.
- * Slices of slices are supported.
- * start {Number} The index at which to start the slice (inclusive).
- * end {Number} The index at which to end the slice (exclusive).
- */
-File.prototype.slice = function(start, end) {
-    var size = this.end - this.start;
-    var newStart = 0;
-    var newEnd = size;
-    if (arguments.length) {
-        if (start < 0) {
-            newStart = Math.max(size + start, 0);
-        } else {
-            newStart = Math.min(size, start);
-        }
-    }
-
-    if (arguments.length >= 2) {
-        if (end < 0) {
-            newEnd = Math.max(size + end, 0);
-        } else {
-            newEnd = Math.min(end, size);
-        }
-    }
-
-    var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
-    newFile.start = this.start + newStart;
-    newFile.end = this.start + newEnd;
-    return newFile;
-};
-
-
-module.exports = File;
-
-});
-
-// file: lib/common/plugin/FileEntry.js
-define("cordova/plugin/FileEntry", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    Entry = require('cordova/plugin/Entry'),
-    FileWriter = require('cordova/plugin/FileWriter'),
-    File = require('cordova/plugin/File'),
-    FileError = require('cordova/plugin/FileError');
-
-/**
- * An interface representing a file on the file system.
- *
- * {boolean} isFile always true (readonly)
- * {boolean} isDirectory always false (readonly)
- * {DOMString} name of the file, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the file (readonly)
- * {FileSystem} filesystem on which the file resides (readonly)
- */
-var FileEntry = function(name, fullPath) {
-     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
-};
-
-utils.extend(FileEntry, Entry);
-
-/**
- * Creates a new FileWriter associated with the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new FileWriter
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
-    this.file(function(filePointer) {
-        var writer = new FileWriter(filePointer);
-
-        if (writer.fileName === null || writer.fileName === "") {
-            errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
-        } else {
-            successCallback && successCallback(writer);
-        }
-    }, errorCallback);
-};
-
-/**
- * Returns a File that represents the current state of the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new File object
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.file = function(successCallback, errorCallback) {
-    var win = successCallback && function(f) {
-        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
-        successCallback(file);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
-};
-
-
-module.exports = FileEntry;
-
-});
-
-// file: lib/common/plugin/FileError.js
-define("cordova/plugin/FileError", function(require, exports, module) {
-
-/**
- * FileError
- */
-function FileError(error) {
-  this.code = error || null;
-}
-
-// File error codes
-// Found in DOMException
-FileError.NOT_FOUND_ERR = 1;
-FileError.SECURITY_ERR = 2;
-FileError.ABORT_ERR = 3;
-
-// Added by File API specification
-FileError.NOT_READABLE_ERR = 4;
-FileError.ENCODING_ERR = 5;
-FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
-FileError.INVALID_STATE_ERR = 7;
-FileError.SYNTAX_ERR = 8;
-FileError.INVALID_MODIFICATION_ERR = 9;
-FileError.QUOTA_EXCEEDED_ERR = 10;
-FileError.TYPE_MISMATCH_ERR = 11;
-FileError.PATH_EXISTS_ERR = 12;
-
-module.exports = FileError;
-
-});
-
-// file: lib/common/plugin/FileReader.js
-define("cordova/plugin/FileReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    modulemapper = require('cordova/modulemapper'),
-    utils = require('cordova/utils'),
-    File = require('cordova/plugin/File'),
-    FileError = require('cordova/plugin/FileError'),
-    ProgressEvent = require('cordova/plugin/ProgressEvent'),
-    origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
-
-/**
- * This class reads the mobile device file system.
- *
- * For Android:
- *      The root directory is the root of the file system.
- *      To read from the SD card, the file name is "sdcard/my_file.txt"
- * @constructor
- */
-var FileReader = function() {
-    this._readyState = 0;
-    this._error = null;
-    this._result = null;
-    this._fileName = '';
-    this._realReader = origFileReader ? new origFileReader() : {};
-};
-
-// States
-FileReader.EMPTY = 0;
-FileReader.LOADING = 1;
-FileReader.DONE = 2;
-
-utils.defineGetter(FileReader.prototype, 'readyState', function() {
-    return this._fileName ? this._readyState : this._realReader.readyState;
-});
-
-utils.defineGetter(FileReader.prototype, 'error', function() {
-    return this._fileName ? this._error: this._realReader.error;
-});
-
-utils.defineGetter(FileReader.prototype, 'result', function() {
-    return this._fileName ? this._result: this._realReader.result;
-});
-
-function defineEvent(eventName) {
-    utils.defineGetterSetter(FileReader.prototype, eventName, function() {
-        return this._realReader[eventName] || null;
-    }, function(value) {
-        this._realReader[eventName] = value;
-    });
-}
-defineEvent('onloadstart');    // When the read starts.
-defineEvent('onprogress');     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
-defineEvent('onload');         // When the read has successfully completed.
-defineEvent('onerror');        // When the read has failed (see errors).
-defineEvent('onloadend');      // When the request has completed (either in success or failure).
-defineEvent('onabort');        // When the read has been aborted. For instance, by invoking the abort() method.
-
-function initRead(reader, file) {
-    // Already loading something
-    if (reader.readyState == FileReader.LOADING) {
-      throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    reader._result = null;
-    reader._error = null;
-    reader._readyState = FileReader.LOADING;
-
-    if (typeof file.fullPath == 'string') {
-        reader._fileName = file.fullPath;
-    } else {
-        reader._fileName = '';
-        return true;
-    }
-
-    reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
-}
-
-/**
- * Abort reading file.
- */
-FileReader.prototype.abort = function() {
-    if (origFileReader && !this._fileName) {
-        return this._realReader.abort();
-    }
-    this._result = null;
-
-    if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
-      return;
-    }
-
-    this._readyState = FileReader.DONE;
-
-    // If abort callback
-    if (typeof this.onabort === 'function') {
-        this.onabort(new ProgressEvent('abort', {target:this}));
-    }
-    // If load end callback
-    if (typeof this.onloadend === 'function') {
-        this.onloadend(new ProgressEvent('loadend', {target:this}));
-    }
-};
-
-/**
- * Read text file.
- *
- * @param file          {File} File object containing file properties
- * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)
- */
-FileReader.prototype.readAsText = function(file, encoding) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsText(file, encoding);
-    }
-
-    // Default encoding is UTF-8
-    var enc = encoding ? encoding : "UTF-8";
-    var me = this;
-    var execArgs = [this._fileName, enc, file.start, file.end];
-
-    // Read file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // Save result
-            me._result = r;
-
-            // If onload callback
-            if (typeof me.onload === "function") {
-                me.onload(new ProgressEvent("load", {target:me}));
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            // null result
-            me._result = null;
-
-            // Save error
-            me._error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        }, "File", "readAsText", execArgs);
-};
-
-
-/**
- * Read file and return data as a base64 encoded data url.
- * A data url is of the form:
- *      data:[<mediatype>][;base64],<data>
- *
- * @param file          {File} File object containing file properties
- */
-FileReader.prototype.readAsDataURL = function(file) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsDataURL(file);
-    }
-
-    var me = this;
-    var execArgs = [this._fileName, file.start, file.end];
-
-    // Read file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            // Save result
-            me._result = r;
-
-            // If onload callback
-            if (typeof me.onload === "function") {
-                me.onload(new ProgressEvent("load", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            me._result = null;
-
-            // Save error
-            me._error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        }, "File", "readAsDataURL", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file          {File} File object containing file properties
- */
-FileReader.prototype.readAsBinaryString = function(file) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsBinaryString(file);
-    }
-
-    var me = this;
-    var execArgs = [this._fileName, file.start, file.end];
-
-    // Read file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            me._result = r;
-
-            // If onload callback
-            if (typeof me.onload === "function") {
-                me.onload(new ProgressEvent("load", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            me._result = null;
-
-            // Save error
-            me._error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        }, "File", "readAsBinaryString", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file          {File} File object containing file properties
- */
-FileReader.prototype.readAsArrayBuffer = function(file) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsArrayBuffer(file);
-    }
-
-    var me = this;
-    var execArgs = [this._fileName, file.start, file.end];
-
-    // Read file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            me._result = r;
-
-            // If onload callback
-            if (typeof me.onload === "function") {
-                me.onload(new ProgressEvent("load", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            me._result = null;
-
-            // Save error
-            me._error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        }, "File", "readAsArrayBuffer", execArgs);
-};
-
-module.exports = FileReader;
-
-});
-
-// file: lib/common/plugin/FileSystem.js
-define("cordova/plugin/FileSystem", function(require, exports, module) {
-
-var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-
-/**
- * An interface representing a file system
- *
- * @constructor
- * {DOMString} name the unique name of the file system (readonly)
- * {DirectoryEntry} root directory of the file system (readonly)
- */
-var FileSystem = function(name, root) {
-    this.name = name || null;
-    if (root) {
-        this.root = new DirectoryEntry(root.name, root.fullPath);
-    }
-};
-
-module.exports = FileSystem;
-
-});
-
-// file: lib/common/plugin/FileTransfer.js
-define("cordova/plugin/FileTransfer", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    FileTransferError = require('cordova/plugin/FileTransferError'),
-    ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-function newProgressEvent(result) {
-    var pe = new ProgressEvent();
-    pe.lengthComputable = result.lengthComputable;
-    pe.loaded = result.loaded;
-    pe.total = result.total;
-    return pe;
-}
-
-function getBasicAuthHeader(urlString) {
-    var header =  null;
-
-    if (window.btoa) {
-        // parse the url using the Location object
-        var url = document.createElement('a');
-        url.href = urlString;
-
-        var credentials = null;
-        var protocol = url.protocol + "//";
-        var origin = protocol + url.host;
-
-        // check whether there are the username:password credentials in the url
-        if (url.href.indexOf(origin) !== 0) { // credentials found
-            var atIndex = url.href.indexOf("@");
-            credentials = url.href.substring(protocol.length, atIndex);
-        }
-
-        if (credentials) {
-            var authHeader = "Authorization";
-            var authHeaderValue = "Basic " + window.btoa(credentials);
-
-            header = {
-                name : authHeader,
-                value : authHeaderValue
-            };
-        }
-    }
-
-    return header;
-}
-
-var idCounter = 0;
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {
-    this._id = ++idCounter;
-    this.onprogress = null; // optional callback
-};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String}           Full path of the file on the device
-* @param server {String}             URL of the server to receive the file
-* @param successCallback (Function}  Callback to be invoked when upload has completed
-* @param errorCallback {Function}    Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
-    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
-    // check for options
-    var fileKey = null;
-    var fileName = null;
-    var mimeType = null;
-    var params = null;
-    var chunkedMode = true;
-    var headers = null;
-    var httpMethod = null;
-    var basicAuthHeader = getBasicAuthHeader(server);
-    if (basicAuthHeader) {
-        options = options || {};
-        options.headers = options.headers || {};
-        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
-    }
-
-    if (options) {
-        fileKey = options.fileKey;
-        fileName = options.fileName;
-        mimeType = options.mimeType;
-        headers = options.headers;
-        httpMethod = options.httpMethod || "POST";
-        if (httpMethod.toUpperCase() == "PUT"){
-            httpMethod = "PUT";
-        } else {
-            httpMethod = "POST";
-        }
-        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
-            chunkedMode = options.chunkedMode;
-        }
-        if (options.params) {
-            params = options.params;
-        }
-        else {
-            params = {};
-        }
-    }
-
-    var fail = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
-        errorCallback(error);
-    };
-
-    var self = this;
-    var win = function(result) {
-        if (typeof result.lengthComputable != "undefined") {
-            if (self.onprogress) {
-                self.onprogress(newProgressEvent(result));
-            }
-        } else {
-            successCallback && successCallback(result);
-        }
-    };
-    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String}          URL of the server to receive the file
- * @param target {String}         Full path of the file on the device
- * @param successCallback (Function}  Callback to be invoked when upload has completed
- * @param errorCallback {Function}    Callback to be invoked upon error
- * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
- * @param options {FileDownloadOptions} Optional parameters such as headers
- */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
-    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
-    var self = this;
-
-    var basicAuthHeader = getBasicAuthHeader(source);
-    if (basicAuthHeader) {
-        options = options || {};
-        options.headers = options.headers || {};
-        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
-    }
-
-    var headers = null;
-    if (options) {
-        headers = options.headers || null;
-    }
-
-    var win = function(result) {
-        if (typeof result.lengthComputable != "undefined") {
-            if (self.onprogress) {
-                return self.onprogress(newProgressEvent(result));
-            }
-        } else if (successCallback) {
-            var entry = null;
-            if (result.isDirectory) {
-                entry = new (require('cordova/plugin/DirectoryEntry'))();
-            }
-            else if (result.isFile) {
-                entry = new (require('cordova/plugin/FileEntry'))();
-            }
-            entry.isDirectory = result.isDirectory;
-            entry.isFile = result.isFile;
-            entry.name = result.name;
-            entry.fullPath = result.fullPath;
-            successCallback(entry);
-        }
-    };
-
-    var fail = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
-        errorCallback(error);
-    };
-
-    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
-};
-
-/**
- * Aborts the ongoing file transfer on this object. The original error
- * callback for the file transfer will be called if necessary.
- */
-FileTransfer.prototype.abort = function() {
-    exec(null, null, 'FileTransfer', 'abort', [this._id]);
-};
-
-module.exports = FileTransfer;
-
-});
-
-// file: lib/common/plugin/FileTransferError.js
-define("cordova/plugin/FileTransferError", function(require, exports, module) {
-
-/**
- * FileTransferError
- * @constructor
- */
-var FileTransferError = function(code, source, target, status, body) {
-    this.code = code || null;
-    this.source = source || null;
-    this.target = target || null;
-    this.http_status = status || null;
-    this.body = body || null;
-};
-
-FileTransferError.FILE_NOT_FOUND_ERR = 1;
-FileTransferError.INVALID_URL_ERR = 2;
-FileTransferError.CONNECTION_ERR = 3;
-FileTransferError.ABORT_ERR = 4;
-
-module.exports = FileTransferError;
-
-});
-
-// file: lib/common/plugin/FileUploadOptions.js
-define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
-
-/**
- * Options to customize the HTTP request used to upload files.
- * @constructor
- * @param fileKey {String}   Name of file request parameter.
- * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
- * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
- * @param params {Object}    Object with key: value params to send to the server.
- * @param headers {Object}   Keys are header names, values are header values. Multiple
- *                           headers of the same name are not supported.
- */
-var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) {
-    this.fileKey = fileKey || null;
-    this.fileName = fileName || null;
-    this.mimeType = mimeType || null;
-    this.params = params || null;
-    this.headers = headers || null;
-    this.httpMethod = httpMethod || null;
-};
-
-module.exports = FileUploadOptions;
-
-});
-
-// file: lib/common/plugin/FileUploadResult.js
-define("cordova/plugin/FileUploadResult", function(require, exports, module) {
-
-/**
- * FileUploadResult
- * @constructor
- */
-var FileUploadResult = function() {
-    this.bytesSent = 0;
-    this.responseCode = null;
-    this.response = null;
-};
-
-module.exports = FileUploadResult;
-
-});
-
-// file: lib/common/plugin/FileWriter.js
-define("cordova/plugin/FileWriter", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    FileError = require('cordova/plugin/FileError'),
-    ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-/**
- * This class writes to the mobile device file system.
- *
- * For Android:
- *      The root directory is the root of the file system.
- *      To write to the SD card, the file name is "sdcard/my_file.txt"
- *
- * @constructor
- * @param file {File} File object containing file properties
- * @param append if true write to the end of the file, otherwise overwrite the file
- */
-var FileWriter = function(file) {
-    this.fileName = "";
-    this.length = 0;
-    if (file) {
-        this.fileName = file.fullPath || file;
-        this.length = file.size || 0;
-    }
-    // default is to write at the beginning of the file
-    this.position = 0;
-
-    this.readyState = 0; // EMPTY
-
-    this.result = null;
-
-    // Error
-    this.error = null;
-
-    // Event handlers
-    this.onwritestart = null;   // When writing starts
-    this.onprogress = null;     // While writing the file, and reporting partial file data
-    this.onwrite = null;        // When the write has successfully completed.
-    this.onwriteend = null;     // When the request has completed (either in success or failure).
-    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.
-    this.onerror = null;        // When the write has failed (see errors).
-};
-
-// States
-FileWriter.INIT = 0;
-FileWriter.WRITING = 1;
-FileWriter.DONE = 2;
-
-/**
- * Abort writing file.
- */
-FileWriter.prototype.abort = function() {
-    // check for invalid state
-    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {
-        throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    // set error
-    this.error = new FileError(FileError.ABORT_ERR);
-
-    this.readyState = FileWriter.DONE;
-
-    // If abort callback
-    if (typeof this.onabort === "function") {
-        this.onabort(new ProgressEvent("abort", {"target":this}));
-    }
-
-    // If write end callback
-    if (typeof this.onwriteend === "function") {
-        this.onwriteend(new ProgressEvent("writeend", {"target":this}));
-    }
-};
-
-/**
- * Writes data to the file
- *
- * @param data text or blob to be written
- */
-FileWriter.prototype.write = function(data) {
-
-    var isBinary = false;
-
-    // If we don't have Blob or ArrayBuffer support, don't bother.
-    if (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined') {
-
-        // Check to see if the incoming data is a blob
-        if (data instanceof Blob) {
-            var that=this;
-            var fileReader = new FileReader();
-            fileReader.onload = function() {
-                // Call this method again, with the arraybuffer as argument
-                FileWriter.prototype.write.call(that, this.result);
-            };
-            fileReader.readAsArrayBuffer(data);
-            return;
-        }
-
-        // Mark data type for safer transport over the binary bridge
-        isBinary = (data instanceof ArrayBuffer);
-    }
-
-    // Throw an exception if we are already writing a file
-    if (this.readyState === FileWriter.WRITING) {
-        throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    // WRITING state
-    this.readyState = FileWriter.WRITING;
-
-    var me = this;
-
-    // If onwritestart callback
-    if (typeof me.onwritestart === "function") {
-        me.onwritestart(new ProgressEvent("writestart", {"target":me}));
-    }
-
-    // Write file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me.readyState === FileWriter.DONE) {
-                return;
-            }
-
-            // position always increases by bytes written because file would be extended
-            me.position += r;
-            // The length of the file is now where we are done writing.
-
-            me.length = me.position;
-
-            // DONE state
-            me.readyState = FileWriter.DONE;
-
-            // If onwrite callback
-            if (typeof me.onwrite === "function") {
-                me.onwrite(new ProgressEvent("write", {"target":me}));
-            }
-
-            // If onwriteend callback
-            if (typeof me.onwriteend === "function") {
-                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me.readyState === FileWriter.DONE) {
-                return;
-            }
-
-            // DONE state
-            me.readyState = FileWriter.DONE;
-
-            // Save error
-            me.error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {"target":me}));
-            }
-
-            // If onwriteend callback
-            if (typeof me.onwriteend === "function") {
-                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
-            }
-        }, "File", "write", [this.fileName, data, this.position, isBinary]);
-};
-
-/**
- * Moves the file pointer to the location specified.
- *
- * If the offset is a negative number the position of the file
- * pointer is rewound.  If the offset is greater than the file
- * size the position is set to the end of the file.
- *
- * @param offset is the location to move the file pointer to.
- */
-FileWriter.prototype.seek = function(offset) {
-    // Throw an exception if we are already writing a file
-    if (this.readyState === FileWriter.WRITING) {
-        throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    if (!offset && offset !== 0) {
-        return;
-    }
-
-    // See back from end of file.
-    if (offset < 0) {
-        this.position = Math.max(offset + this.length, 0);
-    }
-    // Offset is bigger than file size so set position
-    // to the end of the file.
-    else if (offset > this.length) {
-        this.position = this.length;
-    }
-    // Offset is between 0 and file size so set the position
-    // to start writing.
-    else {
-        this.position = offset;
-    }
-};
-
-/**
- * Truncates the file to the size specified.
- *
- * @param size to chop the file at.
- */
-FileWriter.prototype.truncate = function(size) {
-    // Throw an exception if we are already writing a file
-    if (this.readyState === FileWriter.WRITING) {
-        throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    // WRITING state
-    this.readyState = FileWriter.WRITING;
-
-    var me = this;
-
-    // If onwritestart callback
-    if (typeof me.onwritestart === "function") {
-        me.onwritestart(new ProgressEvent("writestart", {"target":this}));
-    }
-
-    // Write file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me.readyState === FileWriter.DONE) {
-                return;
-            }
-
-            // DONE state
-            me.readyState = FileWriter.DONE;
-
-            // Update the length of the file
-            me.length = r;
-            me.position = Math.min(me.position, r);
-
-            // If onwrite callback
-            if (typeof me.onwrite === "function") {
-                me.onwrite(new ProgressEvent("write", {"target":me}));
-            }
-
-            // If onwriteend callback
-            if (typeof me.onwriteend === "function") {
-                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me.readyState === FileWriter.DONE) {
-                return;
-            }
-
-            // DONE state
-            me.readyState = FileWriter.DONE;
-
-            // Save error
-            me.error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {"target":me}));
-            }
-
-            // If onwriteend callback
-            if (typeof me.onwriteend === "function") {
-                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
-            }
-        }, "File", "truncate", [this.fileName, size]);
-};
-
-module.exports = FileWriter;
-
-});
-
-// file: lib/common/plugin/Flags.js
-define("cordova/plugin/Flags", function(require, exports, module) {
-
-/**
- * Supplies arguments to methods that lookup or create files and directories.
- *
- * @param create
- *            {boolean} file or directory if it doesn't exist
- * @param exclusive
- *            {boolean} used with create; if true the command will fail if
- *            target path exists
- */
-function Flags(create, exclusive) {
-    this.create = create || false;
-    this.exclusive = exclusive || false;
-}
-
-module.exports = Flags;
-
-});
-
-// file: lib/common/plugin/GlobalizationError.js
-define("cordova/plugin/GlobalizationError", function(require, exports, module) {
-
-
-/**
- * Globalization error object
- *
- * @constructor
- * @param code
- * @param message
- */
-var GlobalizationError = function(code, message) {
-    this.code = code || null;
-    this.message = message || '';
-};
-
-// Globalization error codes
-GlobalizationError.UNKNOWN_ERROR = 0;
-GlobalizationError.FORMATTING_ERROR = 1;
-GlobalizationError.PARSING_ERROR = 2;
-GlobalizationError.PATTERN_ERROR = 3;
-
-module.exports = GlobalizationError;
-
-});
-
-// file: lib/common/plugin/InAppBrowser.js
-define("cordova/plugin/InAppBrowser", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var channel = require('cordova/channel');
-var modulemapper = require('cordova/modulemapper');
-
-function InAppBrowser() {
-   this.channels = {
-        'loadstart': channel.create('loadstart'),
-        'loadstop' : channel.create('loadstop'),
-        'loaderror' : channel.create('loaderror'),
-        'exit' : channel.create('exit')
-   };
-}
-
-InAppBrowser.prototype = {
-    _eventHandler: function (event) {
-        if (event.type in this.channels) {
-            this.channels[event.type].fire(event);
-        }
-    },
-    close: function (eventname) {
-        exec(null, null, "InAppBrowser", "close", []);
-    },
-    show: function (eventname) {
-      exec(null, null, "InAppBrowser", "show", []);
-    },
-    addEventListener: function (eventname,f) {
-        if (eventname in this.channels) {
-            this.channels[eventname].subscribe(f);
-        }
-    },
-    removeEventListener: function(eventname, f) {
-        if (eventname in this.channels) {
-            this.channels[eventname].unsubscribe(f);
-        }
-    },
-
-    executeScript: function(injectDetails, cb) {
-        if (injectDetails.code) {
-            exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);
-        } else if (injectDetails.file) {
-            exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);
-        } else {
-            throw new Error('executeScript requires exactly one of code or file to be specified');
-        }
-    },
-
-    insertCSS: function(injectDetails, cb) {
-        if (injectDetails.code) {
-            exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);
-        } else if (injectDetails.file) {
-            exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);
-        } else {
-            throw new Error('insertCSS requires exactly one of code or file to be specified');
-        }
-    }
-};
-
-module.exports = function(strUrl, strWindowName, strWindowFeatures) {
-    var iab = new InAppBrowser();
-    var cb = function(eventname) {
-       iab._eventHandler(eventname);
-    };
-
-    // Don't catch calls that write to existing frames (e.g. named iframes).
-    if (window.frames && window.frames[strWindowName]) {
-        var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
-        return origOpenFunc.apply(window, arguments);
-    }
-
-    exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
-    return iab;
-};
-
-
-});
-
-// file: lib/common/plugin/LocalFileSystem.js
-define("cordova/plugin/LocalFileSystem", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-/**
- * Represents a local file system.
- */
-var LocalFileSystem = function() {
-
-};
-
-LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
-LocalFileSystem.PERSISTENT = 1; //persistent
-
-module.exports = LocalFileSystem;
-
-});
-
-// file: lib/common/plugin/Media.js
-define("cordova/plugin/Media", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec');
-
-var mediaObjects = {};
-
-/**
- * This class provides access to the device media, interfaces to both sound and video
- *
- * @constructor
- * @param src                   The file name or url to play
- * @param successCallback       The callback to be called when the file is done playing or recording.
- *                                  successCallback()
- * @param errorCallback         The callback to be called if there is an error.
- *                                  errorCallback(int errorCode) - OPTIONAL
- * @param statusCallback        The callback to be called when media status has changed.
- *                                  statusCallback(int statusCode) - OPTIONAL
- */
-var Media = function(src, successCallback, errorCallback, statusCallback) {
-    argscheck.checkArgs('SFFF', 'Media', arguments);
-    this.id = utils.createUUID();
-    mediaObjects[this.id] = this;
-    this.src = src;
-    this.successCallback = successCallback;
-    this.errorCallback = errorCallback;
-    this.statusCallback = statusCallback;
-    this._duration = -1;
-    this._position = -1;
-    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
-};
-
-// Media messages
-Media.MEDIA_STATE = 1;
-Media.MEDIA_DURATION = 2;
-Media.MEDIA_POSITION = 3;
-Media.MEDIA_ERROR = 9;
-
-// Media states
-Media.MEDIA_NONE = 0;
-Media.MEDIA_STARTING = 1;
-Media.MEDIA_RUNNING = 2;
-Media.MEDIA_PAUSED = 3;
-Media.MEDIA_STOPPED = 4;
-Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
-
-// "static" function to return existing objs.
-Media.get = function(id) {
-    return mediaObjects[id];
-};
-
-/**
- * Start or resume playing audio file.
- */
-Media.prototype.play = function(options) {
-    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
-};
-
-/**
- * Stop playing audio file.
- */
-Media.prototype.stop = function() {
-    var me = this;
-    exec(function() {
-        me._position = 0;
-    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
-};
-
-/**
- * Seek or jump to a new time in the track..
- */
-Media.prototype.seekTo = function(milliseconds) {
-    var me = this;
-    exec(function(p) {
-        me._position = p;
-    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
-};
-
-/**
- * Pause playing audio file.
- */
-Media.prototype.pause = function() {
-    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
-};
-
-/**
- * Get duration of an audio file.
- * The duration is only set for audio that is playing, paused or stopped.
- *
- * @return      duration or -1 if not known.
- */
-Media.prototype.getDuration = function() {
-    return this._duration;
-};
-
-/**
- * Get position of audio.
- */
-Media.prototype.getCurrentPosition = function(success, fail) {
-    var me = this;
-    exec(function(p) {
-        me._position = p;
-        success(p);
-    }, fail, "Media", "getCurrentPositionAudio", [this.id]);
-};
-
-/**
- * Start recording audio file.
- */
-Media.prototype.startRecord = function() {
-    exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
-};
-
-/**
- * Stop recording audio file.
- */
-Media.prototype.stopRecord = function() {
-    exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
-};
-
-/**
- * Release the resources.
- */
-Media.prototype.release = function() {
-    exec(null, this.errorCallback, "Media", "release", [this.id]);
-};
-
-/**
- * Adjust the volume.
- */
-Media.prototype.setVolume = function(volume) {
-    exec(null, null, "Media", "setVolume", [this.id, volume]);
-};
-
-/**
- * Audio has status update.
- * PRIVATE
- *
- * @param id            The media object id (string)
- * @param msgType       The 'type' of update this is
- * @param value         Use of value is determined by the msgType
- */
-Media.onStatus = function(id, msgType, value) {
-
-    var media = mediaObjects[id];
-
-    if(media) {
-        switch(msgType) {
-            case Media.MEDIA_STATE :
-                media.statusCallback && media.statusCallback(value);
-                if(value == Media.MEDIA_STOPPED) {
-                    media.successCallback && media.successCallback();
-                }
-                break;
-            case Media.MEDIA_DURATION :
-                media._duration = value;
-                break;
-            case Media.MEDIA_ERROR :
-                media.errorCallback && media.errorCallback(value);
-                break;
-            case Media.MEDIA_POSITION :
-                media._position = Number(value);
-                break;
-            default :
-                console.error && console.error("Unhandled Media.onStatus :: " + msgType);
-                break;
-        }
-    }
-    else {
-         console.error && console.error("Received Media.onStatus callback for unknown media :: " + id);
-    }
-
-};
-
-module.exports = Media;
-
-});
-
-// file: lib/common/plugin/MediaError.js
-define("cordova/plugin/MediaError", function(require, exports, module) {
-
-/**
- * This class contains information about any Media errors.
-*/
-/*
- According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror
- We should never be creating these objects, we should just implement the interface
- which has 1 property for an instance, 'code'
-
- instead of doing :
-    errorCallbackFunction( new MediaError(3,'msg') );
-we should simply use a literal :
-    errorCallbackFunction( {'code':3} );
- */
-
- var _MediaError = window.MediaError;
-
-
-if(!_MediaError) {
-    window.MediaError = _MediaError = function(code, msg) {
-        this.code = (typeof code != 'undefined') ? code : null;
-        this.message = msg || ""; // message is NON-standard! do not use!
-    };
-}
-
-_MediaError.MEDIA_ERR_NONE_ACTIVE    = _MediaError.MEDIA_ERR_NONE_ACTIVE    || 0;
-_MediaError.MEDIA_ERR_ABORTED        = _MediaError.MEDIA_ERR_ABORTED        || 1;
-_MediaError.MEDIA_ERR_NETWORK        = _MediaError.MEDIA_ERR_NETWORK        || 2;
-_MediaError.MEDIA_ERR_DECODE         = _MediaError.MEDIA_ERR_DECODE         || 3;
-_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;
-// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.
-// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes
-_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4;
-
-module.exports = _MediaError;
-
-});
-
-// file: lib/common/plugin/MediaFile.js
-define("cordova/plugin/MediaFile", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    File = require('cordova/plugin/File'),
-    CaptureError = require('cordova/plugin/CaptureError');
-/**
- * Represents a single file.
- *
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
-    MediaFile.__super__.constructor.apply(this, arguments);
-};
-
-utils.extend(MediaFile, File);
-
-/**
- * Request capture format data for a specific file and type
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- */
-MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
-    if (typeof this.fullPath === "undefined" || this.fullPath === null) {
-        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
-    } else {
-        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
-    }
-};
-
-module.exports = MediaFile;
-
-});
-
-// file: lib/common/plugin/MediaFileData.js
-define("cordova/plugin/MediaFileData", function(require, exports, module) {
-
-/**
- * MediaFileData encapsulates format information of a media file.
- *
- * @param {DOMString} codecs
- * @param {long} bitrate
- * @param {long} height
- * @param {long} width
- * @param {float} duration
- */
-var MediaFileData = function(codecs, bitrate, height, width, duration){
-    this.codecs = codecs || null;
-    this.bitrate = bitrate || 0;
-    this.height = height || 0;
-    this.width = width || 0;
-    this.duration = duration || 0;
-};
-
-module.exports = MediaFileData;
-
-});
-
-// file: lib/common/plugin/Metadata.js
-define("cordova/plugin/Metadata", function(require, exports, module) {
-
-/**
- * Information about the state of the file or directory
- *
- * {Date} modificationTime (readonly)
- */
-var Metadata = function(time) {
-    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
-};
-
-module.exports = Metadata;
-
-});
-
-// file: lib/common/plugin/Position.js
-define("cordova/plugin/Position", function(require, exports, module) {
-
-var Coordinates = require('cordova/plugin/Coordinates');
-
-var Position = function(coords, timestamp) {
-    if (coords) {
-        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
-    } else {
-        this.coords = new Coordinates();
-    }
-    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();
-};
-
-module.exports = Position;
-
-});
-
-// file: lib/common/plugin/PositionError.js
-define("cordova/plugin/PositionError", function(require, exports, module) {
-
-/**
- * Position error object
- *
- * @constructor
- * @param code
- * @param message
- */
-var PositionError = function(code, message) {
-    this.code = code || null;
-    this.message = message || '';
-};
-
-PositionError.PERMISSION_DENIED = 1;
-PositionError.POSITION_UNAVAILABLE = 2;
-PositionError.TIMEOUT = 3;
-
-module.exports = PositionError;
-
-});
-
-// file: lib/common/plugin/ProgressEvent.js
-define("cordova/plugin/ProgressEvent", function(require, exports, module) {
-
-// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
-// Feature test: See if we can instantiate a native ProgressEvent;
-// if so, use that approach,
-// otherwise fill-in with our own implementation.
-//
-// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
-var ProgressEvent = (function() {
-    /*
-    var createEvent = function(data) {
-        var event = document.createEvent('Events');
-        event.initEvent('ProgressEvent', false, false);
-        if (data) {
-            for (var i in data) {
-                if (data.hasOwnProperty(i)) {
-                    event[i] = data[i];
-                }
-            }
-            if (data.target) {
-                // TODO: cannot call <some_custom_object>.dispatchEvent
-                // need to first figure out how to implement EventTarget
-            }
-        }
-        return event;
-    };
-    try {
-        var ev = createEvent({type:"abort",target:document});
-        return function ProgressEvent(type, data) {
-            data.type = type;
-            return createEvent(data);
-        };
-    } catch(e){
-    */
-        return function ProgressEvent(type, dict) {
-            this.type = type;
-            this.bubbles = false;
-            this.cancelBubble = false;
-            this.cancelable = false;
-            this.lengthComputable = false;
-            this.loaded = dict && dict.loaded ? dict.loaded : 0;
-            this.total = dict && dict.total ? dict.total : 0;
-            this.target = dict && dict.target ? dict.target : null;
-        };
-    //}
-})();
-
-module.exports = ProgressEvent;
-
-});
-
-// file: lib/common/plugin/accelerometer.js
-define("cordova/plugin/accelerometer", function(require, exports, module) {
-
-/**
- * This class provides access to device accelerometer data.
- * @constructor
- */
-var argscheck = require('cordova/argscheck'),
-    utils = require("cordova/utils"),
-    exec = require("cordova/exec"),
-    Acceleration = require('cordova/plugin/Acceleration');
-
-// Is the accel sensor running?
-var running = false;
-
-// Keeps reference to watchAcceleration calls.
-var timers = {};
-
-// Array of listeners; used to keep track of when we should call start and stop.
-var listeners = [];
-
-// Last returned acceleration object from native
-var accel = null;
-
-// Tells native to start.
-function start() {
-    exec(function(a) {
-        var tempListeners = listeners.slice(0);
-        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
-        for (var i = 0, l = tempListeners.length; i < l; i++) {
-            tempListeners[i].win(accel);
-        }
-    }, function(e) {
-        var tempListeners = listeners.slice(0);
-        for (var i = 0, l = tempListeners.length; i < l; i++) {
-            tempListeners[i].fail(e);
-        }
-    }, "Accelerometer", "start", []);
-    running = true;
-}
-
-// Tells native to stop.
-function stop() {
-    exec(null, null, "Accelerometer", "stop", []);
-    running = false;
-}
-
-// Adds a callback pair to the listeners array
-function createCallbackPair(win, fail) {
-    return {win:win, fail:fail};
-}
-
-// Removes a win/fail listener pair from the listeners array
-function removeListeners(l) {
-    var idx = listeners.indexOf(l);
-    if (idx > -1) {
-        listeners.splice(idx, 1);
-        if (listeners.length === 0) {
-            stop();
-        }
-    }
-}
-
-var accelerometer = {
-    /**
-     * Asynchronously acquires the current acceleration.
-     *
-     * @param {Function} successCallback    The function to call when the acceleration data is available
-     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
-     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
-     */
-    getCurrentAcceleration: function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'accelerometer.getCurrentAcceleration', arguments);
-
-        var p;
-        var win = function(a) {
-            removeListeners(p);
-            successCallback(a);
-        };
-        var fail = function(e) {
-            removeListeners(p);
-            errorCallback && errorCallback(e);
-        };
-
-        p = createCallbackPair(win, fail);
-        listeners.push(p);
-
-        if (!running) {
-            start();
-        }
-    },
-
-    /**
-     * Asynchronously acquires the acceleration repeatedly at a given interval.
-     *
-     * @param {Function} successCallback    The function to call each time the acceleration data is available
-     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
-     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
-     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
-     */
-    watchAcceleration: function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'accelerometer.watchAcceleration', arguments);
-        // Default interval (10 sec)
-        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
-
-        // Keep reference to watch id, and report accel readings as often as defined in frequency
-        var id = utils.createUUID();
-
-        var p = createCallbackPair(function(){}, function(e) {
-            removeListeners(p);
-            errorCallback && errorCallback(e);
-        });
-        listeners.push(p);
-
-        timers[id] = {
-            timer:window.setInterval(function() {
-                if (accel) {
-                    successCallback(accel);
-                }
-            }, frequency),
-            listeners:p
-        };
-
-        if (running) {
-            // If we're already running then immediately invoke the success callback
-            // but only if we have retrieved a value, sample code does not check for null ...
-            if (accel) {
-                successCallback(accel);
-            }
-        } else {
-            start();
-        }
-
-        return id;
-    },
-
-    /**
-     * Clears the specified accelerometer watch.
-     *
-     * @param {String} id       The id of the watch returned from #watchAcceleration.
-     */
-    clearWatch: function(id) {
-        // Stop javascript timer & remove from timer list
-        if (id && timers[id]) {
-            window.clearInterval(timers[id].timer);
-            removeListeners(timers[id].listeners);
-            delete timers[id];
-        }
-    }
-};
-
-module.exports = accelerometer;
-
-});
-
-// file: lib/common/plugin/accelerometer/symbols.js
-define("cordova/plugin/accelerometer/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/Acceleration', 'Acceleration');
-modulemapper.defaults('cordova/plugin/accelerometer', 'navigator.accelerometer');
-
-});
-
-// file: lib/common/plugin/battery.js
-define("cordova/plugin/battery", function(require, exports, module) {
-
-/**
- * This class contains information about the current battery status.
- * @constructor
- */
-var cordova = require('cordova'),
-    exec = require('cordova/exec');
-
-function handlers() {
-  return battery.channels.batterystatus.numHandlers +
-         battery.channels.batterylow.numHandlers +
-         battery.channels.batterycritical.numHandlers;
-}
-
-var Battery = function() {
-    this._level = null;
-    this._isPlugged = null;
-    // Create new event handlers on the window (returns a channel instance)
-    this.channels = {
-      batterystatus:cordova.addWindowEventHandler("batterystatus"),
-      batterylow:cordova.addWindowEventHandler("batterylow"),
-      batterycritical:cordova.addWindowEventHandler("batterycritical")
-    };
-    for (var key in this.channels) {
-        this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange;
-    }
-};
-/**
- * Event handlers for when callbacks get registered for the battery.
- * Keep track of how many handlers we have so we can start and stop the native battery listener
- * appropriately (and hopefully save on battery life!).
- */
-Battery.onHasSubscribersChange = function() {
-  // If we just registered the first handler, make sure native listener is started.
-  if (this.numHandlers === 1 && handlers() === 1) {
-      exec(battery._status, battery._error, "Battery", "start", []);
-  } else if (handlers() === 0) {
-      exec(null, null, "Battery", "stop", []);
-  }
-};
-
-/**
- * Callback for battery status
- *
- * @param {Object} info            keys: level, isPlugged
- */
-Battery.prototype._status = function(info) {
-    if (info) {
-        var me = battery;
-    var level = info.level;
-        if (me._level !== level || me._isPlugged !== info.isPlugged) {
-            // Fire batterystatus event
-            cordova.fireWindowEvent("batterystatus", info);
-
-            // Fire low battery event
-            if (level === 20 || level === 5) {
-                if (level === 20) {
-                    cordova.fireWindowEvent("batterylow", info);
-                }
-                else {
-                    cordova.fireWindowEvent("batterycritical", info);
-                }
-            }
-        }
-        me._level = level;
-        me._isPlugged = info.isPlugged;
-    }
-};
-
-/**
- * Error callback for battery start
- */
-Battery.prototype._error = function(e) {
-    console.log("Error initializing Battery: " + e);
-};
-
-var battery = new Battery();
-
-module.exports = battery;
-
-});
-
-// file: lib/common/plugin/battery/symbols.js
-define("cordova/plugin/battery/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/battery', 'navigator.battery');
-
-});
-
-// file: lib/common/plugin/camera/symbols.js
-define("cordova/plugin/camera/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/Camera', 'navigator.camera');
-modulemapper.defaults('cordova/plugin/CameraConstants', 'Camera');
-modulemapper.defaults('cordova/plugin/CameraPopoverOptions', 'CameraPopoverOptions');
-
-});
-
-// file: lib/common/plugin/capture.js
-define("cordova/plugin/capture", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    MediaFile = require('cordova/plugin/MediaFile');
-
-/**
- * Launches a capture of different types.
- *
- * @param (DOMString} type
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureVideoOptions} options
- */
-function _capture(type, successCallback, errorCallback, options) {
-    var win = function(pluginResult) {
-        var mediaFiles = [];
-        var i;
-        for (i = 0; i < pluginResult.length; i++) {
-            var mediaFile = new MediaFile();
-            mediaFile.name = pluginResult[i].name;
-            mediaFile.fullPath = pluginResult[i].fullPath;
-            mediaFile.type = pluginResult[i].type;
-            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
-            mediaFile.size = pluginResult[i].size;
-            mediaFiles.push(mediaFile);
-        }
-        successCallback(mediaFiles);
-    };
-    exec(win, errorCallback, "Capture", type, [options]);
-}
-/**
- * The Capture interface exposes an interface to the camera and microphone of the hosting device.
- */
-function Capture() {
-    this.supportedAudioModes = [];
-    this.supportedImageModes = [];
-    this.supportedVideoModes = [];
-}
-
-/**
- * Launch audio recorder application for recording audio clip(s).
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureAudioOptions} options
- */
-Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
-    _capture("captureAudio", successCallback, errorCallback, options);
-};
-
-/**
- * Launch camera application for taking image(s).
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureImageOptions} options
- */
-Capture.prototype.captureImage = function(successCallback, errorCallback, options){
-    _capture("captureImage", successCallback, errorCallback, options);
-};
-
-/**
- * Launch device camera application for recording video(s).
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureVideoOptions} options
- */
-Capture.prototype.captureVideo = function(successCallback, errorCallback, options){
-    _capture("captureVideo", successCallback, errorCallback, options);
-};
-
-
-module.exports = new Capture();
-
-});
-
-// file: lib/common/plugin/capture/symbols.js
-define("cordova/plugin/capture/symbols", function(require, exports, module) {
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/CaptureError', 'CaptureError');
-modulemapper.clobbers('cordova/plugin/CaptureAudioOptions', 'CaptureAudioOptions');
-modulemapper.clobbers('cordova/plugin/CaptureImageOptions', 'CaptureImageOptions');
-modulemapper.clobbers('cordova/plugin/CaptureVideoOptions', 'CaptureVideoOptions');
-modulemapper.clobbers('cordova/plugin/ConfigurationData', 'ConfigurationData');
-modulemapper.clobbers('cordova/plugin/MediaFile', 'MediaFile');
-modulemapper.clobbers('cordova/plugin/MediaFileData', 'MediaFileData');
-modulemapper.clobbers('cordova/plugin/capture', 'navigator.device.capture');
-
-});
-
-// file: lib/common/plugin/compass.js
-define("cordova/plugin/compass", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    utils = require('cordova/utils'),
-    CompassHeading = require('cordova/plugin/CompassHeading'),
-    CompassError = require('cordova/plugin/CompassError'),
-    timers = {},
-    compass = {
-        /**
-         * Asynchronously acquires the current heading.
-         * @param {Function} successCallback The function to call when the heading
-         * data is available
-         * @param {Function} errorCallback The function to call when there is an error
-         * getting the heading data.
-         * @param {CompassOptions} options The options for getting the heading data (not used).
-         */
-        getCurrentHeading:function(successCallback, errorCallback, options) {
-            argscheck.checkArgs('fFO', 'compass.getCurrentHeading', arguments);
-
-            var win = function(result) {
-                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
-                successCallback(ch);
-            };
-            var fail = errorCallback && function(code) {
-                var ce = new CompassError(code);
-                errorCallback(ce);
-            };
-
-            // Get heading
-            exec(win, fail, "Compass", "getHeading", [options]);
-        },
-
-        /**
-         * Asynchronously acquires the heading repeatedly at a given interval.
-         * @param {Function} successCallback The function to call each time the heading
-         * data is available
-         * @param {Function} errorCallback The function to call when there is an error
-         * getting the heading data.
-         * @param {HeadingOptions} options The options for getting the heading data
-         * such as timeout and the frequency of the watch. For iOS, filter parameter
-         * specifies to watch via a distance filter rather than time.
-         */
-        watchHeading:function(successCallback, errorCallback, options) {
-            argscheck.checkArgs('fFO', 'compass.watchHeading', arguments);
-            // Default interval (100 msec)
-            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
-            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
-
-            var id = utils.createUUID();
-            if (filter > 0) {
-                // is an iOS request for watch by filter, no timer needed
-                timers[id] = "iOS";
-                compass.getCurrentHeading(successCallback, errorCallback, options);
-            } else {
-                // Start watch timer to get headings
-                timers[id] = window.setInterval(function() {
-                    compass.getCurrentHeading(successCallback, errorCallback);
-                }, frequency);
-            }
-
-            return id;
-        },
-
-        /**
-         * Clears the specified heading watch.
-         * @param {String} watchId The ID of the watch returned from #watchHeading.
-         */
-        clearWatch:function(id) {
-            // Stop javascript timer & remove from timer list
-            if (id && timers[id]) {
-                if (timers[id] != "iOS") {
-                    clearInterval(timers[id]);
-                } else {
-                    // is iOS watch by filter so call into device to stop
-                    exec(null, null, "Compass", "stopHeading", []);
-                }
-                delete timers[id];
-            }
-        }
-    };
-
-module.exports = compass;
-
-});
-
-// file: lib/common/plugin/compass/symbols.js
-define("cordova/plugin/compass/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/CompassHeading', 'CompassHeading');
-modulemapper.clobbers('cordova/plugin/CompassError', 'CompassError');
-modulemapper.clobbers('cordova/plugin/compass', 'navigator.compass');
-
-});
-
-// file: lib/common/plugin/console-via-logger.js
-define("cordova/plugin/console-via-logger", function(require, exports, module) {
-
-//------------------------------------------------------------------------------
-
-var logger = require("cordova/plugin/logger");
-var utils  = require("cordova/utils");
-
-//------------------------------------------------------------------------------
-// object that we're exporting
-//------------------------------------------------------------------------------
-var console = module.exports;
-
-//------------------------------------------------------------------------------
-// copy of the original console object
-//------------------------------------------------------------------------------
-var WinConsole = window.console;
-
-//------------------------------------------------------------------------------
-// whether to use the logger
-//------------------------------------------------------------------------------
-var UseLogger = false;
-
-//------------------------------------------------------------------------------
-// Timers
-//------------------------------------------------------------------------------
-var Timers = {};
-
-//------------------------------------------------------------------------------
-// used for unimplemented methods
-//------------------------------------------------------------------------------
-function noop() {}
-
-//------------------------------------------------------------------------------
-// used for unimplemented methods
-//------------------------------------------------------------------------------
-console.useLogger = function (value) {
-    if (arguments.length) UseLogger = !!value;
-
-    if (UseLogger) {
-        if (logger.useConsole()) {
-            throw new Error("console and logger are too intertwingly");
-        }
-    }
-
-    return UseLogger;
-};
-
-//------------------------------------------------------------------------------
-console.log = function() {
-    if (logger.useConsole()) return;
-    logger.log.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.error = function() {
-    if (logger.useConsole()) return;
-    logger.error.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.warn = function() {
-    if (logger.useConsole()) return;
-    logger.warn.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.info = function() {
-    if (logger.useConsole()) return;
-    logger.info.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.debug = function() {
-    if (logger.useConsole()) return;
-    logger.debug.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.assert = function(expression) {
-    if (expression) return;
-
-    var message = logger.format.apply(logger.format, [].slice.call(arguments, 1));
-    console.log("ASSERT: " + message);
-};
-
-//------------------------------------------------------------------------------
-console.clear = function() {};
-
-//------------------------------------------------------------------------------
-console.dir = function(object) {
-    console.log("%o", object);
-};
-
-//------------------------------------------------------------------------------
-console.dirxml = function(node) {
-    console.log(node.innerHTML);
-};
-
-//------------------------------------------------------------------------------
-console.trace = noop;
-
-//------------------------------------------------------------------------------
-console.group = console.log;
-
-//------------------------------------------------------------------------------
-console.groupCollapsed = console.log;
-
-//------------------------------------------------------------------------------
-console.groupEnd = noop;
-
-//------------------------------------------------------------------------------
-console.time = function(name) {
-    Timers[name] = new Date().valueOf();
-};
-
-//------------------------------------------------------------------------------
-console.timeEnd = function(name) {
-    var timeStart = Timers[name];
-    if (!timeStart) {
-        console.warn("unknown timer: " + name);
-        return;
-    }
-
-    var timeElapsed = new Date().valueOf() - timeStart;
-    console.log(name + ": " + timeElapsed + "ms");
-};
-
-//------------------------------------------------------------------------------
-console.timeStamp = noop;
-
-//------------------------------------------------------------------------------
-console.profile = noop;
-
-//------------------------------------------------------------------------------
-console.profileEnd = noop;
-
-//------------------------------------------------------------------------------
-console.count = noop;
-
-//------------------------------------------------------------------------------
-console.exception = console.log;
-
-//------------------------------------------------------------------------------
-console.table = function(data, columns) {
-    console.log("%o", data);
-};
-
-//------------------------------------------------------------------------------
-// return a new function that calls both functions passed as args
-//------------------------------------------------------------------------------
-function wrappedOrigCall(orgFunc, newFunc) {
-    return function() {
-        var args = [].slice.call(arguments);
-        try { orgFunc.apply(WinConsole, args); } catch (e) {}
-        try { newFunc.apply(console,    args); } catch (e) {}
-    };
-}
-
-//------------------------------------------------------------------------------
-// For every function that exists in the original console object, that
-// also exists in the new console object, wrap the new console method
-// with one that calls both
-//------------------------------------------------------------------------------
-for (var key in console) {
-    if (typeof WinConsole[key] == "function") {
-        console[key] = wrappedOrigCall(WinConsole[key], console[key]);
-    }
-}
-
-});
-
-// file: lib/common/plugin/contacts.js
-define("cordova/plugin/contacts", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    ContactError = require('cordova/plugin/ContactError'),
-    utils = require('cordova/utils'),
-    Contact = require('cordova/plugin/Contact');
-
-/**
-* Represents a group of Contacts.
-* @constructor
-*/
-var contacts = {
-    /**
-     * Returns an array of Contacts matching the search criteria.
-     * @param fields that should be searched
-     * @param successCB success callback
-     * @param errorCB error callback
-     * @param {ContactFindOptions} options that can be applied to contact searching
-     * @return array of Contacts matching search criteria
-     */
-    find:function(fields, successCB, errorCB, options) {
-        argscheck.checkArgs('afFO', 'contacts.find', arguments);
-        if (!fields.length) {
-            errorCB && errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
-        } else {
-            var win = function(result) {
-                var cs = [];
-                for (var i = 0, l = result.length; i < l; i++) {
-                    cs.push(contacts.create(result[i]));
-                }
-                successCB(cs);
-            };
-            exec(win, errorCB, "Contacts", "search", [fields, options]);
-        }
-    },
-
-    /**
-     * This function creates a new contact, but it does not persist the contact
-     * to device storage. To persist the contact to device storage, invoke
-     * contact.save().
-     * @param properties an object whose properties will be examined to create a new Contact
-     * @returns new Contact object
-     */
-    create:function(properties) {
-        argscheck.checkArgs('O', 'contacts.create', arguments);
-        var contact = new Contact();
-        for (var i in properties) {
-            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
-                contact[i] = properties[i];
-            }
-        }
-        return contact;
-    }
-};
-
-module.exports = contacts;
-
-});
-
-// file: lib/common/plugin/contacts/symbols.js
-define("cordova/plugin/contacts/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/contacts', 'navigator.contacts');
-modulemapper.clobbers('cordova/plugin/Contact', 'Contact');
-modulemapper.clobbers('cordova/plugin/ContactAddress', 'ContactAddress');
-modulemapper.clobbers('cordova/plugin/ContactError', 'ContactError');
-modulemapper.clobbers('cordova/plugin/ContactField', 'ContactField');
-modulemapper.clobbers('cordova/plugin/ContactFindOptions', 'ContactFindOptions');
-modulemapper.clobbers('cordova/plugin/ContactName', 'ContactName');
-modulemapper.clobbers('cordova/plugin/ContactOrganization', 'ContactOrganization');
-
-});
-
-// file: lib/common/plugin/device.js
-define("cordova/plugin/device", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    channel = require('cordova/channel'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec');
-
-// Tell cordova channel to wait on the CordovaInfoReady event
-channel.waitForInitialization('onCordovaInfoReady');
-
-/**
- * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
- * phone, etc.
- * @constructor
- */
-function Device() {
-    this.available = false;
-    this.platform = null;
-    this.version = null;
-    this.uuid = null;
-    this.cordova = null;
-    this.model = null;
-
-    var me = this;
-
-    channel.onCordovaReady.subscribe(function() {
-        me.getInfo(function(info) {
-            var buildLabel = info.cordova;
-            if (buildLabel != CORDOVA_JS_BUILD_LABEL) {
-                buildLabel += ' JS=' + CORDOVA_JS_BUILD_LABEL;
-            }
-            me.available = true;
-            me.platform = info.platform;
-            me.version = info.version;
-            me.uuid = info.uuid;
-            me.cordova = buildLabel;
-            me.model = info.model;
-            channel.onCordovaInfoReady.fire();
-        },function(e) {
-            me.available = false;
-            utils.alert("[ERROR] Error initializing Cordova: " + e);
-        });
-    });
-}
-
-/**
- * Get device info
- *
- * @param {Function} successCallback The function to call when the heading data is available
- * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
- */
-Device.prototype.getInfo = function(successCallback, errorCallback) {
-    argscheck.checkArgs('fF', 'Device.getInfo', arguments);
-    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
-};
-
-module.exports = new Device();
-
-});
-
-// file: lib/common/plugin/device/symbols.js
-define("cordova/plugin/device/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/device', 'device');
-
-});
-
-// file: lib/common/plugin/echo.js
-define("cordova/plugin/echo", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    utils = require('cordova/utils');
-
-/**
- * Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.
- * @param successCallback  invoked with a FileSystem object
- * @param errorCallback  invoked if error occurs retrieving file system
- * @param message  The string to be echoed.
- * @param forceAsync  Whether to force an async return value (for testing native->js bridge).
- */
-module.exports = function(successCallback, errorCallback, message, forceAsync) {
-    var action = 'echo';
-    var messageIsMultipart = (utils.typeName(message) == "Array");
-    var args = messageIsMultipart ? message : [message];
-
-    if (utils.typeName(message) == 'ArrayBuffer') {
-        if (forceAsync) {
-            console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.');
-        }
-        action += 'ArrayBuffer';
-    } else if (messageIsMultipart) {
-        if (forceAsync) {
-            console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.');
-        }
-        action += 'MultiPart';
-    } else if (forceAsync) {
-        action += 'Async';
-    }
-
-    exec(successCallback, errorCallback, "Echo", action, args);
-};
-
-
-});
-
-// file: lib/windowsphone/plugin/file/symbols.js
-define("cordova/plugin/file/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper'),
-    symbolshelper = require('cordova/plugin/file/symbolshelper');
-
-symbolshelper(modulemapper.defaults);
-
-});
-
-// file: lib/common/plugin/file/symbolshelper.js
-define("cordova/plugin/file/symbolshelper", function(require, exports, module) {
-
-module.exports = function(exportFunc) {
-    exportFunc('cordova/plugin/DirectoryEntry', 'DirectoryEntry');
-    exportFunc('cordova/plugin/DirectoryReader', 'DirectoryReader');
-    exportFunc('cordova/plugin/Entry', 'Entry');
-    exportFunc('cordova/plugin/File', 'File');
-    exportFunc('cordova/plugin/FileEntry', 'FileEntry');
-    exportFunc('cordova/plugin/FileError', 'FileError');
-    exportFunc('cordova/plugin/FileReader', 'FileReader');
-    exportFunc('cordova/plugin/FileSystem', 'FileSystem');
-    exportFunc('cordova/plugin/FileUploadOptions', 'FileUploadOptions');
-    exportFunc('cordova/plugin/FileUploadResult', 'FileUploadResult');
-    exportFunc('cordova/plugin/FileWriter', 'FileWriter');
-    exportFunc('cordova/plugin/Flags', 'Flags');
-    exportFunc('cordova/plugin/LocalFileSystem', 'LocalFileSystem');
-    exportFunc('cordova/plugin/Metadata', 'Metadata');
-    exportFunc('cordova/plugin/ProgressEvent', 'ProgressEvent');
-    exportFunc('cordova/plugin/requestFileSystem', 'requestFileSystem');
-    exportFunc('cordova/plugin/resolveLocalFileSystemURI', 'resolveLocalFileSystemURI');
-};
-
-});
-
-// file: lib/windowsphone/plugin/filetransfer/symbols.js
-define("cordova/plugin/filetransfer/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/windowsphone/FileTransfer', 'FileTransfer');
-modulemapper.clobbers('cordova/plugin/FileTransferError', 'FileTransferError');
-
-});
-
-// file: lib/common/plugin/geolocation.js
-define("cordova/plugin/geolocation", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    PositionError = require('cordova/plugin/PositionError'),
-    Position = require('cordova/plugin/Position');
-
-var timers = {};   // list of timers in use
-
-// Returns default params, overrides if provided with values
-function parseParameters(options) {
-    var opt = {
-        maximumAge: 0,
-        enableHighAccuracy: false,
-        timeout: Infinity
-    };
-
-    if (options) {
-        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
-            opt.maximumAge = options.maximumAge;
-        }
-        if (options.enableHighAccuracy !== undefined) {
-            opt.enableHighAccuracy = options.enableHighAccuracy;
-        }
-        if (options.timeout !== undefined && !isNaN(options.timeout)) {
-            if (options.timeout < 0) {
-                opt.timeout = 0;
-            } else {
-                opt.timeout = options.timeout;
-            }
-        }
-    }
-
-    return opt;
-}
-
-// Returns a timeout failure, closed over a specified timeout value and error callback.
-function createTimeout(errorCallback, timeout) {
-    var t = setTimeout(function() {
-        clearTimeout(t);
-        t = null;
-        errorCallback({
-            code:PositionError.TIMEOUT,
-            message:"Position retrieval timed out."
-        });
-    }, timeout);
-    return t;
-}
-
-var geolocation = {
-    lastPosition:null, // reference to last known (cached) position returned
-    /**
-   * Asynchronously acquires the current position.
-   *
-   * @param {Function} successCallback    The function to call when the position data is available
-   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)
-   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)
-   */
-    getCurrentPosition:function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments);
-        options = parseParameters(options);
-
-        // Timer var that will fire an error callback if no position is retrieved from native
-        // before the "timeout" param provided expires
-        var timeoutTimer = {timer:null};
-
-        var win = function(p) {
-            clearTimeout(timeoutTimer.timer);
-            if (!(timeoutTimer.timer)) {
-                // Timeout already happened, or native fired error callback for
-                // this geo request.
-                // Don't continue with success callback.
-                return;
-            }
-            var pos = new Position(
-                {
-                    latitude:p.latitude,
-                    longitude:p.longitude,
-                    altitude:p.altitude,
-                    accuracy:p.accuracy,
-                    heading:p.heading,
-                    velocity:p.velocity,
-                    altitudeAccuracy:p.altitudeAccuracy
-                },
-                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
-            );
-            geolocation.lastPosition = pos;
-            successCallback(pos);
-        };
-        var fail = function(e) {
-            clearTimeout(timeoutTimer.timer);
-            timeoutTimer.timer = null;
-            var err = new PositionError(e.code, e.message);
-            if (errorCallback) {
-                errorCallback(err);
-            }
-        };
-
-        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
-        // fire the success callback with the cached position.
-        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
-            successCallback(geolocation.lastPosition);
-        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
-        } else if (options.timeout === 0) {
-            fail({
-                code:PositionError.TIMEOUT,
-                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter."
-            });
-        // Otherwise we have to call into native to retrieve a position.
-        } else {
-            if (options.timeout !== Infinity) {
-                // If the timeout value was not set to Infinity (default), then
-                // set up a timeout function that will fire the error callback
-                // if no successful position was retrieved before timeout expired.
-                timeoutTimer.timer = createTimeout(fail, options.timeout);
-            } else {
-                // This is here so the check in the win function doesn't mess stuff up
-                // may seem weird but this guarantees timeoutTimer is
-                // always truthy before we call into native
-                timeoutTimer.timer = true;
-            }
-            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
-        }
-        return timeoutTimer;
-    },
-    /**
-     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,
-     * the successCallback is called with the new location.
-     *
-     * @param {Function} successCallback    The function to call each time the location data is available
-     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)
-     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)
-     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
-     */
-    watchPosition:function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments);
-        options = parseParameters(options);
-
-        var id = utils.createUUID();
-
-        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
-        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
-
-        var fail = function(e) {
-            clearTimeout(timers[id].timer);
-            var err = new PositionError(e.code, e.message);
-            if (errorCallback) {
-                errorCallback(err);
-            }
-        };
-
-        var win = function(p) {
-            clearTimeout(timers[id].timer);
-            if (options.timeout !== Infinity) {
-                timers[id].timer = createTimeout(fail, options.timeout);
-            }
-            var pos = new Position(
-                {
-                    latitude:p.latitude,
-                    longitude:p.longitude,
-                    altitude:p.altitude,
-                    accuracy:p.accuracy,
-                    heading:p.heading,
-                    velocity:p.velocity,
-                    altitudeAccuracy:p.altitudeAccuracy
-                },
-                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
-            );
-            geolocation.lastPosition = pos;
-            successCallback(pos);
-        };
-
-        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
-
-        return id;
-    },
-    /**
-     * Clears the specified heading watch.
-     *
-     * @param {String} id       The ID of the watch returned from #watchPosition
-     */
-    clearWatch:function(id) {
-        if (id && timers[id] !== undefined) {
-            clearTimeout(timers[id].timer);
-            timers[id].timer = false;
-            exec(null, null, "Geolocation", "clearWatch", [id]);
-        }
-    }
-};
-
-module.exports = geolocation;
-
-});
-
-// file: lib/common/plugin/geolocation/symbols.js
-define("cordova/plugin/geolocation/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/geolocation', 'navigator.geolocation');
-modulemapper.clobbers('cordova/plugin/PositionError', 'PositionError');
-modulemapper.clobbers('cordova/plugin/Position', 'Position');
-modulemapper.clobbers('cordova/plugin/Coordinates', 'Coordinates');
-
-});
-
-// file: lib/common/plugin/globalization.js
-define("cordova/plugin/globalization", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    GlobalizationError = require('cordova/plugin/GlobalizationError');
-
-var globalization = {
-
-/**
-* Returns the string identifier for the client's current language.
-* It returns the language identifier string to the successCB callback with a
-* properties object as a parameter. If there is an error getting the language,
-* then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {String}: The language identifier
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');},
-*                                function () {});
-*/
-getPreferredLanguage:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getPreferredLanguage', arguments);
-    exec(successCB, failureCB, "Globalization","getPreferredLanguage", []);
-},
-
-/**
-* Returns the string identifier for the client's current locale setting.
-* It returns the locale identifier string to the successCB callback with a
-* properties object as a parameter. If there is an error getting the locale,
-* then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {String}: The locale identifier
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');},
-*                                function () {});
-*/
-getLocaleName:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getLocaleName', arguments);
-    exec(successCB, failureCB, "Globalization","getLocaleName", []);
-},
-
-
-/**
-* Returns a date formatted as a string according to the client's user preferences and
-* calendar using the time zone of the client. It returns the formatted date string to the
-* successCB callback with a properties object as a parameter. If there is an error
-* formatting the date, then the errorCB callback is invoked.
-*
-* The defaults are: formatLenght="short" and selector="date and time"
-*
-* @param {Date} date
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return Object.value {String}: The localized date string
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.dateToString(new Date(),
-*                function (date) {alert('date:' + date.value + '\n');},
-*                function (errorCode) {alert(errorCode);},
-*                {formatLength:'short'});
-*/
-dateToString:function(date, successCB, failureCB, options) {
-    argscheck.checkArgs('dfFO', 'Globalization.dateToString', arguments);
-    var dateValue = date.valueOf();
-    exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]);
-},
-
-
-/**
-* Parses a date formatted as a string according to the client's user
-* preferences and calendar using the time zone of the client and returns
-* the corresponding date object. It returns the date to the successCB
-* callback with a properties object as a parameter. If there is an error
-* parsing the date string, then the errorCB callback is invoked.
-*
-* The defaults are: formatLength="short" and selector="date and time"
-*
-* @param {String} dateString
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return    Object.year {Number}: The four digit year
-*            Object.month {Number}: The month from (0 - 11)
-*            Object.day {Number}: The day from (1 - 31)
-*            Object.hour {Number}: The hour from (0 - 23)
-*            Object.minute {Number}: The minute from (0 - 59)
-*            Object.second {Number}: The second from (0 - 59)
-*            Object.millisecond {Number}: The milliseconds (from 0 - 999),
-*                                        not available on all platforms
-*
-* @error GlobalizationError.PARSING_ERROR
-*
-* Example
-*    globalization.stringToDate('4/11/2011',
-*                function (date) { alert('Month:' + date.month + '\n' +
-*                    'Day:' + date.day + '\n' +
-*                    'Year:' + date.year + '\n');},
-*                function (errorCode) {alert(errorCode);},
-*                {selector:'date'});
-*/
-stringToDate:function(dateString, successCB, failureCB, options) {
-    argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments);
-    exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]);
-},
-
-
-/**
-* Returns a pattern string for formatting and parsing dates according to the client's
-* user preferences. It returns the pattern to the successCB callback with a
-* properties object as a parameter. If there is an error obtaining the pattern,
-* then the errorCB callback is invoked.
-*
-* The defaults are: formatLength="short" and selector="date and time"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.
-*                                    The patterns follow Unicode Technical Standard #35
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.timezone {String}: The abbreviated name of the time zone on the client
-*            Object.utc_offset {Number}: The current difference in seconds between the client's
-*                                        time zone and coordinated universal time.
-*            Object.dst_offset {Number}: The current daylight saving time offset in seconds
-*                                        between the client's non-daylight saving's time zone
-*                                        and the client's daylight saving's time zone.
-*
-* @error GlobalizationError.PATTERN_ERROR
-*
-* Example
-*    globalization.getDatePattern(
-*                function (date) {alert('pattern:' + date.pattern + '\n');},
-*                function () {},
-*                {formatLength:'short'});
-*/
-getDatePattern:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getDatePattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]);
-},
-
-
-/**
-* Returns an array of either the names of the months or days of the week
-* according to the client's user preferences and calendar. It returns the array of names to the
-* successCB callback with a properties object as a parameter. If there is an error obtaining the
-* names, then the errorCB callback is invoked.
-*
-* The defaults are: type="wide" and item="months"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'narrow' or 'wide'
-*            item {String}: 'months', or 'days'
-*
-* @return Object.value {Array{String}}: The array of names starting from either
-*                                        the first month in the year or the
-*                                        first day of the week.
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getDateNames(function (names) {
-*        for(var i = 0; i < names.value.length; i++) {
-*            alert('Month:' + names.value[i] + '\n');}},
-*        function () {});
-*/
-getDateNames:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments);
-    exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]);
-},
-
-/**
-* Returns whether daylight savings time is in effect for a given date using the client's
-* time zone and calendar. It returns whether or not daylight savings time is in effect
-* to the successCB callback with a properties object as a parameter. If there is an error
-* reading the date, then the errorCB callback is invoked.
-*
-* @param {Date} date
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is
-*                                in effect for the given date and "false" indicate that it is not.
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.isDayLightSavingsTime(new Date(),
-*                function (date) {alert('dst:' + date.dst + '\n');}
-*                function () {});
-*/
-isDayLightSavingsTime:function(date, successCB, failureCB) {
-    argscheck.checkArgs('dfF', 'Globalization.isDayLightSavingsTime', arguments);
-    var dateValue = date.valueOf();
-    exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]);
-},
-
-/**
-* Returns the first day of the week according to the client's user preferences and calendar.
-* The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
-* It returns the day to the successCB callback with a properties object as a parameter.
-* If there is an error obtaining the pattern, then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {Number}: The number of the first day of the week.
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getFirstDayOfWeek(function (day)
-*                { alert('Day:' + day.value + '\n');},
-*                function () {});
-*/
-getFirstDayOfWeek:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getFirstDayOfWeek', arguments);
-    exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []);
-},
-
-
-/**
-* Returns a number formatted as a string according to the client's user preferences.
-* It returns the formatted number string to the successCB callback with a properties object as a
-* parameter. If there is an error formatting the number, then the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {Number} number
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return Object.value {String}: The formatted number string.
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.numberToString(3.25,
-*                function (number) {alert('number:' + number.value + '\n');},
-*                function () {},
-*                {type:'decimal'});
-*/
-numberToString:function(number, successCB, failureCB, options) {
-    argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments);
-    exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]);
-},
-
-/**
-* Parses a number formatted as a string according to the client's user preferences and
-* returns the corresponding number. It returns the number to the successCB callback with a
-* properties object as a parameter. If there is an error parsing the number string, then
-* the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {String} numberString
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return Object.value {Number}: The parsed number.
-*
-* @error GlobalizationError.PARSING_ERROR
-*
-* Example
-*    globalization.stringToNumber('1234.56',
-*                function (number) {alert('Number:' + number.value + '\n');},
-*                function () { alert('Error parsing number');});
-*/
-stringToNumber:function(numberString, successCB, failureCB, options) {
-    argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments);
-    exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]);
-},
-
-/**
-* Returns a pattern string for formatting and parsing numbers according to the client's user
-* preferences. It returns the pattern to the successCB callback with a properties object as a
-* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.
-*                                    The patterns follow Unicode Technical Standard #35.
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.symbol {String}: The symbol to be used when formatting and parsing
-*                                    e.g., percent or currency symbol.
-*            Object.fraction {Number}: The number of fractional digits to use when parsing and
-*                                    formatting numbers.
-*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-*            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.
-*            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.
-*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-*
-* @error GlobalizationError.PATTERN_ERROR
-*
-* Example
-*    globalization.getNumberPattern(
-*                function (pattern) {alert('Pattern:' + pattern.pattern + '\n');},
-*                function () {});
-*/
-getNumberPattern:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getNumberPattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]);
-},
-
-/**
-* Returns a pattern string for formatting and parsing currency values according to the client's
-* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
-* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
-* callback is invoked.
-*
-* @param {String} currencyCode
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.
-*                                    The patterns follow Unicode Technical Standard #35
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.code {String}: The ISO 4217 currency code for the pattern.
-*            Object.fraction {Number}: The number of fractional digits to use when parsing and
-*                                    formatting currency.
-*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.getCurrencyPattern('EUR',
-*                function (currency) {alert('Pattern:' + currency.pattern + '\n');}
-*                function () {});
-*/
-getCurrencyPattern:function(currencyCode, successCB, failureCB) {
-    argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);
-}
-
-};
-
-module.exports = globalization;
-
-});
-
-// file: lib/common/plugin/globalization/symbols.js
-define("cordova/plugin/globalization/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/globalization', 'navigator.globalization');
-modulemapper.clobbers('cordova/plugin/GlobalizationError', 'GlobalizationError');
-
-});
-
-// file: lib/windowsphone/plugin/inappbrowser/symbols.js
-define("cordova/plugin/inappbrowser/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/InAppBrowser', 'open');
-
-});
-
-// file: lib/common/plugin/logger.js
-define("cordova/plugin/logger", function(require, exports, module) {
-
-//------------------------------------------------------------------------------
-// The logger module exports the following properties/functions:
-//
-// LOG                          - constant for the level LOG
-// ERROR                        - constant for the level ERROR
-// WARN                         - constant for the level WARN
-// INFO                         - constant for the level INFO
-// DEBUG                        - constant for the level DEBUG
-// logLevel()                   - returns current log level
-// logLevel(value)              - sets and returns a new log level
-// useConsole()                 - returns whether logger is using console
-// useConsole(value)            - sets and returns whether logger is using console
-// log(message,...)             - logs a message at level LOG
-// error(message,...)           - logs a message at level ERROR
-// warn(message,...)            - logs a message at level WARN
-// info(message,...)            - logs a message at level INFO
-// debug(message,...)           - logs a message at level DEBUG
-// logLevel(level,message,...)  - logs a message specified level
-//
-//------------------------------------------------------------------------------
-
-var logger = exports;
-
-var exec    = require('cordova/exec');
-var utils   = require('cordova/utils');
-
-var UseConsole   = true;
-var UseLogger    = true;
-var Queued       = [];
-var DeviceReady  = false;
-var CurrentLevel;
-
-var originalConsole = console;
-
-/**
- * Logging levels
- */
-
-var Levels = [
-    "LOG",
-    "ERROR",
-    "WARN",
-    "INFO",
-    "DEBUG"
-];
-
-/*
- * add the logging levels to the logger object and
- * to a separate levelsMap object for testing
- */
-
-var LevelsMap = {};
-for (var i=0; i<Levels.length; i++) {
-    var level = Levels[i];
-    LevelsMap[level] = i;
-    logger[level]    = level;
-}
-
-CurrentLevel = LevelsMap.WARN;
-
-/**
- * Getter/Setter for the logging level
- *
- * Returns the current logging level.
- *
- * When a value is passed, sets the logging level to that value.
- * The values should be one of the following constants:
- *    logger.LOG
- *    logger.ERROR
- *    logger.WARN
- *    logger.INFO
- *    logger.DEBUG
- *
- * The value used determines which messages get printed.  The logging
- * values above are in order, and only messages logged at the logging
- * level or above will actually be displayed to the user.  E.g., the
- * default level is WARN, so only messages logged with LOG, ERROR, or
- * WARN will be displayed; INFO and DEBUG messages will be ignored.
- */
-logger.level = function (value) {
-    if (arguments.length) {
-        if (LevelsMap[value] === null) {
-            throw new Error("invalid logging level: " + value);
-        }
-        CurrentLevel = LevelsMap[value];
-    }
-
-    return Levels[CurrentLevel];
-};
-
-/**
- * Getter/Setter for the useConsole functionality
- *
- * When useConsole is true, the logger will log via the
- * browser 'console' object.
- */
-logger.useConsole = function (value) {
-    if (arguments.length) UseConsole = !!value;
-
-    if (UseConsole) {
-        if (typeof console == "undefined") {
-            throw new Error("global console object is not defined");
-        }
-
-        if (typeof console.log != "function") {
-            throw new Error("global console object does not have a log function");
-        }
-
-        if (typeof console.useLogger == "function") {
-            if (console.useLogger()) {
-                throw new Error("console and logger are too intertwingly");
-            }
-        }
-    }
-
-    return UseConsole;
-};
-
-/**
- * Getter/Setter for the useLogger functionality
- *
- * When useLogger is true, the logger will log via the
- * native Logger plugin.
- */
-logger.useLogger = function (value) {
-    // Enforce boolean
-    if (arguments.length) UseLogger = !!value;
-    return UseLogger;
-};
-
-/**
- * Logs a message at the LOG level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.log   = function(message) { logWithArgs("LOG",   arguments); };
-
-/**
- * Logs a message at the ERROR level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.error = function(message) { logWithArgs("ERROR", arguments); };
-
-/**
- * Logs a message at the WARN level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
-
-/**
- * Logs a message at the INFO level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.info  = function(message) { logWithArgs("INFO",  arguments); };
-
-/**
- * Logs a message at the DEBUG level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
-
-// log at the specified level with args
-function logWithArgs(level, args) {
-    args = [level].concat([].slice.call(args));
-    logger.logLevel.apply(logger, args);
-}
-
-/**
- * Logs a message at the specified level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.logLevel = function(level /* , ... */) {
-    // format the message with the parameters
-    var formatArgs = [].slice.call(arguments, 1);
-    var message    = logger.format.apply(logger.format, formatArgs);
-
-    if (LevelsMap[level] === null) {
-        throw new Error("invalid logging level: " + level);
-    }
-
-    if (LevelsMap[level] > CurrentLevel) return;
-
-    // queue the message if not yet at deviceready
-    if (!DeviceReady && !UseConsole) {
-        Queued.push([level, message]);
-        return;
-    }
-
-    // Log using the native logger if that is enabled
-    if (UseLogger) {
-        exec(null, null, "Logger", "logLevel", [level, message]);
-    }
-
-    // Log using the console if that is enabled
-    if (UseConsole) {
-        // make sure console is not using logger
-        if (console.__usingCordovaLogger) {
-            throw new Error("console and logger are too intertwingly");
-        }
-
-        // log to the console
-        switch (level) {
-            case logger.LOG:   originalConsole.log(message); break;
-            case logger.ERROR: originalConsole.log("ERROR: " + message); break;
-            case logger.WARN:  originalConsole.log("WARN: "  + message); break;
-            case logger.INFO:  originalConsole.log("INFO: "  + message); break;
-            case logger.DEBUG: originalConsole.log("DEBUG: " + message); break;
-        }
-    }
-};
-
-
-/**
- * Formats a string and arguments following it ala console.log()
- *
- * Any remaining arguments will be appended to the formatted string.
- *
- * for rationale, see FireBug's Console API:
- *    http://getfirebug.com/wiki/index.php/Console_API
- */
-logger.format = function(formatString, args) {
-    return __format(arguments[0], [].slice.call(arguments,1)).join(' ');
-};
-
-
-//------------------------------------------------------------------------------
-/**
- * Formats a string and arguments following it ala vsprintf()
- *
- * format chars:
- *   %j - format arg as JSON
- *   %o - format arg as JSON
- *   %c - format arg as ''
- *   %% - replace with '%'
- * any other char following % will format it's
- * arg via toString().
- *
- * Returns an array containing the formatted string and any remaining
- * arguments.
- */
-function __format(formatString, args) {
-    if (formatString === null || formatString === undefined) return [""];
-    if (arguments.length == 1) return [formatString.toString()];
-
-    if (typeof formatString != "string")
-        formatString = formatString.toString();
-
-    var pattern = /(.*?)%(.)(.*)/;
-    var rest    = formatString;
-    var result  = [];
-
-    while (args.length) {
-        var match = pattern.exec(rest);
-        if (!match) break;
-
-        var arg   = args.shift();
-        rest = match[3];
-        result.push(match[1]);
-
-        if (match[2] == '%') {
-            result.push('%');
-            args.unshift(arg);
-            continue;
-        }
-
-        result.push(__formatted(arg, match[2]));
-    }
-
-    result.push(rest);
-
-    var remainingArgs = [].slice.call(args);
-    remainingArgs.unshift(result.join(''));
-    return remainingArgs;
-}
-
-function __formatted(object, formatChar) {
-
-    try {
-        switch(formatChar) {
-            case 'j':
-            case 'o': return JSON.stringify(object);
-            case 'c': return '';
-        }
-    }
-    catch (e) {
-        return "error JSON.stringify()ing argument: " + e;
-    }
-
-    if ((object === null) || (object === undefined)) {
-        return Object.prototype.toString.call(object);
-    }
-
-    return object.toString();
-}
-
-
-//------------------------------------------------------------------------------
-// when deviceready fires, log queued messages
-logger.__onDeviceReady = function() {
-    if (DeviceReady) return;
-
-    DeviceReady = true;
-
-    for (var i=0; i<Queued.length; i++) {
-        var messageArgs = Queued[i];
-        logger.logLevel(messageArgs[0], messageArgs[1]);
-    }
-
-    Queued = null;
-};
-
-// add a deviceready event to log queued messages
-document.addEventListener("deviceready", logger.__onDeviceReady, false);
-
-});
-
-// file: lib/common/plugin/logger/symbols.js
-define("cordova/plugin/logger/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/logger', 'cordova.logger');
-
-});
-
-// file: lib/windowsphone/plugin/media/symbols.js
-define("cordova/plugin/media/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/Media', 'Media');
-modulemapper.defaults('cordova/plugin/MediaError', 'MediaError');
-
-});
-
-// file: lib/common/plugin/network.js
-define("cordova/plugin/network", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    cordova = require('cordova'),
-    channel = require('cordova/channel'),
-    utils = require('cordova/utils');
-
-// Link the onLine property with the Cordova-supplied network info.
-// This works because we clobber the naviagtor object with our own
-// object in bootstrap.js.
-if (typeof navigator != 'undefined') {
-    utils.defineGetter(navigator, 'onLine', function() {
-        return this.connection.type != 'none';
-    });
-}
-
-function NetworkConnection() {
-    this.type = 'unknown';
-}
-
-/**
- * Get connection info
- *
- * @param {Function} successCallback The function to call when the Connection data is available
- * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
- */
-NetworkConnection.prototype.getInfo = function(successCallback, errorCallback) {
-    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);
-};
-
-var me = new NetworkConnection();
-var timerId = null;
-var timeout = 500;
-
-channel.onCordovaReady.subscribe(function() {
-    me.getInfo(function(info) {
-        me.type = info;
-        if (info === "none") {
-            // set a timer if still offline at the end of timer send the offline event
-            timerId = setTimeout(function(){
-                cordova.fireDocumentEvent("offline");
-                timerId = null;
-            }, timeout);
-        } else {
-            // If there is a current offline event pending clear it
-            if (timerId !== null) {
-                clearTimeout(timerId);
-                timerId = null;
-            }
-            cordova.fireDocumentEvent("online");
-        }
-
-        // should only fire this once
-        if (channel.onCordovaConnectionReady.state !== 2) {
-            channel.onCordovaConnectionReady.fire();
-        }
-    },
-    function (e) {
-        // If we can't get the network info we should still tell Cordova
-        // to fire the deviceready event.
-        if (channel.onCordovaConnectionReady.state !== 2) {
-            channel.onCordovaConnectionReady.fire();
-        }
-        console.log("Error initializing Network Connection: " + e);
-    });
-});
-
-module.exports = me;
-
-});
-
-// file: lib/common/plugin/networkstatus/symbols.js
-define("cordova/plugin/networkstatus/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/network', 'navigator.network.connection', 'navigator.network.connection is deprecated. Use navigator.connection instead.');
-modulemapper.clobbers('cordova/plugin/network', 'navigator.connection');
-modulemapper.defaults('cordova/plugin/Connection', 'Connection');
-
-});
-
-// file: lib/common/plugin/notification.js
-define("cordova/plugin/notification", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var platform = require('cordova/platform');
-
-/**
- * Provides access to notifications on the device.
- */
-
-module.exports = {
-
-    /**
-     * Open a native alert dialog, with a customizable title and button text.
-     *
-     * @param {String} message              Message to print in the body of the alert
-     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
-     * @param {String} title                Title of the alert dialog (default: Alert)
-     * @param {String} buttonLabel          Label of the close button (default: OK)
-     */
-    alert: function(message, completeCallback, title, buttonLabel) {
-        var _title = (title || "Alert");
-        var _buttonLabel = (buttonLabel || "OK");
-        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);
-    },
-
-    /**
-     * Open a native confirm dialog, with a customizable title and button text.
-     * The result that the user selects is returned to the result callback.
-     *
-     * @param {String} message              Message to print in the body of the alert
-     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
-     * @param {String} title                Title of the alert dialog (default: Confirm)
-     * @param {Array} buttonLabels          Array of the labels of the buttons (default: ['OK', 'Cancel'])
-     */
-    confirm: function(message, resultCallback, title, buttonLabels) {
-        var _title = (title || "Confirm");
-        var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);
-
-        // Strings are deprecated!
-        if (typeof _buttonLabels === 'string') {
-            console.log("Notification.confirm(string, function, string, string) is deprecated.  Use Notification.confirm(string, function, string, array).");
-        }
-
-        // Some platforms take an array of button label names.
-        // Other platforms take a comma separated list.
-        // For compatibility, we convert to the desired type based on the platform.
-        if (platform.id == "android" || platform.id == "ios" || platform.id == "windowsphone" || platform.id == "blackberry10") {
-            if (typeof _buttonLabels === 'string') {
-                var buttonLabelString = _buttonLabels;
-                _buttonLabels = _buttonLabels.split(","); // not crazy about changing the var type here
-            }
-        } else {
-            if (Array.isArray(_buttonLabels)) {
-                var buttonLabelArray = _buttonLabels;
-                _buttonLabels = buttonLabelArray.toString();
-            }
-        }
-        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
-    },
-
-    /**
-     * Open a native prompt dialog, with a customizable title and button text.
-     * The following results are returned to the result callback:
-     *  buttonIndex     Index number of the button selected.
-     *  input1          The text entered in the prompt dialog box.
-     *
-     * @param {String} message              Dialog message to display (default: "Prompt message")
-     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
-     * @param {String} title                Title of the dialog (default: "Prompt")
-     * @param {Array} buttonLabels          Array of strings for the button labels (default: ["OK","Cancel"])
-     * @param {String} defaultText          Textbox input value (default: "Default text")
-     */
-    prompt: function(message, resultCallback, title, buttonLabels, defaultText) {
-        var _message = (message || "Prompt message");
-        var _title = (title || "Prompt");
-        var _buttonLabels = (buttonLabels || ["OK","Cancel"]);
-        var _defaultText = (defaultText || "Default text");
-        exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels, _defaultText]);
-    },
-
-    /**
-     * Causes the device to vibrate.
-     *
-     * @param {Integer} mills       The number of milliseconds to vibrate for.
-     */
-    vibrate: function(mills) {
-        exec(null, null, "Notification", "vibrate", [mills]);
-    },
-
-    /**
-     * Causes the device to beep.
-     * On Android, the default notification ringtone is played "count" times.
-     *
-     * @param {Integer} count       The number of beeps.
-     */
-    beep: function(count) {
-        exec(null, null, "Notification", "beep", [count]);
-    }
-};
-
-});
-
-// file: lib/common/plugin/notification/symbols.js
-define("cordova/plugin/notification/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/notification', 'navigator.notification');
-
-});
-
-// file: lib/common/plugin/requestFileSystem.js
-define("cordova/plugin/requestFileSystem", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    FileError = require('cordova/plugin/FileError'),
-    FileSystem = require('cordova/plugin/FileSystem'),
-    exec = require('cordova/exec');
-
-/**
- * Request a file system in which to store application data.
- * @param type  local file system type
- * @param size  indicates how much storage space, in bytes, the application expects to need
- * @param successCallback  invoked with a FileSystem object
- * @param errorCallback  invoked if error occurs retrieving file system
- */
-var requestFileSystem = function(type, size, successCallback, errorCallback) {
-    argscheck.checkArgs('nnFF', 'requestFileSystem', arguments);
-    var fail = function(code) {
-        errorCallback && errorCallback(new FileError(code));
-    };
-
-    if (type < 0 || type > 3) {
-        fail(FileError.SYNTAX_ERR);
-    } else {
-        // if successful, return a FileSystem object
-        var success = function(file_system) {
-            if (file_system) {
-                if (successCallback) {
-                    // grab the name and root from the file system object
-                    var result = new FileSystem(file_system.name, file_system.root);
-                    successCallback(result);
-                }
-            }
-            else {
-                // no FileSystem object returned
-                fail(FileError.NOT_FOUND_ERR);
-            }
-        };
-        exec(success, fail, "File", "requestFileSystem", [type, size]);
-    }
-};
-
-module.exports = requestFileSystem;
-
-});
-
-// file: lib/common/plugin/resolveLocalFileSystemURI.js
-define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
-    FileEntry = require('cordova/plugin/FileEntry'),
-    FileError = require('cordova/plugin/FileError'),
-    exec = require('cordova/exec');
-
-/**
- * Look up file system Entry referred to by local URI.
- * @param {DOMString} uri  URI referring to a local file or directory
- * @param successCallback  invoked with Entry object corresponding to URI
- * @param errorCallback    invoked if error occurs retrieving file system entry
- */
-module.exports = function(uri, successCallback, errorCallback) {
-    argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments);
-    // error callback
-    var fail = function(error) {
-        errorCallback && errorCallback(new FileError(error));
-    };
-    // sanity check for 'not:valid:filename'
-    if(!uri || uri.split(":").length > 2) {
-        setTimeout( function() {
-            fail(FileError.ENCODING_ERR);
-        },0);
-        return;
-    }
-    // if successful, return either a file or directory entry
-    var success = function(entry) {
-        var result;
-        if (entry) {
-            if (successCallback) {
-                // create appropriate Entry object
-                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
-                successCallback(result);
-            }
-        }
-        else {
-            // no Entry object returned
-            fail(FileError.NOT_FOUND_ERR);
-        }
-    };
-
-    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
-};
-
-});
-
-// file: lib/common/plugin/splashscreen.js
-define("cordova/plugin/splashscreen", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-var splashscreen = {
-    show:function() {
-        exec(null, null, "SplashScreen", "show", []);
-    },
-    hide:function() {
-        exec(null, null, "SplashScreen", "hide", []);
-    }
-};
-
-module.exports = splashscreen;
-
-});
-
-// file: lib/common/plugin/splashscreen/symbols.js
-define("cordova/plugin/splashscreen/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/splashscreen', 'navigator.splashscreen');
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/DOMStorage/plugininit.js
-define("cordova/plugin/windowsphone/DOMStorage/plugininit", function(require, exports, module) {
-
-(function(win,doc) {
-
-var docDomain = null;
-try {
-    docDomain = doc.domain;
-} catch (err) {
-    //console.log("caught exception trying to access document.domain");
-}
-
-// conditionally patch the window.localStorage and window.sessionStorage objects
-if (!docDomain || docDomain.length === 0) {
-
-    var DOMStorage = function(type) {
-        // default type is local
-        if(type == "sessionStorage") {
-            this._type = type;
-        }
-        Object.defineProperty( this, "length", {
-            configurable: true,
-            get: function(){ return this.getLength(); }
-        });
-    };
-
-    DOMStorage.prototype = {
-        _type:"localStorage",
-        _result:null,
-        keys:null,
-
-        onResult:function(key,valueStr) {
-            if(!this.keys) {
-                this.keys = [];
-            }
-            this._result = valueStr;
-        },
-
-        onKeysChanged:function(jsonKeys) {
-            this.keys = JSON.parse(jsonKeys);
-
-            var key;
-            for(var n = 0,len = this.keys.length; n < len; n++) {
-                key = this.keys[n];
-                if(!this.hasOwnProperty(key)) {
-                    Object.defineProperty( this, key, {
-                        configurable: true,
-                        get: function(){ return this.getItem(key); },
-                        set: function(val){ return this.setItem(key,val); }
-                    });
-                }
-            }
-
-        },
-
-        initialize:function() {
-            window.external.Notify("DOMStorage/" + this._type + "/load/keys");
-        },
-
-    /*
-        The length attribute must return the number of key/value pairs currently present
-        in the list associated with the object.
-    */
-        getLength:function() {
-            if(!this.keys) {
-                this.initialize();
-            }
-            return this.keys.length;
-        },
-
-    /*
-        The key(n) method must return the name of the nth key in the list.
-        The order of keys is user-agent defined, but must be consistent within an object so long as the number of keys doesn't change.
-        (Thus, adding or removing a key may change the order of the keys, but merely changing the value of an existing key must not.)
-        If n is greater than or equal to the number of key/value pairs in the object, then this method must return null.
-    */
-        key:function(n) {
-            if(!this.keys) {
-                this.initialize();
-            }
-
-            if(n >= this.keys.length) {
-                return null;
-            } else {
-                return this.keys[n];
-            }
-        },
-
-    /*
-        The getItem(key) method must return the current value associated with the given key.
-        If the given key does not exist in the list associated with the object then this method must return null.
-    */
-        getItem:function(key) {
-            if(!this.keys) {
-                this.initialize();
-            }
-
-            var retVal = null;
-            if(this.keys.indexOf(key) > -1) {
-                window.external.Notify("DOMStorage/" + this._type + "/get/" + key);
-                retVal = window.unescape(decodeURIComponent(this._result));
-                this._result = null;
-            }
-            return retVal;
-        },
-    /*
-        The setItem(key, value) method must first check if a key/value pair with the given key already exists
-        in the list associated with the object.
-        If it does not, then a new key/value pair must be added to the list, with the given key and with its value set to value.
-        If the given key does exist in the list, then it must have its value updated to value.
-        If it couldn't set the new value, the method must raise an QUOTA_EXCEEDED_ERR exception.
-        (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.)
-    */
-        setItem:function(key,value) {
-            if(!this.keys) {
-                this.initialize();
-            }
-            window.external.Notify("DOMStorage/" + this._type + "/set/" + key + "/" + encodeURIComponent(window.escape(value)));
-        },
-
-    /*
-        The removeItem(key) method must cause the key/value pair with the given key to be removed from the list
-        associated with the object, if it exists.
-        If no item with that key exists, the method must do nothing.
-    */
-        removeItem:function(key) {
-            if(!this.keys) {
-                this.initialize();
-            }
-            var index = this.keys.indexOf(key);
-            if(index > -1) {
-                this.keys.splice(index,1);
-                // TODO: need sanity check for keys ? like 'clear','setItem', ...
-                window.external.Notify("DOMStorage/" + this._type + "/remove/" + key);
-                delete this[key];
-            }
-        },
-
-    /*
-        The clear() method must atomically cause the list associated with the object to be emptied of all
-        key/value pairs, if there are any.
-        If there are none, then the method must do nothing.
-    */
-        clear:function() {
-            if(!this.keys) {
-                this.initialize();
-            }
-
-            for(var n=0,len=this.keys.length; n < len;n++) {
-                // TODO: do we need a sanity check for keys ? like 'clear','setItem', ...
-                delete this[this.keys[n]];
-            }
-            this.keys = [];
-            window.external.Notify("DOMStorage/" + this._type + "/clear/");
-        }
-    };
-
-    // initialize DOMStorage
-
-    if (typeof window.localStorage === "undefined") {
-
-        Object.defineProperty(window, "localStorage", {
-            writable: false,
-            configurable: false,
-            value: new DOMStorage("localStorage")
-        });
-        window.localStorage.initialize();
-    }
-
-    if (typeof window.sessionStorage === "undefined") {
-        Object.defineProperty(window, "sessionStorage", {
-            writable: false,
-            configurable: false,
-            value: new DOMStorage("sessionStorage")
-        });
-        window.sessionStorage.initialize();
-    }
-}
-
-})(window, document);
-
-module.exports = null;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/FileTransfer.js
-define("cordova/plugin/windowsphone/FileTransfer", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    FileTransferError = require('cordova/plugin/FileTransferError');
-
-// Note that the only difference between this and the default implementation is the
-// object literal passed to exec() in upload - jm
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String}           Full path of the file on the device
-* @param server {String}             URL of the server to receive the file
-* @param successCallback (Function}  Callback to be invoked when upload has completed
-* @param errorCallback {Function}    Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
-
-    // sanity parameter checking
-    if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum.");
-    // check for options
-    var fileKey = null;
-    var fileName = null;
-    var mimeType = null;
-    var params = null;
-    var chunkedMode = true;
-
-    if (options) {
-        fileKey = options.fileKey;
-        fileName = options.fileName;
-        mimeType = options.mimeType;
-        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
-            chunkedMode = options.chunkedMode;
-        }
-
-        // if options are specified, and NOT a string already, we will stringify it.
-        if(options.params && typeof options.params != typeof "") {
-            var arrParams = [];
-            for(var v in options.params) {
-                arrParams.push(v + "=" + options.params[v]);
-            }
-            params = encodeURI(arrParams.join("&"));
-        }
-    }
-
-    var fail = function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
-        errorCallback(error);
-    };
-    exec(successCallback, fail, 'FileTransfer', 'upload', [{"filePath":filePath,
-                                                              "server":server,
-                                                              "fileKey":fileKey,
-                                                              "fileName":fileName,
-                                                              "mimeType":mimeType,
-                                                              "params":params,
-                                                              "trustAllHosts":trustAllHosts,
-                                                              "chunkedMode":chunkedMode}]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String}          URL of the server to receive the file
- * @param target {String}         Full path of the file on the device
- * @param successCallback (Function}  Callback to be invoked when upload has completed
- * @param errorCallback {Function}    Callback to be invoked upon error
- */
-
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {
-    // sanity parameter checking
-    if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum.");
-    var win = function(result) {
-        var entry = null;
-        if (result.isDirectory) {
-            entry = new (require('cordova/plugin/DirectoryEntry'))();
-        }
-        else if (result.isFile) {
-            entry = new (require('cordova/plugin/FileEntry'))();
-        }
-        entry.isDirectory = result.isDirectory;
-        entry.isFile = result.isFile;
-        entry.name = result.name;
-        entry.fullPath = result.fullPath;
-        successCallback(entry);
-    };
-
-    var fail = function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
-        errorCallback(error);
-    };
-
-    exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);
-};
-
-
-module.exports = FileTransfer;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/FileUploadOptions.js
-define("cordova/plugin/windowsphone/FileUploadOptions", function(require, exports, module) {
-
-/**
- * Options to customize the HTTP request used to upload files.
- * @constructor
- * @param fileKey {String}   Name of file request parameter.
- * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
- * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
- * @param params {Object}    Object with key: value params to send to the server.
- */
-var FileUploadOptions = function(fileKey, fileName, mimeType, params) {
-    this.fileKey = fileKey || null;
-    this.fileName = fileName || null;
-    this.mimeType = mimeType || null;
-
-    if(params && typeof params != typeof "") {
-        var arrParams = [];
-        for(var v in params) {
-            arrParams.push(v + "=" + params[v]);
-        }
-        this.params = encodeURIComponent(arrParams.join("&"));
-    }
-    else {
-        this.params = params || null;
-    }
-};
-
-module.exports = FileUploadOptions;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/XHRPatch/plugininit.js
-define("cordova/plugin/windowsphone/XHRPatch/plugininit", function(require, exports, module) {
-
-// TODO: the build process will implicitly wrap this in a define() call
-// with a closure of its own; do you need this extra closure?
-
-var LocalFileSystem = require('cordova/plugin/LocalFileSystem');
-
-(function (win, doc) {
-
-var docDomain = null;
-try {
-    docDomain = doc.domain;
-} catch (err) {
-    //console.log("caught exception trying to access document.domain");
-}
-
-if (!docDomain || docDomain.length === 0) {
-
-    var aliasXHR = win.XMLHttpRequest;
-
-    win.XMLHttpRequest = function () { };
-    win.XMLHttpRequest.noConflict = aliasXHR;
-    win.XMLHttpRequest.UNSENT = 0;
-    win.XMLHttpRequest.OPENED = 1;
-    win.XMLHttpRequest.HEADERS_RECEIVED = 2;
-    win.XMLHttpRequest.LOADING = 3;
-    win.XMLHttpRequest.DONE = 4;
-
-    win.XMLHttpRequest.prototype = {
-        UNSENT: 0,
-        OPENED: 1,
-        HEADERS_RECEIVED: 2,
-        LOADING: 3,
-        DONE: 4,
-
-        isAsync: false,
-        onreadystatechange: null,
-        readyState: 0,
-        _url: "",
-        timeout: 0,
-        withCredentials: false,
-        _requestHeaders: null,
-        open: function (reqType, uri, isAsync, user, password) {
-
-            if (uri && uri.indexOf("http") === 0) {
-                if (!this.wrappedXHR) {
-                    this.wrappedXHR = new aliasXHR();
-                    var self = this;
-
-                    // timeout
-                    if (this.timeout > 0) {
-                        this.wrappedXHR.timeout = this.timeout;
-                    }
-                    Object.defineProperty(this, "timeout", {
-                        set: function (val) {
-                            this.wrappedXHR.timeout = val;
-                        },
-                        get: function () {
-                            return this.wrappedXHR.timeout;
-                        }
-                    });
-
-
-
-                    if (this.withCredentials) {
-                        this.wrappedXHR.withCredentials = this.withCredentials;
-                    }
-                    Object.defineProperty(this, "withCredentials", {
-                        set: function (val) {
-                            this.wrappedXHR.withCredentials = val;
-                        },
-                        get: function () {
-                            return this.wrappedXHR.withCredentials;
-                        }
-                    });
-
-
-                    Object.defineProperty(this, "status", { get: function () {
-                        return this.wrappedXHR.status;
-                    }
-                    });
-                    Object.defineProperty(this, "responseText", { get: function () {
-                        return this.wrappedXHR.responseText;
-                    }
-                    });
-                    Object.defineProperty(this, "statusText", { get: function () {
-                        return this.wrappedXHR.statusText;
-                    }
-                    });
-
-                    Object.defineProperty(this, "responseXML", { get: function () {
-                        return this.wrappedXHR.responseXML;
-                    }
-                    });
-
-                    this.getResponseHeader = function (header) {
-                        return this.wrappedXHR.getResponseHeader(header);
-                    };
-                    this.getAllResponseHeaders = function () {
-                        return this.wrappedXHR.getAllResponseHeaders();
-                    };
-
-                    this.wrappedXHR.onreadystatechange = function () {
-                        self.changeReadyState(self.wrappedXHR.readyState);
-                    };
-                }
-                return this.wrappedXHR.open(reqType, uri, isAsync, user, password);
-            }
-            else {
-                // x-wmapp1://app/www/page2.html
-                // need to work some magic on the actual url/filepath
-                var newUrl = uri;
-                if (newUrl.indexOf(":/") > -1) {
-                    newUrl = newUrl.split(":/")[1];
-                }
-                // prefix relative urls to our physical root
-                if(newUrl.indexOf("app/www/") < 0 && this.getContentLocation() == this.contentLocation.ISOLATED_STORAGE)
-                {
-                    newUrl = "app/www/" + newUrl;
-                }
-
-                if (newUrl.lastIndexOf("/") === newUrl.length - 1) {
-                    newUrl += "index.html"; // default page is index.html, when call is to a dir/ ( why not ...? )
-                }
-                this._url = newUrl;
-            }
-        },
-        statusText: "",
-        changeReadyState: function (newState) {
-            this.readyState = newState;
-            if (this.onreadystatechange) {
-                this.onreadystatechange();
-            }
-        },
-        setRequestHeader: function (header, value) {
-            if (this.wrappedXHR) {
-                this.wrappedXHR.setRequestHeader(header, value);
-            }
-        },
-        getResponseHeader: function (header) {
-            return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : "";
-        },
-        getAllResponseHeaders: function () {
-            return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : "";
-        },
-        responseText: "",
-        responseXML: "",
-        onResult: function (res) {
-            this.status = 200;
-            if(typeof res == "object")
-            {   // callback result handler may have already parsed this from a string-> a JSON object,
-                // if so, we need to restore its stringyness, as handlers are expecting string data.
-                // especially if used with jQ -> $.getJSON
-                res = JSON.stringify(res);
-            }
-            this.responseText = res;
-            this.responseXML = res;
-            this.changeReadyState(this.DONE);
-        },
-        onError: function (err) {
-            this.status = 404;
-            this.changeReadyState(this.DONE);
-        },
-
-        abort: function () {
-            if (this.wrappedXHR) {
-                return this.wrappedXHR.abort();
-            }
-        },
-
-        send: function (data) {
-            if (this.wrappedXHR) {
-                return this.wrappedXHR.send(data);
-            }
-            else {
-                this.changeReadyState(this.OPENED);
-
-                var alias = this;
-
-                var fail = function fail(evt) {
-                    alias.onError(evt.code);
-                };
-
-                if (alias.getContentLocation() == this.contentLocation.RESOURCES) {
-                    var exec = require('cordova/exec');
-                    exec(function(result) {
-                            alias.onResult.apply(alias, [result]);
-                        },
-                        fail,
-                        "File", "readResourceAsText", [alias._url]
-                    );
-                }
-                else {
-                    var gotFile = function gotFile(file) {
-                        var reader = new FileReader();
-                        reader.onloadend = function (evt) {
-                            alias.onResult.apply(alias,[evt.target.result]);
-                        };
-                        reader.readAsText(file);
-                    };
-
-                    var gotEntry = function gotEntry(entry) {
-                        entry.file(gotFile, fail);
-                    };
-
-                    var gotFS = function gotFS(fs) {
-                        fs.root.getFile(alias._url, null, gotEntry, fail);
-                    };
-
-                    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
-                }
-            }
-        },
-
-        getContentLocation: function () {
-            if (window.contentLocation === undefined) {
-                window.contentLocation = (navigator.userAgent.toUpperCase().indexOf('MSIE 10') > -1) ?
-                    this.contentLocation.RESOURCES : this.contentLocation.ISOLATED_STORAGE;
-            }
-
-            return window.contentLocation;
-        },
-
-        contentLocation:{
-            ISOLATED_STORAGE: 0,
-            RESOURCES: 1
-        },
-
-        status: 404
-    };
-} // if doc domain
-
-// end closure wrap
-})(window, document);
-
-module.exports = null;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/console.js
-define("cordova/plugin/windowsphone/console", function(require, exports, module) {
-
-
-var exec = require('cordova/exec'),
-    channel = require('cordova/channel');
-var cordova = require("cordova");
-
-var debugConsole = {
-    log:function(msg){
-        exec(null,null,"DebugConsole","log",msg);
-    },
-    warn:function(msg){
-        exec(null,null,"DebugConsole","warn",msg);
-    },
-    error:function(msg){
-        exec(null,null,"DebugConsole","error",msg);
-    }
-};
-
-var oldOnError = window.onerror;
-window.onerror = function(msg,fileName,line) {
-    oldOnError && oldOnError(msg,fileName,line);
-    debugConsole.error(msg + " file:" + fileName + " Line:" + line);
-};
-
-module.exports = debugConsole;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/console/symbols.js
-define("cordova/plugin/windowsphone/console/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/windowsphone/console', 'navigator.console');
-modulemapper.clobbers('cordova/plugin/windowsphone/console', 'console');
-
-});
-
-// file: lib/common/symbols.js
-define("cordova/symbols", function(require, exports, module) {
-
-var modulemapper = require('cordova/modulemapper');
-
-// Use merges here in case others symbols files depend on this running first,
-// but fail to declare the dependency with a require().
-modulemapper.merges('cordova', 'cordova');
-modulemapper.clobbers('cordova/exec', 'cordova.exec');
-modulemapper.clobbers('cordova/exec', 'Cordova.exec');
-
-});
-
-// file: lib/common/utils.js
-define("cordova/utils", function(require, exports, module) {
-
-var utils = exports;
-
-/**
- * Defines a property getter / setter for obj[key].
- */
-utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
-    if (Object.defineProperty) {
-        var desc = {
-            get: getFunc,
-            configurable: true
-        };
-        if (opt_setFunc) {
-            desc.set = opt_setFunc;
-        }
-        Object.defineProperty(obj, key, desc);
-    } else {
-        obj.__defineGetter__(key, getFunc);
-        if (opt_setFunc) {
-            obj.__defineSetter__(key, opt_setFunc);
-        }
-    }
-};
-
-/**
- * Defines a property getter for obj[key].
- */
-utils.defineGetter = utils.defineGetterSetter;
-
-utils.arrayIndexOf = function(a, item) {
-    if (a.indexOf) {
-        return a.indexOf(item);
-    }
-    var len = a.length;
-    for (var i = 0; i < len; ++i) {
-        if (a[i] == item) {
-            return i;
-        }
-    }
-    return -1;
-};
-
-/**
- * Returns whether the item was found in the array.
- */
-utils.arrayRemove = function(a, item) {
-    var index = utils.arrayIndexOf(a, item);
-    if (index != -1) {
-        a.splice(index, 1);
-    }
-    return index != -1;
-};
-
-utils.typeName = function(val) {
-    return Object.prototype.toString.call(val).slice(8, -1);
-};
-
-/**
- * Returns an indication of whether the argument is an array or not
- */
-utils.isArray = function(a) {
-    return utils.typeName(a) == 'Array';
-};
-
-/**
- * Returns an indication of whether the argument is a Date or not
- */
-utils.isDate = function(d) {
-    return utils.typeName(d) == 'Date';
-};
-
-/**
- * Does a deep clone of the object.
- */
-utils.clone = function(obj) {
-    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
-        return obj;
-    }
-
-    var retVal, i;
-
-    if(utils.isArray(obj)){
-        retVal = [];
-        for(i = 0; i < obj.length; ++i){
-            retVal.push(utils.clone(obj[i]));
-        }
-        return retVal;
-    }
-
-    retVal = {};
-    for(i in obj){
-        if(!(i in retVal) || retVal[i] != obj[i]) {
-            retVal[i] = utils.clone(obj[i]);
-        }
-    }
-    return retVal;
-};
-
-/**
- * Returns a wrapped version of the function
- */
-utils.close = function(context, func, params) {
-    if (typeof params == 'undefined') {
-        return function() {
-            return func.apply(context, arguments);
-        };
-    } else {
-        return function() {
-            return func.apply(context, params);
-        };
-    }
-};
-
-/**
- * Create a UUID
- */
-utils.createUUID = function() {
-    return UUIDcreatePart(4) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(6);
-};
-
-/**
- * Extends a child object from a parent object using classical inheritance
- * pattern.
- */
-utils.extend = (function() {
-    // proxy used to establish prototype chain
-    var F = function() {};
-    // extend Child from Parent
-    return function(Child, Parent) {
-        F.prototype = Parent.prototype;
-        Child.prototype = new F();
-        Child.__super__ = Parent.prototype;
-        Child.prototype.constructor = Child;
-    };
-}());
-
-/**
- * Alerts a message in any available way: alert or console.log.
- */
-utils.alert = function(msg) {
-    if (window.alert) {
-        window.alert(msg);
-    } else if (console && console.log) {
-        console.log(msg);
-    }
-};
-
-
-//------------------------------------------------------------------------------
-function UUIDcreatePart(length) {
-    var uuidpart = "";
-    for (var i=0; i<length; i++) {
-        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
-        if (uuidchar.length == 1) {
-            uuidchar = "0" + uuidchar;
-        }
-        uuidpart += uuidchar;
-    }
-    return uuidpart;
-}
-
-
-});
-
-window.cordova = require('cordova');
-// file: lib/scripts/bootstrap.js
-
-(function (context) {
-    if (context._cordovaJsLoaded) {
-        throw new Error('cordova.js included multiple times.');
-    }
-    context._cordovaJsLoaded = true;
-
-    var channel = require('cordova/channel');
-    var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
-
-    function logUnfiredChannels(arr) {
-        for (var i = 0; i < arr.length; ++i) {
-            if (arr[i].state != 2) {
-                console.log('Channel not fired: ' + arr[i].type);
-            }
-        }
-    }
-
-    window.setTimeout(function() {
-        if (channel.onDeviceReady.state != 2) {
-            console.log('deviceready has not fired after 5 seconds.');
-            logUnfiredChannels(platformInitChannelsArray);
-            logUnfiredChannels(channel.deviceReadyChannelsArray);
-        }
-    }, 5000);
-
-    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
-    // We replace it so that properties that can't be clobbered can instead be overridden.
-    function replaceNavigator(origNavigator) {
-        var CordovaNavigator = function() {};
-        CordovaNavigator.prototype = origNavigator;
-        var newNavigator = new CordovaNavigator();
-        // This work-around really only applies to new APIs that are newer than Function.bind.
-        // Without it, APIs such as getGamepads() break.
-        if (CordovaNavigator.bind) {
-            for (var key in origNavigator) {
-                if (typeof origNavigator[key] == 'function') {
-                    newNavigator[key] = origNavigator[key].bind(origNavigator);
-                }
-            }
-        }
-        return newNavigator;
-    }
-    if (context.navigator) {
-        context.navigator = replaceNavigator(context.navigator);
-    }
-
-    // _nativeReady is global variable that the native side can set
-    // to signify that the native code is ready. It is a global since
-    // it may be called before any cordova JS is ready.
-    if (window._nativeReady) {
-        channel.onNativeReady.fire();
-    }
-
-    /**
-     * Create all cordova objects once native side is ready.
-     */
-    channel.join(function() {
-        // Call the platform-specific initialization
-        require('cordova/platform').initialize();
-
-        // Fire event to notify that all objects are created
-        channel.onCordovaReady.fire();
-
-        // Fire onDeviceReady event once page has fully loaded, all
-        // constructors have run and cordova info has been received from native
-        // side.
-        // This join call is deliberately made after platform.initialize() in
-        // order that plugins may manipulate channel.deviceReadyChannelsArray
-        // if necessary.
-        channel.join(function() {
-            require('cordova').fireDocumentEvent('deviceready');
-        }, channel.deviceReadyChannelsArray);
-
-    }, platformInitChannelsArray);
-
-}(window));
-
-// file: lib/scripts/plugin_loader.js
-
-// Tries to load all plugins' js-modules.
-// This is an async process, but onDeviceReady is blocked on onPluginsReady.
-// onPluginsReady is fired when there are no plugins to load, or they are all done.
-(function (context) {
-    // To be populated with the handler by handlePluginsObject.
-    var onScriptLoadingComplete;
-
-    var scriptCounter = 0;
-    function scriptLoadedCallback() {
-        scriptCounter--;
-        if (scriptCounter === 0) {
-            onScriptLoadingComplete && onScriptLoadingComplete();
-        }
-    }
-
-    function scriptErrorCallback(err) {
-        // Open Question: If a script path specified in cordova_plugins.js does not exist, do we fail for all?
-        // this is currently just continuing.
-        scriptCounter--;
-        if (scriptCounter === 0) {
-            onScriptLoadingComplete && onScriptLoadingComplete();
-        }
-    }
-
-    // Helper function to inject a <script> tag.
-    function injectScript(path) {
-        scriptCounter++;
-        var script = document.createElement("script");
-        script.onload = scriptLoadedCallback;
-        script.onerror = scriptErrorCallback;
-        script.src = path;
-        document.head.appendChild(script);
-    }
-
-    // Called when:
-    // * There are plugins defined and all plugins are finished loading.
-    // * There are no plugins to load.
-    function finishPluginLoading() {
-        context.cordova.require('cordova/channel').onPluginsReady.fire();
-    }
-
-    // Handler for the cordova_plugins.js content.
-    // See plugman's plugin_loader.js for the details of this object.
-    // This function is only called if the really is a plugins array that isn't empty.
-    // Otherwise the onerror response handler will just call finishPluginLoading().
-    function handlePluginsObject(modules, path) {
-        // First create the callback for when all plugins are loaded.
-        var mapper = context.cordova.require('cordova/modulemapper');
-        onScriptLoadingComplete = function() {
-            // Loop through all the plugins and then through their clobbers and merges.
-            for (var i = 0; i < modules.length; i++) {
-                var module = modules[i];
-                if (module) {
-                    try { 
-                        if (module.clobbers && module.clobbers.length) {
-                            for (var j = 0; j < module.clobbers.length; j++) {
-                                mapper.clobbers(module.id, module.clobbers[j]);
-                            }
-                        }
-
-                        if (module.merges && module.merges.length) {
-                            for (var k = 0; k < module.merges.length; k++) {
-                                mapper.merges(module.id, module.merges[k]);
-                            }
-                        }
-
-                        // Finally, if runs is truthy we want to simply require() the module.
-                        // This can be skipped if it had any merges or clobbers, though,
-                        // since the mapper will already have required the module.
-                        if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
-                            context.cordova.require(module.id);
-                        }
-                    }
-                    catch(err) {
-                        // error with module, most likely clobbers, should we continue?
-                    }
-                }
-            }
-
-            finishPluginLoading();
-        };
-
-        // Now inject the scripts.
-        for (var i = 0; i < modules.length; i++) {
-            injectScript(path + modules[i].file);
-        }
-    }
-
-    // Find the root of the app
-    var path = '';
-    var scripts = document.getElementsByTagName('script');
-    var term = 'cordova.js';
-    for (var n = scripts.length-1; n>-1; n--) {
-        var src = scripts[n].src;
-        if (src.indexOf(term) == (src.length - term.length)) {
-            path = src.substring(0, src.length - term.length);
-            break;
-        }
-    }
-
-    var plugins_json = path + 'cordova_plugins.json';
-    var plugins_js = path + 'cordova_plugins.js';
-
-    // One some phones (Windows) this xhr.open throws an Access Denied exception
-    // So lets keep trying, but with a script tag injection technique instead of XHR
-    var injectPluginScript = function injectPluginScript() {
-        try {
-            var script = document.createElement("script");
-            script.onload = function(){
-                var list = cordova.require("cordova/plugin_list");
-                handlePluginsObject(list,path);
-            };
-            script.onerror = function() {
-                // Error loading cordova_plugins.js, file not found or something
-                // this is an acceptable error, pre-3.0.0, so we just move on.
-                finishPluginLoading();
-            };
-            script.src = plugins_js;
-            document.head.appendChild(script);
-
-        } catch(err){
-            finishPluginLoading();
-        }
-    } 
-
-
-    // Try to XHR the cordova_plugins.json file asynchronously.
-    var xhr = new XMLHttpRequest();
-    xhr.onload = function() {
-        // If the response is a JSON string which composes an array, call handlePluginsObject.
-        // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
-        var obj;
-        try {
-            obj = (this.status == 0 || this.status == 200) && this.responseText && JSON.parse(this.responseText);
-        } catch (err) {
-            // obj will be undefined.
-        }
-        if (Array.isArray(obj) && obj.length > 0) {
-            handlePluginsObject(obj, path);
-        } else {
-            finishPluginLoading();
-        }
-    };
-    xhr.onerror = function() {
-        // In this case, the json file was not present, but XHR was allowed, 
-        // so we should still try the script injection technique with the js file
-        // in case that is there.
-        injectPluginScript();
-    };
-    try { // we commented we were going to try, so let us actually try and catch
-        xhr.open('GET', plugins_json, true); // Async
-        xhr.send();
-    } catch(err){
-        injectPluginScript();
-    }
-}(window));
-
-
-})();
\ No newline at end of file
diff --git a/templates/standalone/www/css/index.css b/templates/standalone/www/css/index.css
deleted file mode 100644
index 1d34d88..0000000
--- a/templates/standalone/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-* {
-    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
-    -webkit-text-size-adjust: none;             /* prevent WebKit from resizing text to fit */
-    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
-    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
-}
-
-body {
-    background-color:#E4E4E4;
-    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-gradient(
-        linear,
-        left top,
-        left bottom,
-        color-stop(0, #A7A7A7),
-        color-stop(0.51, #E4E4E4)
-    );
-    background-attachment:fixed;
-    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
-    font-size:12px;
-    height:100%;
-    margin:0px;
-    padding:0px;
-    text-transform:uppercase;
-    width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
-    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
-    position:absolute;             /* position in the center of the screen */
-    left:50%;
-    top:50%;
-    height:50px;                   /* text area height */
-    width:225px;                   /* text area width */
-    text-align:center;
-    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
-    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
-                                   /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
-    .app {
-        background-position:left center;
-        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
-        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
-                                      /* offset horizontal: half of image width and text area width */
-    }
-}
-
-h1 {
-    font-size:24px;
-    font-weight:normal;
-    margin:0px;
-    overflow:visible;
-    padding:0px;
-    text-align:center;
-}
-
-.event {
-    border-radius:4px;
-    -webkit-border-radius:4px;
-    color:#FFFFFF;
-    font-size:12px;
-    margin:0px 30px;
-    padding:2px 0px;
-}
-
-.event.listening {
-    background-color:#333333;
-    display:block;
-}
-
-.event.received {
-    background-color:#4B946A;
-    display:none;
-}
-
-@keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-@-webkit-keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-.blink {
-    animation:fade 3000ms infinite;
-    -webkit-animation:fade 3000ms infinite;
-}
diff --git a/templates/standalone/www/img/logo.png b/templates/standalone/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
--- a/templates/standalone/www/img/logo.png
+++ /dev/null
Binary files differ
diff --git a/templates/standalone/www/index.html b/templates/standalone/www/index.html
deleted file mode 100644
index e8fb3e5..0000000
--- a/templates/standalone/www/index.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<!--
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
--->
-<html>
-    <head>
-        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-        <meta name="format-detection" content="telephone=no" />
-        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
-        <link rel="stylesheet" type="text/css" href="css/index.css" />
-        <title>Hello World</title>
-    </head>
-    <body>
-        <div class="app">
-            <h1>Apache Cordova</h1>
-            <div id="deviceready" class="blink">
-                <p class="event listening">Connecting to Device</p>
-                <p class="event received">Device is Ready</p>
-            </div>
-        </div>
-        <script type="text/javascript" src="cordova.js"></script>
-        <script type="text/javascript" src="js/index.js"></script>
-        <script type="text/javascript">
-            app.initialize();
-        </script>
-    </body>
-</html>
diff --git a/templates/standalone/www/js/index.js b/templates/standalone/www/js/index.js
deleted file mode 100644
index bf02e98..0000000
--- a/templates/standalone/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-var app = {
-    // Application Constructor
-    initialize: function() {
-        this.bindEvents();
-    },
-    // Bind Event Listeners
-    //
-    // Bind any events that are required on startup. Common events are:
-    // `load`, `deviceready`, `offline`, and `online`.
-    bindEvents: function() {
-        document.addEventListener('deviceready', this.onDeviceReady, false);
-    },
-    // deviceready Event Handler
-    //
-    // The scope of `this` is the event. In order to call the `receivedEvent`
-    // function, we must explicitly call `app.receivedEvent(...);`
-    onDeviceReady: function() {
-        app.receivedEvent('deviceready');
-    },
-    // Update DOM on a Received Event
-    receivedEvent: function(id) {
-        var parentElement = document.getElementById(id);
-        var listeningElement = parentElement.querySelector('.listening');
-        var receivedElement = parentElement.querySelector('.received');
-
-        listeningElement.setAttribute('style', 'display:none;');
-        receivedElement.setAttribute('style', 'display:block;');
-
-        console.log('Received Event: ' + id);
-    }
-};
diff --git a/templates/vs/MyTemplateStandAlone.vstemplate b/templates/vs/MyTemplateStandAlone.vstemplate
deleted file mode 100644
index 22ace38..0000000
--- a/templates/vs/MyTemplateStandAlone.vstemplate
+++ /dev/null
@@ -1,143 +0,0 @@
-<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
-  <TemplateData>
-    <Name>CordovaWP7_2_9_0</Name>
-    <Description>Cordova 2.9.0 for Windows Phone 7.5 using the Cordova source code directly.</Description>
-    <ProjectType>CSharp</ProjectType>
-    <ProjectSubType>
-    </ProjectSubType>
-    <SortOrder>1000</SortOrder>
-    <CreateNewFolder>true</CreateNewFolder>
-    <DefaultName>CordovaWP7_2_9_0</DefaultName>
-    <ProvideDefaultName>true</ProvideDefaultName>
-    <LocationField>Enabled</LocationField>
-    <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
-    <Icon>__TemplateIcon.png</Icon>
-    <PreviewImage>__PreviewImage.jpg</PreviewImage>
-  </TemplateData>
-  <TemplateContent>
-    <Project TargetFileName="CordovaAppProj.csproj" File="CordovaAppProj.csproj" ReplaceParameters="true">
-      <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs">App.xaml.cs</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="ApplicationIcon.png">ApplicationIcon.png</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="Background.png">Background.png</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="BuildManifestProcessor.js">BuildManifestProcessor.js</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="config.xml">config.xml</ProjectItem>
-      <Folder Name="cordovalib" TargetFolderName="cordovalib">
-        <ProjectItem ReplaceParameters="true" TargetFileName="BaseCommand.cs">BaseCommand.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="BrowserMouseHelper.cs">BrowserMouseHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CommandFactory.cs">CommandFactory.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ConfigHandler.cs">ConfigHandler.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaCommandCall.cs">CordovaCommandCall.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml">CordovaView.xaml</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml.cs">CordovaView.xaml.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="DOMStorageHelper.cs">DOMStorageHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ImageExifHelper.cs">ImageExifHelper.cs</ProjectItem>
-        <Folder Name="JSON" TargetFolderName="JSON">
-          <ProjectItem ReplaceParameters="true" TargetFileName="JsonHelper.cs">JsonHelper.cs</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="true" TargetFileName="NativeExecution.cs">NativeExecution.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="OrientationHelper.cs">OrientationHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="PluginResult.cs">PluginResult.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ScriptCallback.cs">ScriptCallback.cs</ProjectItem>
-      </Folder>
-      <ProjectItem ReplaceParameters="true" TargetFileName="CordovaSourceDictionary.xml">CordovaSourceDictionary.xml</ProjectItem>
-      <Folder Name="Images" TargetFolderName="Images">
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.back.rest.png">appbar.back.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.close.rest.png">appbar.close.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.feature.video.rest.png">appbar.feature.video.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.next.rest.png">appbar.next.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.save.rest.png">appbar.save.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.stop.rest.png">appbar.stop.rest.png</ProjectItem>
-      </Folder>
-      <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml.cs">MainPage.xaml.cs</ProjectItem>
-      <Folder Name="Plugins" TargetFolderName="Plugins">
-        <ProjectItem ReplaceParameters="true" TargetFileName="Accelerometer.cs">Accelerometer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AudioFormatsHelper.cs">AudioFormatsHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AudioPlayer.cs">AudioPlayer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Battery.cs">Battery.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Camera.cs">Camera.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Capture.cs">Capture.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Compass.cs">Compass.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Contacts.cs">Contacts.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="DebugConsole.cs">DebugConsole.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Device.cs">Device.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="File.cs">File.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="FileTransfer.cs">FileTransfer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="GeoLocation.cs">GeoLocation.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Globalization.cs">Globalization.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="InAppBrowser.cs">InAppBrowser.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Media.cs">Media.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="MimeTypeMapper.cs">MimeTypeMapper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="NetworkStatus.cs">NetworkStatus.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Notification.cs">Notification.cs</ProjectItem>
-        <Folder Name="UI" TargetFolderName="UI">
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioCaptureTask.cs">AudioCaptureTask.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml">AudioRecorder.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml.cs">AudioRecorder.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml">ImageCapture.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml.cs">ImageCapture.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml">NotificationBox.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml.cs">NotificationBox.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoCaptureTask.cs">VideoCaptureTask.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml">VideoRecorder.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml.cs">VideoRecorder.xaml.cs</ProjectItem>
-        </Folder>
-      </Folder>
-      <Folder Name="Properties" TargetFolderName="Properties">
-        <ProjectItem ReplaceParameters="true" TargetFileName="AppManifest.xml">AppManifest.xml</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="WMAppManifest.xml">WMAppManifest.xml</ProjectItem>
-      </Folder>
-      <Folder Name="resources" TargetFolderName="resources">
-        <ProjectItem ReplaceParameters="false" TargetFileName="notification-beep.wav">notification-beep.wav</ProjectItem>
-      </Folder>
-      <Folder Name="Service References" TargetFolderName="Service References" />
-      <ProjectItem ReplaceParameters="false" TargetFileName="SplashScreenImage.jpg">SplashScreenImage.jpg</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="VERSION">VERSION</ProjectItem>
-      <Folder Name="www" TargetFolderName="www">
-        <ProjectItem ReplaceParameters="true" TargetFileName="cordova.js">cordova.js</ProjectItem>
-        <Folder Name="css" TargetFolderName="css">
-          <ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
-        </Folder>
-        <Folder Name="img" TargetFolderName="img">
-          <ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
-        <Folder Name="js" TargetFolderName="js">
-          <ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
-        </Folder>
-      </Folder>
-      <Folder Name="cordova" TargetFolderName="cordova">
-        <ProjectItem ReplaceParameters="false" TargetFileName="build.bat">build.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="clean.bat">clean.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="log.bat">log.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="run.bat">run.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="version.bat">version.bat</ProjectItem>
-        <Folder Name="lib" TargetFolderName="lib">
-          <ProjectItem ReplaceParameters="false" TargetFileName="build.js">build.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="clean.js">clean.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="deploy.js">deploy.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="install-device.bat">install-device.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="install-emulator.bat">install-emulator.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-devices.bat">list-devices.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-emulator-images.bat">list-emulator-images.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-started-emulators.bat">list-started-emulators.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="log.js">log.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="start-emulator.bat">start-emulator.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="target-list.js">target-list.js</ProjectItem>
-          <Folder Name="CordovaDeploy" TargetFolderName="CordovaDeploy">
-            <ProjectItem ReplaceParameters="false" TargetFileName="CordovaDeploy.sln">CordovaDeploy.sln</ProjectItem>
-            <Folder Name="CordovaDeploy" TargetFolderName="CordovaDeploy">
-              <ProjectItem ReplaceParameters="false" TargetFileName="CordovaDeploy.csproj">CordovaDeploy.csproj</ProjectItem>
-              <ProjectItem ReplaceParameters="false" TargetFileName="Program.cs">Program.cs</ProjectItem>
-              <Folder Name="Properties" TargetFolderName="Properties">
-                <ProjectItem ReplaceParameters="false" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
-              </Folder>
-            </Folder>
-          </Folder>
-        </Folder>
-      </Folder>
-    </Project>
-  </TemplateContent>
-</VSTemplate>
\ No newline at end of file
diff --git a/templates/vs/description.txt b/templates/vs/description.txt
deleted file mode 100644
index 089ad81..0000000
--- a/templates/vs/description.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CordovaStarter
-
-Starter project for building a Cordova app for Windows Phone version: 2.6.0
-
diff --git a/templates/vs/pg_templateIcon.png b/templates/vs/pg_templateIcon.png
deleted file mode 100644
index 75c17c7..0000000
--- a/templates/vs/pg_templateIcon.png
+++ /dev/null
Binary files differ
diff --git a/templates/vs/pg_templatePreview.jpg b/templates/vs/pg_templatePreview.jpg
deleted file mode 100644
index 1d72941..0000000
--- a/templates/vs/pg_templatePreview.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/README.md b/tests/README.md
deleted file mode 100644
index cdf9516..0000000
--- a/tests/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Tests Have Moved
-===
-
-Tests now live in the MobileSpec repo at:
-https://github.com/apache/incubator-cordova-mobile-spec
-
-You will need to create a new project, and add the mobile-spec files to it to run the tests.
\ No newline at end of file
diff --git a/tooling/scripts/buildjs.bat b/tooling/scripts/buildjs.bat
deleted file mode 100644
index 28d2423..0000000
--- a/tooling/scripts/buildjs.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-cscript "%~dp0\buildjs.js" %* //nologo
\ No newline at end of file
diff --git a/tooling/scripts/buildjs.js b/tooling/scripts/buildjs.js
deleted file mode 100644
index 4bfba53..0000000
--- a/tooling/scripts/buildjs.js
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject'),
-    shell = WScript.CreateObject("shell.application"),
-    wscript_shell = WScript.CreateObject("WScript.Shell");
-
-var args = WScript.Arguments,
-    //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp7)
-    ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
-    //Sub folder containing templates
-    TEMPLATES_PATH = '\\templates',
-    //Sub folder for standalone project
-    STANDALONE_PATH = TEMPLATES_PATH + '\\standalone',
-    //Sub folder containing framework
-    FRAMEWORK_PATH = '\\framework',
-    //Subfolder containing example project
-    EXAMPLE_PATH = '\\example',
-    //Git Repositories
-    CORDOVA_JS = "https://git-wip-us.apache.org/repos/asf/cordova-js.git",
-    // get version
-    VERSION = read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,''),
-    BUILD_DESTINATION;
-
-
-// help function
-function Usage()
-{
-    Log("");
-    Log("This Script builds the given virsion of cordova.js and injects it into this or the given cordova-wp7 ");
-    Log("");
-    Log("Usage: buildjs [ Version PathTOCordovaWP7 ]");
-    Log("    Version : The version of cordova.js to build (must already be tagged)");
-    Log("    PathTOCordovaWP7 : The path to the cordova directory where the new cordova.js will go.");
-    Log("examples:");
-    Log("    buildjs 2.5.0rc1  //Puts cordova-2.5.0rc1 as the cordova.js in the current working directory");
-    Log("    buildjs 2.4.0 C:\\Users\\anonymous\\Desktop\\cordova-wp7  //Puts cordova-2.4.0.js in the given directory");
-    Log("    buildjs //Builds the version of cordova.js from the root folder and adds it to the working directory repo");
-    Log("");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// returns the contents of a file
-function read(filename) {
-    //Log('Reading in ' + filename);
-    if(fso.FileExists(filename))
-    {
-        var f=fso.OpenTextFile(filename, 1,2);
-        var s=f.ReadAll();
-        f.Close();
-        return s;
-    }
-    else
-    {
-        Log('Cannot read non-existant file : ' + filename);
-        WScript.Quit(1);
-    }
-    return null;
-}
-
-// executes a commmand in the shell
-function exec(command) {
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        WScript.sleep(100);
-    }
-}
-
-// executes a commmand in the shell
-function exec_verbose(command) {
-    //Log("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if(!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadLine();
-            Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if(!oShell.StdErr.AtEndOfStream)
-    {
-        var err_line = oShell.StdErr.ReadAll();
-        Log(err_line, true);
-        WScript.Quit(1);
-    }
-}
-
-function build_js(path)
-{
-    if(fso.FolderExists(path + '\\temp'))
-    {
-        fso.DeleteFolder(path + '\\temp', true);
-    }
-    fso.CreateFolder(path + '\\temp');
-    wscript_shell.CurrentDirectory = path + '\\temp';
-
-    Log('\tCloning js tagged with ' + VERSION + '...');
-    exec('%comspec% /c git clone ' + CORDOVA_JS + ' && cd cordova-js && git fetch && git checkout ' + VERSION );
-    if(!fso.FolderExists(path + '\\temp\\cordova-js'))
-    {
-        WScript.StdErr.WriteLine("ERROR: Failed to clone cordova-js. Aborting...");
-        WScript.Quit(1);
-    }
-    wscript_shell.CurrentDirectory = path + '\\temp\\cordova-js';
-    Log("Building Cordova.js...");
-
-    exec_verbose('%comspec% /c jake build');
-    if(!fso.FolderExists(path + '\\temp\\cordova-js\\pkg'))
-    {
-        WScript.StdErr.WriteLine("ERROR: Failed to build cordova-js. Aborting...");
-        WScript.Quit(1);
-    }
-
-    //copy the javascript wherever it needs to go.
-    wscript_shell.CurrentDirectory = path + '\\temp\\cordova-js\\pkg';
-    exec('%comspec% /c copy /Y cordova.windowsphone.js ' + path + STANDALONE_PATH + '\\www\\cordova.js');
-    exec('%comspec% /c copy /Y cordova.windowsphone.js ' + path + EXAMPLE_PATH + '\\www\\cordova.js');
-
-    //TODO: Delete old cordova.js (done in reversion.js)
-
-    Log("SUCESS");
-}
-
-function set_path(some_arg)
-{
-    if(some_arg.indexOf('-p:')!= -1)
-    {
-        var path = some_arg.split('-p:')[1];
-        if(fso.FolderExists(path) && fso.FolderExists(path + '\\tooling'))
-        {
-            BUILD_DESTINATION = path;
-            return true;
-        }
-        else
-        {
-            Log("ERROR: The given path is not a cordova-wp7 repo, or", true);
-            Log(" does not exist. If your trying to reversion a", true);
-            Log(" cordova repo other then this one, please provide", true);
-            Log(" it's path in the form: -p:C:\\Path\\to\\repo", true);
-            WScript.Quit(1);
-        }
-        
-    }
-    return false;
-}
-
-Log("");
-
-if(args.Count() > 1)
-{
-    set_path(args(1));
-}
-
-if(args.Count() > 0)
-{
-    //Support help flags
-    if(args(0).indexOf("--help") > -1 ||
-         args(0).indexOf("/?") > -1 )
-    {
-        Usage();
-        WScript.Quit(1);
-    }
-
-    if(args(0).match(/(\d+)[.](\d+)[.](\d+)(rc\d)?/))
-    {
-        VERSION = args(0);
-        if(args.Count()  == 1)
-        {
-            BUILD_DESTINATION = ROOT;
-        }
-    }
-    else if(set_path(arg(0))) {} //do nothing
-    else
-    {
-        Log("The provided version number is invalid, please provide", true);
-        Log(" a version number in the format Major.Minor.Fix[rc#]", true);
-        Usage();
-        WScript.Quit(1);
-    }
-}
-else
-{
-    BUILD_DESTINATION = ROOT;
-}
-
-//If we haven't quit by here, build the damn javascript!
-Log("Creating js for " + BUILD_DESTINATION);
-build_js(BUILD_DESTINATION);
\ No newline at end of file
diff --git a/tooling/scripts/dist.bat b/tooling/scripts/dist.bat
deleted file mode 100644
index a1c0e1d..0000000
--- a/tooling/scripts/dist.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-cscript "%~dp0\dist.js" %* //nologo
diff --git a/tooling/scripts/dist.js b/tooling/scripts/dist.js
deleted file mode 100644
index 8b27bb9..0000000
--- a/tooling/scripts/dist.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-/*************************************************/
-/****************  REQUIREMENTS  *****************/
-/*************************************************/
-/*
-Paths:
-  - path to git.exe  -> C:\msysgit\bin
-  - path to msbuild -> C:\Windows\Microsoft.NET\Framework\v4.0.30319
-Famework
-  - .NET 4.0
-  - Windows phone SDKs
-
-
-/************ Globals ********/
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject'),
-    wscript_shell = WScript.CreateObject("WScript.Shell");
-
-//Replace root directory or create new directory?
-var replace = false;
-
-//Set up directory structure of current release
-    //arguments passed in
-var args = WScript.Arguments,
-    //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp7)
-    ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
-    // tooling scripts
-    SCRIPTS = '\\tooling\\scripts';
-    //Get version number
-    VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
-
-//Destination to build to
-var BUILD_DESTINATION;
-//current script that is running
-var current_script = "dist";
-
-
-/*************************************************/
-/****************  FUNCTIONS  ********************/
-/*************************************************/
-
-
-// help function
-function Usage()
-{
-  Log("");
-  Log("This is a command line tool for building new releases. It will package a new release");
-  Log(" of a cordova-wp7 project, reversioning it to match the VERSION file in the root directory.");
-  Log("Usage: dist [ <PATH_TO_NEW_REPO> | -f ] ");
-  Log("                       -f : reversion the repositoy this script is in.");
-  Log("       <PATH_TO_NEW_REPO> : path to create the new reversioned repositoy in.");
-  Log("");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-
-// returns the contents of a file
-function read(filename) {
-    //Log('Reading in ' + filename);
-    if(fso.FileExists(filename))
-    {
-        var f=fso.OpenTextFile(filename, 1,2);
-        var s=f.ReadAll();
-        f.Close();
-        return s;
-    }
-    else
-    {
-        Log('Cannot read non-existant file : ' + filename);
-        WScript.Quit(1);
-    }
-    return null;
-}
-
-// executes a commmand in the shell
-function exec(command) {
-    Log("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if(!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadLine();
-            Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if(!oShell.StdErr.AtEndOfStream)
-    {
-        var err_line = oShell.StdErr.ReadAll();
-        Log(err_line, true);
-        Log("ERROR: Could not complete distribution, failed while running: " + current_script, true);
-        WScript.Quit(1);
-    }
-}
-
-function space()
-{
-    Log("");
-    Log("*****************************************************");
-    Log("");
-}
-
-
-/*************************************************/
-/**************  MAIN SCRIPT  ********************/
-/*************************************************/
-
-if (args.Count() > 0) {
-    if (args.Count() == 1) {
-        // support help flags
-        if (args(0).indexOf("--help") > -1 ||
-              args(0).indexOf("/?") > -1 ) {
-            Usage();
-            WScript.Quit(1);
-        }
-        else if (args(0) == '-f') {
-          BUILD_DESTINATION = ROOT;
-          replace = true;
-        }
-        else {
-          BUILD_DESTINATION = args(0);
-        }
-
-    }
-    else if (args.Count() == 2) {
-        if (args(0) == '-f') {
-            replace = true;
-            BUILD_DESTINATION = args(1);
-        } else {
-           BUILD_DESTINATION = args(0);
-           if (args(1) == '-f') {
-              replace = true;
-           }
-           else {
-              Log('WARNING : "' + args(1) + '" is not regognized, attempting to continue distribution.');
-           }
-        }
-    }
-    else {
-        Log("Error : too many arguments provided.", true);
-        WScript.Quit(1);
-    }
-}
-else {
-    Usage();
-    WScript.Quit(1);
-}
-
-
-/*************************************************/
-/******************  Step 1  *********************/
-/*************************************************/
-/** - Copy source code to new directory         **/
-/*************************************************/
-if (!replace) {
-  current_script = "new.js";
-  exec('cscript ' + ROOT + SCRIPTS + '\\new.js ' + BUILD_DESTINATION + ' //nologo');
-  space();
-}
-
-/*************************************************/
-/******************  Step 2  *********************/
-/*************************************************/
-/** - Retag everything with new version numbers **/
-/** - Delete any generated files and cordova.js **/
-/** - Rebuild dll                               **/
-/*************************************************/
-current_script = "reversion.js";
-exec('cscript ' + BUILD_DESTINATION + SCRIPTS + '\\reversion.js ' + VERSION + ' //nologo');
-space();
-
-/*************************************************/
-/******************  Step 3  *********************/
-/*************************************************/
-/** - Download tagged version of cordova.js     **/
-/** - build cordova.js                          **/
-/** - windows.cordova.js -> templates + example **/
-/*************************************************/
-// New Workflow may not require building the new js, it should already be in place.
-/*current_script = "buildjs.js";
-exec('cscript ' + BUILD_DESTINATION + SCRIPTS + '\\buildjs.js //nologo');
-space();*/
-
-/*************************************************/
-/******************  Step 5  *********************/
-/*************************************************/
-/** - Build templates                           **/
-/** - Zip templates                             **/
-/** - inject into Visual Studio                 **/
-/*************************************************/
-current_script = "package.js";
-exec('cscript ' + BUILD_DESTINATION + SCRIPTS + '\\package.js //nologo');
-space();
-Log("Distribution Complete.");
\ No newline at end of file
diff --git a/tooling/scripts/new.bat b/tooling/scripts/new.bat
deleted file mode 100644
index cb08e2e..0000000
--- a/tooling/scripts/new.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-cscript "%~dp0\new.js" %* //nologo
\ No newline at end of file
diff --git a/tooling/scripts/new.js b/tooling/scripts/new.js
deleted file mode 100644
index c17dc94..0000000
--- a/tooling/scripts/new.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject'),
-    shell = WScript.CreateObject("shell.application"),
-    wscript_shell = WScript.CreateObject("WScript.Shell");
-
-var args = WScript.Arguments,
-    //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp7)
-    ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
-    //Sub folder containing templates
-    TEMPLATES_PATH = '\\templates',
-    //Sub folder containing framework
-    FRAMEWORK_PATH = '\\framework',
-    //Subfolder containing example project
-    EXAMPLE_PATH = '\\example';
-// git repo for cordova-wp7
-var CORDOVA_WP7 = 'https://git-wip-us.apache.org/repos/asf/cordova-wp7.git';
-//Destination to build to
-var BUILD_DESTINATION;
-// pull the project down from github?
-var GET_NEW = false;
-
-// help function
-function Usage()
-{
-    WScript.StdOut.WriteLine("");
-    WScript.StdOut.WriteLine("Usage: new [ PathToDestinationFolder ]");
-    WScript.StdOut.WriteLine("    PathToDestinationFolder : Folder you wish to be created for a new cordova-wp7 repo");
-    WScript.StdOut.WriteLine("examples:");
-    WScript.StdOut.WriteLine("    new C:\\Users\\anonymous\\Desktop\\cordova-wp7");
-    WScript.StdOut.WriteLine("");
-}
-
-// returns the contents of a file
-function read(filename) {
-    //WScript.StdOut.WriteLine('Reading in ' + filename);
-    if(fso.FileExists(filename))
-    {
-        var f=fso.OpenTextFile(filename, 1,2);
-        var s=f.ReadAll();
-        f.Close();
-        return s;
-    }
-    else
-    {
-        WScript.StdErr.WriteLine('Cannot read non-existant file : ' + filename);
-        WScript.Quit(1);
-    }
-    return null;
-}
-
-// executes a commmand in the shell
-function exec(command) {
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        WScript.sleep(100);
-    }
-}
-
-function copy_to(path)
-{
-    //Copy everything over to BUILD_DESTINATION
-    var dest = shell.NameSpace(path);
-    WScript.StdOut.WriteLine("Copying files to build directory...");
-
-    /** copy by file instead? (just what we need)**/
-    dest.CopyHere(ROOT + "\\bin", 4|20);
-    dest.CopyHere(ROOT + EXAMPLE_PATH, 4|20);      //Should mostly be copied from standalone
-    dest.CopyHere(ROOT + FRAMEWORK_PATH, 4|20);
-    dest.CopyHere(ROOT + TEMPLATES_PATH, 4|20);
-    dest.CopyHere(ROOT + "\\tests", 4|20);
-    dest.CopyHere(ROOT + "\\tooling", 4|20);
-    dest.CopyHere(ROOT + "\\.gitignore", 4|20);
-    dest.CopyHere(ROOT + "\\LICENSE", 4|20);
-    dest.CopyHere(ROOT + "\\NOTICE", 4|20);
-    dest.CopyHere(ROOT + "\\README.md", 4|20);
-    dest.CopyHere(ROOT + "\\VERSION", 4|20);
-}
-
-WScript.StdOut.WriteLine("");
-
-if(args.Count() > 0)
-{
-    if(fso.FolderExists(args(0)))
-    {
-        WScript.StdErr.WriteLine("The given directory already exists!");
-        Usage();
-        WScript.Quit(1);
-    }
-    else
-    {
-        BUILD_DESTINATION = args(0);
-
-    }
-
-    if(!GET_NEW) {
-
-        if(fso.FolderExists(BUILD_DESTINATION))
-        {
-            WScript.StdErr.WriteLine("The given directory already exists!");
-            Usage();
-            WScript.Quit(1);
-        }
-        else
-        {
-            BUILD_DESTINATION = args(0);
-        }
-
-        // set up file structure
-        fso.CreateFolder(BUILD_DESTINATION);
-        // copy nessisary files
-        copy_to(BUILD_DESTINATION);
-    }
-    else
-    {
-        wscript_shell.CurrentDirectory = arg(0) + '\\..';
-        BUILD_DESTINATION = wscript_shell.CurrentDirectory + '\\cordova-wp7';
-
-        WScript.StdOut.WriteLine('Cloning cordova-wp7 from git, build destination now ' + BUILD_DESTINATION);
-        if(fso.FolderExists(BUILD_DESTINATION))
-        {
-            WScript.StdErr.WriteLine("Could not clone cordova-wp7 from git because it's directory already exists!");
-            WScript.Quit(1);
-        }
-
-        exec('git clone ' + CORDOVA_WP7); //git fetch --tags && git checkout?
-
-    }
-}
-else
-{
-    Usage();
-    WScript.Quit(1);
-}
\ No newline at end of file
diff --git a/tooling/scripts/package.bat b/tooling/scripts/package.bat
deleted file mode 100644
index c00551e..0000000
--- a/tooling/scripts/package.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-cscript "%~dp0\package.js" %* //nologo
\ No newline at end of file
diff --git a/tooling/scripts/package.js b/tooling/scripts/package.js
deleted file mode 100644
index b5f882d..0000000
--- a/tooling/scripts/package.js
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject'),
-    shell = WScript.CreateObject("shell.application"),
-    wscript_shell = WScript.CreateObject("WScript.Shell");
-
-var args = WScript.Arguments,
-    // root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp7)
-    ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
-    // sub folder containing templates
-    TEMPLATES_PATH = '\\templates',
-    // sub folder for standalone project
-    STANDALONE_PATH = TEMPLATES_PATH + '\\standalone',
-    // sub folder containing framework
-    FRAMEWORK_PATH = '\\framework',
-    // subfolder containing example project
-    EXAMPLE_PATH = '\\example',
-    // get version number
-    VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,''),
-    BASE_VERSION = VERSION.split('rc', 1) + ".0";
-
-// destination directory to package
-var BUILD_DESTINATION;
-// add templates to visual studio?
-var ADD_TO_VS = false;
-// build the dll?
-var BUILD_DLL = false;
-
-
-// help function
-function Usage()
-{
-    Log("");
-    Log("Usage: package [ PathToCordovaWP7 ]");
-    Log("    PathToCordovaWP7 : Cordova-wp7 repo you wish to package for release");
-    Log("examples:");
-    Log("    package C:\\Users\\anonymous\\Desktop\\cordova-wp7");
-    Log("    package     // packages current cordova directory");
-    Log("");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
-    if (error) {
-        WScript.StdErr.WriteLine(msg);
-    }
-    else {
-        WScript.StdOut.WriteLine(msg);
-    }
-}
-
-// returns the contents of a file
-function read(filename) {
-    //Log('Reading in ' + filename);
-    if(fso.FileExists(filename))
-    {
-        var f=fso.OpenTextFile(filename, 1,2);
-        var s=f.ReadAll();
-        f.Close();
-        return s;
-    }
-    else
-    {
-        Log('ERROR: Cannot read non-existant file : ' + filename);
-        WScript.Quit(1);
-    }
-    return null;
-}
-
-// executes a commmand in the shell
-function exec(command) {
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        WScript.sleep(100);
-    }
-}
-
-// executes a commmand in the shell
-function exec_verbose(command) {
-    Log("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if(!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadLine();
-            Log(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if(!oShell.StdErr.AtEndOfStream)
-    {
-        var err_line = oShell.StdErr.ReadAll();
-        Log(err_lin, true);
-        WScript.Quit(1);
-    }
-}
-
-// packages templates into .zip
-function package_templates()
-{
-    Log("Creating template .zip files ...");
-
-    var template_path = BUILD_DESTINATION + '\\CordovaWP7_' + VERSION.replace(/\./g, '_') + '.zip';
-    if(fso.FileExists(template_path))
-    {
-      fso.DeleteFile(template_path);
-    }
-
-    exec('%comspec% /c copy /Y ' + BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\MyTemplateStandAlone.vstemplate ' + BUILD_DESTINATION + STANDALONE_PATH + '\\MyTemplate.vstemplate');
-    exec('%comspec% /c copy /Y ' + BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\pg_templateIcon.png ' + BUILD_DESTINATION + STANDALONE_PATH + '\\__TemplateIcon.png');
-    exec('%comspec% /c copy /Y ' + BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\pg_templatePreview.jpg ' + BUILD_DESTINATION + STANDALONE_PATH + '\\__PreviewImage.jpg');
-    exec('%comspec% /c copy /Y ' + BUILD_DESTINATION + '\\VERSION ' + BUILD_DESTINATION + STANDALONE_PATH);
-
-    zip_project(template_path, BUILD_DESTINATION + STANDALONE_PATH);
-
-
-    if(ADD_TO_VS)
-    {
-        var template_dir = wscript_shell.ExpandEnvironmentStrings("%USERPROFILE%") + '\\Documents\\Visual Studio 2012\\Templates\\ProjectTemplates';
-        if(fso.FolderExists(template_dir ))
-        {
-            dest = shell.NameSpace(template_dir);
-            dest.CopyHere(template_path, 4|20);
-        }
-        else
-        {
-            Log("WARNING: Could not find template directory in Visual Studio,\n you can manually copy over the template .zip files.");
-        }
-  }
-}
-
-function zip_project(zip_path, project_path)
-{
-    // create empty ZIP file and open for adding
-    var file = fso.CreateTextFile(zip_path, true);
-
-    // create twenty-two byte "fingerprint" for .zip
-    file.write("PK");
-    file.write(String.fromCharCode(5));
-    file.write(String.fromCharCode(6));
-    file.write('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0');
-    file.Close();
-
-    // open .zip foder and copy contents of project_path to zip_path
-    var zipFolder = shell.NameSpace(zip_path);
-    var sourceItems = shell.NameSpace(project_path).items();
-    if (zipFolder !== null) {
-        zipFolder.CopyHere(sourceItems, 4|20|16);
-        var maxTime = 5000;
-        while(zipFolder.items().Count < sourceItems.Count)
-        {
-            maxTime -= 100;
-            if(maxTime > 0 ) {
-                WScript.Sleep(100);
-            }
-            else {
-                Log('Failed to create .zip file.', true);
-                break;
-            }
-        }
-    }
-    else {
-        Log('Failed to create .zip file.', true);
-    }
-}
-
-// builds the new cordova dll and copys it to the full template (only done because of the version referance in Device.cs)
-function build_dll()
-{
-    Log("Packaging .dll ...");
-    // move to framework directory
-    wscript_shell.CurrentDirectory = BUILD_DESTINATION + FRAMEWORK_PATH;
-    // build .dll in Release
-    exec_verbose('msbuild /p:Configuration=Release;VersionNumber=' + VERSION + ';BaseVersionNumber=' + BASE_VERSION);
-    //Check if file dll was created
-    if(!fso.FileExists(BUILD_DESTINATION + FRAMEWORK_PATH + '\\Bin\\Release\\WPCordovaClassLib.dll'))
-    {
-        WScript.StdErr.WriteLine('ERROR: MSBuild failed to create .dll.');
-        WScript.Quit(1);
-    }
-
-    Log("SUCESS");
-}
-
-// delete any unnessisary files when finished
-function cleanUp() {
-
-  if(fso.FileExists(BUILD_DESTINATION + STANDALONE_PATH + '\\MyTemplate.vstemplate')) {
-      fso.DeleteFile(BUILD_DESTINATION + STANDALONE_PATH + '\\MyTemplate.vstemplate');
-  }
-  if(fso.FileExists(BUILD_DESTINATION + STANDALONE_PATH + '\\__PreviewImage.jpg')) {
-      fso.DeleteFile(BUILD_DESTINATION + STANDALONE_PATH + '\\__PreviewImage.jpg');
-  }
-  if(fso.FileExists(BUILD_DESTINATION + STANDALONE_PATH + '\\__TemplateIcon.png')) {
-      fso.DeleteFile(BUILD_DESTINATION + STANDALONE_PATH + '\\__TemplateIcon.png');
-  }
-  //Add any other cleanup here
-}
-
-
-Log("");
-
-if(args.Count() > 0)
-{
-    //Support help flags
-    if(args(0).indexOf("--help") > -1 ||
-         args(0).indexOf("/?") > -1 )
-    {
-        Usage();
-        WScript.Quit(1);
-    }
-
-    if(fso.FolderExists(args(0)) && fso.FolderExists(args(0) + '\\tooling'))
-    {
-        BUILD_DESTINATION = args(0);
-    }
-    else
-    {
-        Log("ERROR: The given directory is not a cordova-wp7 repo.");
-        Usage();
-        WScript.Quit(1);
-
-    }
-}
-else
-{
-    BUILD_DESTINATION = ROOT;
-}
-
-// build dll for full template
-if (BUILD_DLL) {
-  build_dll();
-}
-
-// build/package the templates
-package_templates(BUILD_DESTINATION);
-
-cleanUp();
\ No newline at end of file
diff --git a/tooling/scripts/reversion.bat b/tooling/scripts/reversion.bat
deleted file mode 100644
index b35ab08..0000000
--- a/tooling/scripts/reversion.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-cscript "%~dp0\reversion.js" %* //nologo
\ No newline at end of file
diff --git a/tooling/scripts/reversion.js b/tooling/scripts/reversion.js
deleted file mode 100644
index 753cbdd..0000000
--- a/tooling/scripts/reversion.js
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-
-/************ Globals ********/
-
-var fso = WScript.CreateObject('Scripting.FileSystemObject'),
-    shell = WScript.CreateObject("shell.application"),
-    wscript_shell = WScript.CreateObject("WScript.Shell");
-
-//Get new version from git or build off this version?
-var GET_NEW = false;
-
-//Set up directory structure of current release
-    //arguments passed in
-var args = WScript.Arguments,
-    //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp7)
-    ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
-    //Sub folder containing templates
-    TEMPLATES_PATH = '\\templates',
-    //Sub folder for standalone project
-    STANDALONE_PATH = TEMPLATES_PATH + '\\standalone',
-    //Sub folder containing framework
-    FRAMEWORK_PATH = '\\framework',
-    //Subfolder containing example project
-    EXAMPLE_PATH = '\\example',
-    //Path to cordovalib folder, containing source for .dll
-    CORDOVA_LIB = STANDALONE_PATH + '\\cordovalib',
-    //Get version number
-    VERSION='',
-    BASE_VERSION = '';
-
-//Destination to build to
-var BUILD_DESTINATION;
-
-// help function
-function Usage()
-{
-    WScript.StdOut.WriteLine("");
-    WScript.StdOut.WriteLine("Usage: reversion [ Version PathTOCordovaWP7 ]");
-    WScript.StdOut.WriteLine("    Version : The new version for codova-wp7");
-    WScript.StdOut.WriteLine("    PathTOCordovaWP7 : The path to the cordova directory being reversioned.");
-    WScript.StdOut.WriteLine("examples:");
-    WScript.StdOut.WriteLine("    reversion 2.5.0rc1  //Reversions the current working directory");
-    WScript.StdOut.WriteLine("    reversion 2.5.0 C :\\Users\\anonymous\\Desktop\\cordova-wp7");
-    WScript.StdOut.WriteLine("");
-}
-
-var ForReading = 1, ForWriting = 2, ForAppending = 8;
-var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
-
-// returns the contents of a file
-function read(filename) {
-    //WScript.Echo('Reading in ' + filename);
-    if(fso.FileExists(filename))
-    {
-        var f=fso.OpenTextFile(filename, 1,2);
-        var s=f.ReadAll();
-        f.Close();
-        return s;
-    }
-    else
-    {
-        WScript.StdErr.WriteLine('Cannot read non-existant file : ' + filename);
-        WScript.Quit(1);
-    }
-    return null;
-}
-
-// writes the contents to the specified file
-function write(filename, contents) {
-    var f=fso.OpenTextFile(filename, ForWriting, TristateTrue);
-    f.Write(contents);
-    f.Close();
-}
-
-// replaces the matches of regexp with replacement
-function replaceInFile(filename, regexp, replacement) {
-    //WScript.Echo("Replaceing with "+replacement+ " in:");
-    var text = read(filename).replace(regexp,replacement);
-    //WScript.Echo(text);
-    write(filename,text);
-}
-
-// executes a commmand in the shell
-function exec(command) {
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        WScript.sleep(100);
-    }
-}
-
-// executes a commmand in the shell
-function exec_verbose(command) {
-    //WScript.StdOut.WriteLine("Command: " + command);
-    var oShell=wscript_shell.Exec(command);
-    while (oShell.Status === 0) {
-        //Wait a little bit so we're not super looping
-        WScript.sleep(100);
-        //Print any stdout output from the script
-        if(!oShell.StdOut.AtEndOfStream) {
-            var line = oShell.StdOut.ReadLine();
-            WScript.StdOut.WriteLine(line);
-        }
-    }
-    //Check to make sure our scripts did not encounter an error
-    if(!oShell.StdErr.AtEndOfStream)
-    {
-        var err_line = oShell.StdErr.ReadAll();
-        WScript.StdErr.WriteLine(err_line);
-        WScript.Quit(1);
-    }
-}
-
-function updateVersionNumbers() {
-    WScript.StdOut.WriteLine("Updating version numbers....");
-    var version_regex = /(\d+)[.](\d+)[.](\d+)(rc\d)?/;
-    replaceInFile(BUILD_DESTINATION + '\\VERSION', version_regex,  VERSION);
-    // replace assembaly versions in framework
-    var framework_regex = /Description\(\"(\d+)[.](\d+)[.](\d+)(rc\d)?\"\)\]/; //Will match ("x.x.x[rcx]")]
-    replaceInFile(BUILD_DESTINATION + FRAMEWORK_PATH + "\\Properties\\AssemblyInfo.cs", framework_regex, "Description(\"" + VERSION + "\")]");
-    framework_regex = /Version\(\"(\d+)[.](\d+)[.](\d+)[.](\d+)\"\)\]/g;
-    replaceInFile(BUILD_DESTINATION + FRAMEWORK_PATH + "\\Properties\\AssemblyInfo.cs", framework_regex, "Version(\"" + BASE_VERSION + "\")]");
-
-    // update standalone project
-    exec('%comspec% /c copy /Y /V ' + BUILD_DESTINATION + "\\VERSION " + BUILD_DESTINATION + STANDALONE_PATH + "\\VERSION");
-    var cordova_regex = /cordova-(\d+)[.](\d+)[.](\d+)(rc\d)?/g; //Matches *first* cordova-x.x.x[rcx] (just ad g at end to make global)
-    version_regex = /return\s*\"(\d+)[.](\d+)[.](\d+)(rc\d)?/; //Matches return "x.x.x[rcx]
-    replaceInFile(BUILD_DESTINATION + CORDOVA_LIB + '\\..\\Plugins\\Device.cs', version_regex,  "return \"" + VERSION);
-
-    // update template discription
-    version_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?\s*Windows/g; //Matches version: x.x.x[rcx]
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\description.txt', version_regex,  "Cordova " + VERSION + " Windows");
-
-    // update .vstemplate files for the template zips.
-    var name_regex = /CordovaWP7[_](\d+)[_](\d+)[_](\d+)(rc\d)?/g;
-    var discript_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
-
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\MyTemplateStandAlone.vstemplate', name_regex,  'CordovaWP7_' + VERSION.replace(/\./g, '_'));
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\MyTemplateStandAlone.vstemplate', discript_regex,  "Cordova " + VERSION);
-}
-
-// delete all cordova.js and generated files (templates) from old version numbers
-function cleanup()
-{
-    WScript.StdOut.WriteLine("Cleanup");
-    // remove old template .zip files
-    if(fso.FileExists(BUILD_DESTINATION + '\\*.zip'))
-    {
-        fso.DeleteFile(BUILD_DESTINATION + '\\*.zip');
-    }
-    // remove any generated framework files
-    if(fso.FolderExists(BUILD_DESTINATION + FRAMEWORK_PATH + '\\Bin'))
-    {
-        fso.DeleteFolder(BUILD_DESTINATION + FRAMEWORK_PATH + '\\Bin');
-    }
-    if(fso.FolderExists(BUILD_DESTINATION + FRAMEWORK_PATH + '\\obj'))
-    {
-        fso.DeleteFolder(BUILD_DESTINATION + FRAMEWORK_PATH + '\\obj');
-    }
-    // remove any generated CordovaDeploy
-    if(fso.FolderExists(BUILD_DESTINATION + '\\tooling\\CordovaDeploy\\CordovaDeploy\\bin'))
-    {
-        fso.DeleteFolder(BUILD_DESTINATION + '\\tooling\\CordovaDeploy\\CordovaDeploy\\bin');
-    }
-    if(fso.FolderExists(BUILD_DESTINATION + '\\tooling\\CordovaDeploy\\CordovaDeploy\\obj'))
-    {
-        fso.DeleteFolder(BUILD_DESTINATION + '\\tooling\\CordovaDeploy\\CordovaDeploy\\obj');
-    }
-    //remove old template .zip files
-    WScript.Echo(BUILD_DESTINATION);
-    var root_folder = shell.NameSpace(BUILD_DESTINATION + '\\').Items();
-    for(var i = 0; i < root_folder.Count; i++)
-    {
-        if(root_folder.Item(i).Name.match(/CordovaWP7[_](\d+)[_](\d+)[_](\d+)(rc\d)?/))
-        {
-            fso.DeleteFile(BUILD_DESTINATION + '\\' + root_folder.Item(i).Name);
-        }
-    }
-    // remove old cordova.js
-    /*var example_www = shell.NameSpace(BUILD_DESTINATION + EXAMPLE_PATH + '\\www').Items();
-    for(i = 0; i < example_www.Count; i++)
-    {
-        if(example_www.Item(i).Name.match(/cordova\-(\d+)[.](\d+)[.](\d+)(rc\d)?[.]js/))
-        {
-            fso.DeleteFile(BUILD_DESTINATION + EXAMPLE_PATH + '\\www\\' + example_www.Item(i).Name);
-        }
-    }*/
-
-    var standalone_www = shell.NameSpace(BUILD_DESTINATION + STANDALONE_PATH + '\\www').Items();
-    for(i = 0; i < standalone_www.Count; i++)
-    {
-        if(standalone_www.Item(i).Name.match(/cordova\-(\d+)[.](\d+)[.](\d+)(rc\d)?[.]js/))
-        {
-            fso.DeleteFile(BUILD_DESTINATION + STANDALONE_PATH + '\\www\\' + standalone_www.Item(i).Name);
-        }
-    }
-}
-
-
-WScript.StdOut.WriteLine("");
-
-if(args.Count() > 1)
-{
-    if(fso.FolderExists(args(1)) && fso.FolderExists(args(1) + '\\tooling'))
-    {
-        BUILD_DESTINATION = args(1);
-    }
-    else
-    {
-        WScript.StdErr.WriteLine("The given path is not a cordova-wp7 repo, if");
-        WScript.StdErr.WriteLine(" your trying to reversion a cordova-wp7 repo");
-        WScript.StdErr.WriteLine(" other then this one, please provide its path.");
-        Usage();
-        WScript.Quit(1);
-    }
-}
-
-if(args.Count() > 0)
-{
-    //Support help flags
-    if(args(0).indexOf("--help") > -1 ||
-         args(0).indexOf("/?") > -1 )
-    {
-        Usage();
-        WScript.Quit(1);
-    }
-
-    if(args(0).match(/(\d+)[.](\d+)[.](\d+)(rc\d)?/))
-    {
-        VERSION = args(0);
-        BASE_VERSION = VERSION.split('rc', 1) + ".0";
-        if(args.Count() < 2)
-        {
-          BUILD_DESTINATION = ROOT;
-        }
-        // remove old cordova.js files and any generated files
-        cleanup();
-        // update version numbers
-        updateVersionNumbers();
-    }
-    else
-    {
-        WScript.StdOut.WriteLine("The  version number is invalid, please provide");
-        WScript.StdOut.WriteLine(" a version number in the format Major.Minor.Fix[rc#]");
-        Usage();
-        WScript.Quit(1);
-    }
-}
-else
-{
-    Usage();
-    WScript.Quit(1);
-}
\ No newline at end of file
