You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2014/09/19 00:49:52 UTC

[17/27] moving stuff around

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/MSBuildTools.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/MSBuildTools.js b/template/cordova/lib/MSBuildTools.js
new file mode 100644
index 0000000..ba1ee79
--- /dev/null
+++ b/template/cordova/lib/MSBuildTools.js
@@ -0,0 +1,73 @@
+/*
+       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 Q     = require('Q'),
+    path  = require('path'),
+    utils = require('./utils');
+
+function MSBuildTools (version, path) {
+    this.version = version;
+    this.path = path;
+}
+
+MSBuildTools.prototype.buildProject = function(projFile, buildType, buildarch) {
+    console.log("\nBuilding project: " + projFile);
+    console.log("\tConfiguration : " + buildType);
+    console.log("\tPlatform      : " + buildarch);
+
+    var args = ['/clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal', '/nologo',
+    '/p:Configuration=' + buildType,
+    '/p:Platform=' + buildarch];
+
+    return utils.spawn(path.join(this.path, 'msbuild'), [projFile].concat(args));
+};
+
+// returns full path to msbuild tools required to build the project and tools version
+module.exports.findAvailableVersion = function (searchFor32Bit) {
+    var versions = ['12.0', '4.0'];
+
+    return Q.all(versions.map(function (version) {
+        return checkMSBuildVersion(version, searchFor32Bit);
+    }))
+    .then(function (versions) {
+        // select first msbuild version available, and resolve promise with it
+        var msbuildTools = versions[0] || versions[1];
+        return msbuildTools ? Q.resolve(msbuildTools) : Q.reject('MSBuild tools not found');
+    });
+};
+
+function checkMSBuildVersion(version, searchFor32Bit) {
+    var deferred = Q.defer();
+
+    var regRoot = searchFor32Bit ? 'HKLM\\SOFTWARE\\Wow6432Node' : 'HKLM\\SOFTWARE';
+
+    utils.exec('reg query ' + regRoot + '\\Microsoft\\MSBuild\\ToolsVersions\\' + version + ' /v MSBuildToolsPath')
+    .then(function(output) {
+        // fetch msbuild path from 'reg' output
+        var path = /MSBuildToolsPath\s+REG_SZ\s+(.*)/i.exec(output);
+        if (path) {
+            deferred.resolve(new MSBuildTools(version, path[1]));
+            return;
+        }
+        deferred.resolve(null); // not found
+    }, function () {
+        deferred.resolve(null);
+    });
+    return deferred.promise;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/build.js b/template/cordova/lib/build.js
new file mode 100644
index 0000000..90e07c0
--- /dev/null
+++ b/template/cordova/lib/build.js
@@ -0,0 +1,92 @@
+/*
+       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 Q     = require('Q'),
+    path  = require('path'),
+    nopt  = require('nopt'),
+    utils = require('./utils'),
+    shell = require('shelljs'),
+    MSBuildTools = require('./MSBuildTools');
+
+// Platform project root folder
+var ROOT = path.join(__dirname, '..', '..');
+
+function parseAndValidateArgs(argv) {
+    // parse and validate args
+    args = nopt({'debug': Boolean, 'release': Boolean, 'archs': [String]}, {'-r': '--release'}, argv);
+    // Validate args
+    if (args.debug && args.release) {
+        return Q.reject('Only one of "debug"/"release" options should be specified');
+    }
+    // get build options/defaults and resolvew with buildopts object
+    return Q.resolve({
+        buildType: args.release ? 'release' : 'debug',
+        buildArchs: args.archs ? args.archs.split(' ') : ['anycpu'],
+    });
+}
+
+// help/usage function
+module.exports.help = function () {
+    console.log("");
+    console.log("Usage: build [ --debug | --release ] [--archs=\"<list of architectures...>\"]");
+    console.log("    --help    : Displays this dialog.");
+    console.log("    --debug   : Cleans and builds project in debug mode.");
+    console.log("    --release : Cleans and builds project in release mode.");
+    console.log("    --release : Cleans and builds project in release mode.");
+    console.log("    --archs   : Builds project binaries for specific chip architectures. `arm` and `x86` are supported for wp8");
+    console.log("examples:");
+    console.log("    build ");
+    console.log("    build --debug");
+    console.log("    build --release");
+    console.log("    build --release --archs=\"arm x86\"");
+    console.log("");
+};
+
+// builds cordova-windows application with parameters provided.
+// See 'help' function for args list
+module.exports.run = function (argv) {
+    if (!utils.isCordovaProject(ROOT)){
+        return Q.reject('Could not find project at ' + ROOT);
+    }
+
+    return parseAndValidateArgs(argv)
+    .then(function (buildopts) {
+        // WP8 requires x86 version of MSBuild, CB-6732
+        var is64bitSystem = process.env["PROCESSOR_ARCHITECTURE"] != 'x86';
+
+        // Get available msbuild tools
+        return MSBuildTools.findAvailableVersion(is64bitSystem)
+        .then(function (msbuildTools) {
+            // then build all architectures specified
+            // chain promises each after previous with reduce function
+            return buildopts.buildArchs.reduce(function (promise, buildarch) {
+                return promise.then(function () {
+                    buildarch = buildarch == "anycpu" ? "any cpu" : buildarch;
+                    // serach for first solution file found
+                    // this is performed due to solution file can be renamed in create
+                    var solutionFiles = shell.ls(path.join(ROOT, '*.sln'));
+                    if (solutionFiles && solutionFiles[0]) {
+                      return msbuildTools.buildProject(solutionFiles[0], buildopts.buildType, buildarch);
+                    }
+                    return Q.reject('No solution files found in project directory');
+                });
+            }, Q());
+        });
+    });
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/clean.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/clean.js b/template/cordova/lib/clean.js
new file mode 100644
index 0000000..6d1248c
--- /dev/null
+++ b/template/cordova/lib/clean.js
@@ -0,0 +1,32 @@
+/*
+       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 Q     = require('q'),
+    path  = require('path'),
+    shell = require('shelljs');
+
+var ROOT = path.join(__dirname, '..', '..');
+
+module.exports.run = function (argv) {
+    var projectPath = ROOT;
+    ['obj', 'Bin'].forEach(function(dir) {
+        shell.rm('-rf', path.join(projectPath, dir));
+    });
+    return Q.resolve();
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/device.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/device.js b/template/cordova/lib/device.js
new file mode 100644
index 0000000..f79a4fe
--- /dev/null
+++ b/template/cordova/lib/device.js
@@ -0,0 +1,54 @@
+/*
+       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 Q     = require('q'),
+    fs    = require('fs'),
+    path  = require('path'),
+    shell = require('shelljs'),
+    utils = require('./utils');
+
+// returns one of available devices which name match with parovided string
+// return rejected promise if device with name specified not found
+module.exports.findDevice = function (target) {
+    return module.exports.listDevices()
+    .then(function(deviceList) {
+        for (var idx in deviceList){
+            if (deviceList[idx].indexOf(target) > -1) {
+                return Q.resolve(idx);
+            }
+        }
+        return Q.reject('Specified device not found');
+    });
+};
+
+// returns array of available devices names
+module.exports.listDevices = function () {
+    return utils.getXapDeploy()
+    .then(function(xapDeploy) {
+        return utils.exec('"' + xapDeploy + '" /enumeratedevices')
+        .then(function(output) {
+            return Q.resolve(output.split('\n').map(function(line) {
+                var match = /\s*(\d)+\s+(.*)/.exec(line);
+                return match && match[2];
+            }).filter(function (line) {
+                return line;
+            }));
+        });
+    });
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/install-device.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/install-device.bat b/template/cordova/lib/install-device.bat
new file mode 100644
index 0000000..01dd232
--- /dev/null
+++ b/template/cordova/lib/install-device.bat
@@ -0,0 +1,30 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+SET script_path="%~dp0\..\run"
+IF EXIST %script_path% (
+    node %script_path% %* --device --nobuild
+) ELSE (
+    ECHO.
+    ECHO ERROR: Could not find 'deploy' in cordova, aborting...>&2
+    EXIT /B 1
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/install-emulator.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/install-emulator.bat b/template/cordova/lib/install-emulator.bat
new file mode 100644
index 0000000..c3a2b73
--- /dev/null
+++ b/template/cordova/lib/install-emulator.bat
@@ -0,0 +1,30 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+SET script_path="%~dp0\..\run"
+IF EXIST %script_path% (
+    node %script_path% %* --emulator --nobuild
+) ELSE (
+    ECHO. 
+    ECHO ERROR: Could not find 'run' in cordova, aborting...>&2
+    EXIT /B 1
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/list-devices.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/list-devices.bat b/template/cordova/lib/list-devices.bat
new file mode 100644
index 0000000..47e911d
--- /dev/null
+++ b/template/cordova/lib/list-devices.bat
@@ -0,0 +1,30 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+SET script_path="%~dp0target-list.js"
+IF EXIST %script_path% (
+    node %script_path% %* --devices
+) ELSE (
+    ECHO. 
+    ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
+    EXIT /B 1
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/list-emulator-images.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/list-emulator-images.bat b/template/cordova/lib/list-emulator-images.bat
new file mode 100644
index 0000000..0232002
--- /dev/null
+++ b/template/cordova/lib/list-emulator-images.bat
@@ -0,0 +1,30 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+SET script_path="%~dp0target-list.js"
+IF EXIST %script_path% (
+    node %script_path% %* --emulators
+) ELSE (
+    ECHO. 
+    ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
+    EXIT /B 1
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/list-started-emulators.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/list-started-emulators.bat b/template/cordova/lib/list-started-emulators.bat
new file mode 100644
index 0000000..7c5c7f9
--- /dev/null
+++ b/template/cordova/lib/list-started-emulators.bat
@@ -0,0 +1,24 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+ECHO Sorry, list-started-emulators is not availible yet for Windows Phone. 1>&2
+EXIT /B 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/package.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/package.js b/template/cordova/lib/package.js
new file mode 100644
index 0000000..e7eeb89
--- /dev/null
+++ b/template/cordova/lib/package.js
@@ -0,0 +1,63 @@
+/*
+       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 Q     = require('q'),
+    fs    = require('fs'),
+    path  = require('path'),
+    shell = require('shelljs'),
+    utils = require('./utils');
+
+function Package (packagepath) {
+    this.packagePath = packagepath;
+}
+
+Package.prototype.deployTo = function (deployTarget) {
+    var pkg = this;
+    return utils.getXapDeploy()
+    .then(function (xapDeploy) {
+        var getTarget = deployTarget == "device" ? Q("de") :
+            deployTarget == "emulator" ? Q("xd") : module.exports.findDevice(deployTarget);
+
+        return getTarget.then(function (target) {
+            return utils.spawn(xapDeploy, ['/installlaunch', pkg.packagePath, '/targetdevice:' + target]);
+        });
+    });
+};
+
+// returns full path to package with chip architecture, build and project types specified
+module.exports.getPackage = function (buildtype, buildarch) {
+    var projectPath = path.resolve(path.join(__dirname, '..', '..'));
+    var buildFolder = buildarch.toLowerCase() == 'anycpu' ?
+        path.join(projectPath, 'Bin', buildtype) :
+        path.join(projectPath, 'Bin', buildarch, buildtype);
+
+    // reject promise if buildFolder folder doesn't exists
+    if (!fs.existsSync(buildFolder)) {
+        return Q.reject('Directory with build artefacts doesn\'t exists');
+    }
+
+    // search for first .appx file in specified folder
+    var appxFiles = shell.ls(path.join(buildFolder, '*.xap'));
+    if (appxFiles && appxFiles[0]) {
+        // resolve with full path to file if found
+        return Q.resolve(new Package(appxFiles[0]));
+    }
+    // else reject with error
+    return Q.reject('Can\'t find package with ' + buildtype + ' build type and ' + buildarch + ' chip architecture');
+};

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/run.js b/template/cordova/lib/run.js
new file mode 100644
index 0000000..c179ced
--- /dev/null
+++ b/template/cordova/lib/run.js
@@ -0,0 +1,88 @@
+/*
+       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 Q = require('q'),
+    nopt  = require('nopt'),
+    path  = require('path'),
+    build = require('./build'),
+    utils = require('./utils'),
+    packages = require('./package');
+
+var ROOT = path.join(__dirname, '..', '..');
+
+module.exports.run = function (argv) {
+    if (!utils.isCordovaProject(ROOT)){
+        return Q.reject("Could not find project at " + ROOT);
+    }
+
+    // parse args
+    var args  = nopt({"debug": Boolean, "release": Boolean, "nobuild": Boolean,
+        "device": Boolean, "emulator": Boolean, "target": String, "archs": String},
+        {"r" : "--release"}, argv);
+
+    // Validate args
+    if (args.debug && args.release) {
+        return Q.reject('Only one of "debug"/"release" options should be specified');
+    }
+    if ((args.device && args.emulator) || ((args.device || args.emulator) && args.target)) {
+        return Q.reject('Only one of "device"/"emulator"/"target" options should be specified');
+    }
+
+    // Get build/deploy options
+    var buildType    = args.release ? "release" : "debug",
+        buildArchs   = args.archs ? args.archs.split(' ') : ["anycpu"],
+        deployTarget = args.target ? args.target : args.device ? "device" : "emulator";
+
+    // if --nobuild isn't specified then build app first
+    var buildPackages = args.nobuild ? Q() : build.run(argv);
+
+    return buildPackages
+    .then(function () {
+        return packages.getPackage(buildType, buildArchs[0]);
+    })
+    .then(function(builtPackage) {
+        console.log('\nDeploying package to ' + deployTarget);
+        return builtPackage.deployTo(deployTarget);
+    });
+};
+
+module.exports.help = function () {
+    console.log("");
+    console.log("Usage:");
+    console.log("  run [ --device || --emulator || --target=<id> ] ");
+    console.log("      [ --debug || --release || --nobuild ]");
+    console.log("      [--archs=\"<list of architectures...>\"]");
+    console.log("    --device      : Deploys and runs the project on the connected device.");
+    console.log("    --emulator    : [DEFAULT] Deploys and runs the project on an emulator.");
+    console.log("    --target=<id> : Deploys and runs the project on the specified target.");
+    console.log("    --debug       : [DEFAULT] Builds project in debug mode.");
+    console.log("    --release     : Builds project in release mode.");
+    console.log("    --nobuild     : Ueses pre-built xap, or errors if project is not built.");
+    console.log("    --archs       : Builds project binaries for specific chip architectures.");
+    console.log("                    Deploys and runs package with first architecture specified.");
+    console.log("                    arm` and `x86` are supported for wp8");
+    console.log("Examples:");
+    console.log("    run");
+    console.log("    run --emulator");
+    console.log("    run --device");
+    console.log("    run --target=7988B8C3-3ADE-488d-BA3E-D052AC9DC710");
+    console.log("    run --device --release");
+    console.log("    run --emulator --debug");
+    console.log("");
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/start-emulator.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/start-emulator.bat b/template/cordova/lib/start-emulator.bat
new file mode 100644
index 0000000..ca7c18e
--- /dev/null
+++ b/template/cordova/lib/start-emulator.bat
@@ -0,0 +1,24 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+ECHO Sorry, start-emulator is not availible yet for Windows Phone. 1>&2
+EXIT /B 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/target-list.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/target-list.js b/template/cordova/lib/target-list.js
new file mode 100644
index 0000000..9d85510
--- /dev/null
+++ b/template/cordova/lib/target-list.js
@@ -0,0 +1,49 @@
+/*
+       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 devices = require('./device'),
+    args = process.argv.slice(2);
+
+// help/usage function
+function help() {
+    console.log("");
+    console.log("Usage: node target-list.js  [ --emulators | --devices | --started_emulators | --all ]");
+    console.log("    --emulators         : List the possible target emulators availible.");
+    console.log("    --devices           : List the possible target devices availible. *NOT IMPLEMENTED YET*");
+    console.log("    --started_emulators : List any started emulators availible. *NOT IMPLEMENTED YET*");
+    console.log("    --all               : List all devices returned by CordovaDeploy.exe -devices ");
+    console.log("examples:");
+    console.log("    node target-list.js --emulators");
+    console.log("    node target-list.js --devices");
+    console.log("    node target-list.js --started_emulators");
+    console.log("    node target-list.js --all");
+    console.log("");
+}
+
+// Handle help flag
+if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[0]) > -1) {
+    help();
+} else {
+    devices.listDevices()
+    .then(function (deviceList) {
+        deviceList.forEach(function (device) {
+            console.log(device);
+        });
+    });
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/utils.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/utils.js b/template/cordova/lib/utils.js
new file mode 100644
index 0000000..28fb018
--- /dev/null
+++ b/template/cordova/lib/utils.js
@@ -0,0 +1,120 @@
+/*
+       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 Q    = require('Q'),
+    fs   = require('fs'),
+    path = require('path'),
+    proc = require('child_process'),
+    msbuildTools = require('./MSBuildTools');
+
+// returns path to XapDeploy util from Windows Phone 8.1 SDK
+module.exports.getXapDeploy = function () {
+    var xapDeployUtils = path.join((process.env["ProgramFiles(x86)"] || process.env["ProgramFiles"]),
+        'Microsoft SDKs', 'Windows Phone', 'v8.0', 'Tools', 'Xap Deployment', 'XapDeployCmd.exe');
+    // Check if XapDeployCmd is exists
+    if (!fs.existsSync(xapDeployUtils)) {
+        console.warn("WARNING: XapDeploy tool (XapDeployCmd.exe) didn't found. Assume that it's in %PATH%");
+        return Q.resolve("XapDeployCmd");
+    }
+    return Q.resolve(xapDeployUtils);
+};
+
+module.exports.getOSVersion = function () {
+    return module.exports.exec('reg query "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CurrentVersion')
+    .then(function(output) {
+        // fetch msbuild path from 'reg' output
+        var version = /CurrentVersion\s+REG_SZ\s+(.*)/i.exec(output);
+        if (version) {
+            return Q.resolve(version[1]);
+        }
+        return Q.reject('Can\'t fetch version number from reg output');
+    }, function (err) {
+        return Q.reject('Failed to query OS version ' + err);
+    });
+};
+
+module.exports.getSDKVersion = function () {
+    var is64bitSystem = process.env["PROCESSOR_ARCHITECTURE"] != 'x86';
+    return msbuildTools.findAvailableVersion(is64bitSystem)
+    .then(function (msbuild) {
+        return module.exports.exec(module.exports.quote(path.join(msbuild.path, 'msbuild')) + ' -version')
+        .then(function (output) {
+            var version = /\.NET\sFramework\,\s[a-z]+\s(\d+\.\d+\.\d+)/gi.exec(output);
+            if (version) {
+                return Q.resolve(version[1]);
+            }
+            return Q.reject('Unable to get the .NET Framework version');
+        }, function (err) {
+            return Q.reject('Unable to get the .NET Framework version: ' + err);
+        });
+    });
+};
+
+// checks to see if a .jsproj file exists in the project root
+module.exports.isCordovaProject = function (platformpath) {
+    if (fs.existsSync(platformpath)) {
+        var files = fs.readdirSync(platformpath);
+        for (var i in files){
+            if (path.extname(files[i]) == '.csproj'){
+                return true;
+            }
+        }
+    }
+    return false;
+};
+
+// Takes a command and optional current working directory.
+// Returns a promise that either resolves with the stdout, or
+// rejects with an error message and the stderr.
+module.exports.exec = function(cmd, opt_cwd) {
+    var d = Q.defer();
+    try {
+        proc.exec(cmd, {cwd: opt_cwd, maxBuffer: 1024000}, function(err, stdout, stderr) {
+            if (err) d.reject('Error executing "' + cmd + '": ' + stderr);
+            else d.resolve(stdout);
+        });
+    } catch(e) {
+        console.error('error caught: ' + e);
+        d.reject(e);
+    }
+    return d.promise;
+};
+
+// Takes a command and optional current working directory.
+module.exports.spawn = function(cmd, args, opt_cwd) {
+    var d = Q.defer();
+    try {
+        var child = proc.spawn(cmd, args, {cwd: opt_cwd, stdio: 'inherit'});
+        child.on('exit', function(code) {
+            if (code) {
+                d.reject('Error code ' + code + ' for command: ' + cmd + ' with args: ' + args);
+            } else {
+                d.resolve();
+            }
+        });
+    } catch(e) {
+        console.error('error caught: ' + e);
+        d.reject(e);
+    }
+    return d.promise;
+};
+
+module.exports.quote = function(str) {
+    return '"' + str + '"';
+};

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/win_os_version.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/win_os_version.js b/template/cordova/lib/win_os_version.js
new file mode 100644
index 0000000..c6d940f
--- /dev/null
+++ b/template/cordova/lib/win_os_version.js
@@ -0,0 +1,27 @@
+/*
+       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 utils = require('./utils');
+
+utils.getOSVersion().then(function (version) {
+    console.log(version);
+}, function (err) {
+    console.error(err);
+    process.exit(2);
+});

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/lib/win_sdk_version.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/win_sdk_version.js b/template/cordova/lib/win_sdk_version.js
new file mode 100644
index 0000000..e624ac8
--- /dev/null
+++ b/template/cordova/lib/win_sdk_version.js
@@ -0,0 +1,27 @@
+/*
+       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 utils = require('./utils');
+
+utils.getSDKVersion().then(function (version) {
+    console.log(version);
+}, function (err) {
+    console.error(err);
+    process.exit(2);
+});

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/log.bat
----------------------------------------------------------------------
diff --git a/template/cordova/log.bat b/template/cordova/log.bat
new file mode 100644
index 0000000..009e5b3
--- /dev/null
+++ b/template/cordova/log.bat
@@ -0,0 +1,25 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+@ECHO OFF
+ECHO Sorry, logging is not supported for Windows Phone. 1>&2
+EXIT /B 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/run
----------------------------------------------------------------------
diff --git a/template/cordova/run b/template/cordova/run
new file mode 100644
index 0000000..48c77d5
--- /dev/null
+++ b/template/cordova/run
@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+
+/*
+       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 = process.argv,
+    run   = require('./lib/run');
+
+// Handle help flag
+if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[2]) > -1) {
+    run.help();
+} else {
+    run.run(args).done(null, function (err) {
+        var errorMessage = (err && err.stack) ? err.stack : err;
+        console.error('ERROR: ' + errorMessage);
+        process.exit(2);
+    });
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/run.bat
----------------------------------------------------------------------
diff --git a/template/cordova/run.bat b/template/cordova/run.bat
new file mode 100644
index 0000000..68ed160
--- /dev/null
+++ b/template/cordova/run.bat
@@ -0,0 +1,30 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+SET script_path="%~dp0run"
+IF EXIST %script_path% (
+        node %script_path% %*
+) ELSE (
+    ECHO.
+    ECHO ERROR: Could not find 'run' in cordova, aborting...>&2
+    EXIT /B 1
+)

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/version.bat
----------------------------------------------------------------------
diff --git a/template/cordova/version.bat b/template/cordova/version.bat
new file mode 100644
index 0000000..fb4a129
--- /dev/null
+++ b/template/cordova/version.bat
@@ -0,0 +1,31 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+@ECHO OFF
+SET script_path="%~dp0..\VERSION"
+IF EXIST %script_path% (
+    type %script_path%
+) ELSE (
+    ECHO.
+    ECHO ERROR: Could not find file VERSION in project folder, path tried was %script_path% >&2
+    EXIT /B 1
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/win_os_version.bat
----------------------------------------------------------------------
diff --git a/template/cordova/win_os_version.bat b/template/cordova/win_os_version.bat
new file mode 100644
index 0000000..97a69c9
--- /dev/null
+++ b/template/cordova/win_os_version.bat
@@ -0,0 +1,30 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+SET script_path="%~dp0lib\win_os_version.js"
+IF EXIST %script_path% (
+    node %script_path% %*
+) ELSE (
+    ECHO.
+    ECHO ERROR: Could not find 'win_os_version.js' in 'bin' folder, aborting...>&2
+    EXIT /B 1
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordova/win_sdk_version.bat
----------------------------------------------------------------------
diff --git a/template/cordova/win_sdk_version.bat b/template/cordova/win_sdk_version.bat
new file mode 100644
index 0000000..0a1a2ca
--- /dev/null
+++ b/template/cordova/win_sdk_version.bat
@@ -0,0 +1,30 @@
+@ECHO OFF
+goto endheader
+#
+# 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.
+#
+:endheader
+
+SET script_path="%~dp0lib\win_sdk_version.js"
+IF EXIST %script_path% (
+    node %script_path% %*
+) ELSE (
+    ECHO.
+    ECHO ERROR: Could not find 'win_sdk_version.js' in 'bin' folder, aborting...>&2
+    EXIT /B 1
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordovalib/BrowserMouseHelper.cs
----------------------------------------------------------------------
diff --git a/template/cordovalib/BrowserMouseHelper.cs b/template/cordovalib/BrowserMouseHelper.cs
new file mode 100644
index 0000000..fc83e03
--- /dev/null
+++ b/template/cordovalib/BrowserMouseHelper.cs
@@ -0,0 +1,162 @@
+/*
+ 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
+    {
+        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;
+
+        /// <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);             
+            var grid2 = VisualTreeHelper.GetChild(grid, 0);
+            border = VisualTreeHelper.GetChild(grid2, 0) as Border;
+            
+            if (border != null)
+            {
+                border.ManipulationDelta += Border_ManipulationDelta;
+                border.ManipulationCompleted += Border_ManipulationCompleted;
+            }
+
+            _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();
+        }
+
+        #region ManipulationEvents
+
+        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;
+            }
+            // optionally suppress scrolling
+            if (ScrollDisabled && (e.DeltaManipulation.Translation.X != 0.0 || e.DeltaManipulation.Translation.Y != 0.0))
+            {
+                e.Handled = true;
+            }
+        }
+
+        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
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordovalib/CommandFactory.cs
----------------------------------------------------------------------
diff --git a/template/cordovalib/CommandFactory.cs b/template/cordovalib/CommandFactory.cs
new file mode 100644
index 0000000..4bd5a09
--- /dev/null
+++ b/template/cordovalib/CommandFactory.cs
@@ -0,0 +1,128 @@
+/*  
+	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 Cordova 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>
+        /// alias can be used as a namespace which is resolved + service
+        /// or it can be the fully qualified classname
+        /// or the classname in the current assembly
+        public static BaseCommand CreateByServiceName(string service, string alias="")
+        {
+
+            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);
+
+                if (t == null && !string.IsNullOrEmpty(alias))
+                {
+                    t = Type.GetType(alias);
+
+                    if (t == null)
+                    {
+                        t = Type.GetType(BaseCommandNamespacePrefix + alias);
+                    }
+
+                    if (t == null)
+                    {
+                        t = Type.GetType(alias + "." + 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();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordovalib/Commands/BaseCommand.cs
----------------------------------------------------------------------
diff --git a/template/cordovalib/Commands/BaseCommand.cs b/template/cordovalib/Commands/BaseCommand.cs
new file mode 100644
index 0000000..3e2e690
--- /dev/null
+++ b/template/cordovalib/Commands/BaseCommand.cs
@@ -0,0 +1,197 @@
+/*  
+	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 void DetachHandlers()
+        {
+            this.OnCommandResult = null;
+            this.OnCustomScript = null;
+            foreach (string callbackId in new List<string>(ResultHandlers.Keys))
+            {
+                RemoveResultHandler(callbackId);
+            }
+        }
+
+        public static string GetBaseURL()
+        {
+#if CORDOVA_CLASSLIB
+            return "/WPCordovaClassLib;component/";
+#else
+            return "./";
+#endif
+        }
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordovalib/ConfigHandler.cs
----------------------------------------------------------------------
diff --git a/template/cordovalib/ConfigHandler.cs b/template/cordovalib/ConfigHandler.cs
new file mode 100644
index 0000000..e2575f7
--- /dev/null
+++ b/template/cordovalib/ConfigHandler.cs
@@ -0,0 +1,289 @@
+/*  
+    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.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, string className = "")
+            {
+                Name = name;
+                isAutoLoad = autoLoad;
+                ClassName = className;
+            }
+            public string Name;
+            public bool isAutoLoad;
+            public string ClassName;
+        }
+
+        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.ContainsKey(key.ToLowerInvariant()) ? Preferences[key.ToLowerInvariant()] : null;
+        }
+
+        protected static string[] AllowedSchemes = { "http", "https", "ftp", "ftps" };
+        protected bool SchemeIsAllowed(string scheme)
+        {
+            return AllowedSchemes.Contains(scheme);
+        }
+
+        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 + uri.PathAndQuery;
+                //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 (this.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 (uri.PathAndQuery == "/")
+                        {
+                            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(uri.PathAndQuery, pattern)))
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public string GetNamespaceForCommand(string key)
+        {
+            if(AllowedPlugins.Keys.Contains(key))
+            {
+                return AllowedPlugins[key].Name;
+            }
+            
+            return "";
+        }
+
+        public bool IsPluginAllowed(string key)
+        {
+            return AllowAllPlugins || AllowedPlugins.Keys.Contains(key);
+        }
+
+        public string[] AutoloadPlugins
+        {
+            get
+            {
+                // TODO:
+                var res = from results in AllowedPlugins.TakeWhile(p => p.Value.isAutoLoad)
+                          select results.Value.Name;
+
+                return res.ToArray<string>();
+            }
+        }
+
+        private void LoadPluginFeatures(XDocument document)
+        {
+            var features = from feats in document.Descendants()
+                           where feats.Name.LocalName == "feature"
+                           select feats;
+
+            foreach (var feature in features)
+            {
+                string name = (string)feature.Attribute("name");
+                var value = (from results in feature.Descendants()
+                             where results.Name.LocalName == "param" && ((string)results.Attribute("name") == "wp-package")
+                             select results).FirstOrDefault();
+
+                var autoloadNode = (from results in feature.Descendants()
+                                    where results.Name.LocalName == "param" && ((string)results.Attribute("name") == "onload")
+                                    select results).FirstOrDefault();
+                bool isAutoLoad = false;
+                if (autoloadNode != null)
+                {
+                    isAutoLoad = ((string)autoloadNode.Attribute("value") == "true");
+                }
+
+                if (value != null)
+                {
+                    string key = (string)value.Attribute("value");
+                    Debug.WriteLine("Adding feature.value=" + key);
+                    PluginConfig pConfig = new PluginConfig(key, isAutoLoad);
+                    AllowedPlugins[name] = 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()
+                                  where results.Name.LocalName == "preference"
+                                  select new
+                                  {
+                                      name = (string)results.Attribute("name"),
+                                      value = (string)results.Attribute("value")
+                                  };
+
+                foreach (var pref in preferences)
+                {
+                    Preferences[pref.name.ToLowerInvariant()] = pref.value;
+                }
+
+                var accessList = from results in document.Descendants()
+                                 where results.Name.LocalName == "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 = (from results in document.Descendants()
+                                   where results.Name.LocalName == "content"
+                                   select results).FirstOrDefault();
+
+                if (contentsTag != null)
+                {
+                    var src = contentsTag.Attribute("src");
+                    ContentSrc = (string)src.Value;
+                }
+            }
+            else
+            {
+                // no config.xml, allow all
+                AllowAllDomains = true;
+                AllowAllPlugins = true;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordovalib/ConsoleHelper.cs
----------------------------------------------------------------------
diff --git a/template/cordovalib/ConsoleHelper.cs b/template/cordovalib/ConsoleHelper.cs
new file mode 100644
index 0000000..3443821
--- /dev/null
+++ b/template/cordovalib/ConsoleHelper.cs
@@ -0,0 +1,100 @@
+/*  
+    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.Shell;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Linq;
+using System.Text;
+
+namespace WPCordovaClassLib.CordovaLib
+{
+    class ConsoleHelper : IBrowserDecorator
+    {
+
+        public WebBrowser Browser { get; set; }
+
+        protected bool hasListener = false;
+
+
+
+        public void InjectScript()
+        {
+            using(IsolatedStorageFileStream file = new IsolatedStorageFileStream("debugOutput.txt", FileMode.Create, FileAccess.Write, IsolatedStorageFile.GetUserStoreForApplication()))
+            {
+            }
+
+            if (!hasListener)
+            {
+                PhoneApplicationService.Current.Closing += OnServiceClosing;
+                hasListener = true;
+            }
+
+
+            string script = @"(function(win) {
+        function exec(msg) { window.external.Notify('ConsoleLog/' + msg); }
+        var cons = win.console = win.console || {};
+        cons.log = exec;
+        cons.debug = cons.debug || cons.log;
+        cons.info = cons.info   || function(msg) { exec('INFO:' + msg ); };     
+        cons.warn = cons.warn   || function(msg) { exec('WARN:' + msg ); };
+        cons.error = cons.error || function(msg) { exec('ERROR:' + msg ); };
+    })(window);";
+
+            Browser.InvokeScript("eval", new string[] { script });
+        }
+
+        void OnServiceClosing(object sender, ClosingEventArgs e)
+        {
+            using (IsolatedStorageFileStream file = new IsolatedStorageFileStream("debugOutput.txt", FileMode.Append, FileAccess.Write, IsolatedStorageFile.GetUserStoreForApplication()))
+            {
+                using (StreamWriter writeFile = new StreamWriter(file))
+                {
+                    writeFile.WriteLine("EXIT");
+                    writeFile.Close();
+                }
+                file.Close();
+            }
+        }
+
+        public void DetachHandler()
+        {
+            if (hasListener)
+            {
+                PhoneApplicationService.Current.Closing -= OnServiceClosing;
+                hasListener = false;
+            }
+        }
+
+        public bool HandleCommand(string commandStr)
+        {
+            string output = commandStr.Substring("ConsoleLog/".Length);
+            Debug.WriteLine(output);
+            using (IsolatedStorageFileStream file = new IsolatedStorageFileStream("debugOutput.txt", FileMode.Append, FileAccess.Write, IsolatedStorageFile.GetUserStoreForApplication()))
+            {
+                using (StreamWriter writeFile = new StreamWriter(file))
+                {
+                    writeFile.WriteLine(output);
+                    writeFile.Close();
+                }
+                file.Close();
+            }
+            return true;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordovalib/CordovaCommandCall.cs
----------------------------------------------------------------------
diff --git a/template/cordovalib/CordovaCommandCall.cs b/template/cordovalib/CordovaCommandCall.cs
new file mode 100644
index 0000000..7b9ee0c
--- /dev/null
+++ b/template/cordovalib/CordovaCommandCall.cs
@@ -0,0 +1,101 @@
+/*  
+	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; }
+        public String Namespace { get; 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)
+        {
+            //System.Diagnostics.Debug.WriteLine("CommandString : " + 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];
+            commandCallParameters.Namespace = String.Empty; 
+
+            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() { }
+
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/c74fdafa/template/cordovalib/CordovaView.xaml
----------------------------------------------------------------------
diff --git a/template/cordovalib/CordovaView.xaml b/template/cordovalib/CordovaView.xaml
new file mode 100644
index 0000000..fce54bb
--- /dev/null
+++ b/template/cordovalib/CordovaView.xaml
@@ -0,0 +1,63 @@
+<!--
+ 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.0"
+                          HorizontalAlignment="Stretch"  
+                          VerticalAlignment="Stretch" 
+                          IsScriptEnabled="True" 
+                          Foreground="White"
+                          Background="Black"
+                          Navigated="CordovaBrowser_Navigated" 
+                          Loaded="CordovaBrowser_Loaded" 
+                          Unloaded="CordovaBrowser_Unloaded" 
+                          ScriptNotify="CordovaBrowser_ScriptNotify" 
+                          LoadCompleted="CordovaBrowser_LoadCompleted" 
+                          Navigating="CordovaBrowser_Navigating" 
+                          NavigationFailed="CordovaBrowser_NavigationFailed" 
+                          IsGeolocationEnabled="True">
+
+            <phone:WebBrowser.Resources>      
+                <Storyboard x:Name="FadeIn">
+                    <DoubleAnimation Duration="0:0:0.6" 
+                            To="1.0"
+                            Storyboard.TargetName="CordovaBrowser" 
+                            Storyboard.TargetProperty="Opacity"/>
+                </Storyboard>
+            </phone:WebBrowser.Resources>
+
+        </phone:WebBrowser>
+        
+    </Grid>
+</UserControl>
+
+