You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2014/09/16 01:40:36 UTC

[2/2] git commit: Revert "Merge branch 'browserPlatform' of https://github.com/surajpindoria/cordova-lib"

Revert "Merge branch 'browserPlatform' of https://github.com/surajpindoria/cordova-lib"

This reverts commit 405d0da0fc8ba1598192b7ef212854b9d7542bf8, reversing
changes made to ace7e33531e3dce2ac84038ca4c76fb4cfc4657f.


Project: http://git-wip-us.apache.org/repos/asf/cordova-lib/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-lib/commit/a0177955
Tree: http://git-wip-us.apache.org/repos/asf/cordova-lib/tree/a0177955
Diff: http://git-wip-us.apache.org/repos/asf/cordova-lib/diff/a0177955

Branch: refs/heads/master
Commit: a01779552ad240dc2e2a550376ce6e2978eeba8b
Parents: 405d0da
Author: Anis Kadri <an...@apache.org>
Authored: Mon Sep 15 16:39:52 2014 -0700
Committer: Anis Kadri <an...@apache.org>
Committed: Mon Sep 15 16:39:52 2014 -0700

----------------------------------------------------------------------
 .travis.yml                                     |   4 +-
 README.md                                       |   3 +-
 cordova-lib/RELEASENOTES.md                     | 146 +----------
 cordova-lib/package.json                        |  10 +-
 cordova-lib/spec-cordova/ConfigParser.spec.js   | 163 ------------
 .../fixtures/plugins/malformed/plugin.xml       |  10 -
 .../spec-cordova/metadata/ios_parser.spec.js    |   4 +-
 .../metadata/windows8_parser.spec.js            |   5 +-
 .../spec-cordova/metadata/wp8_parser.spec.js    |   7 +-
 cordova-lib/spec-cordova/test-config.xml        |  27 +-
 .../spec-plugman/install-browserify.spec.js     |   6 +-
 cordova-lib/spec-plugman/install.spec.js        |   5 +-
 cordova-lib/spec-plugman/platforms/ios.spec.js  |   2 +-
 .../spec-plugman/platforms/windows8.spec.js     |   6 +-
 .../projects/android_install/cordova/version    |  24 +-
 .../projects/android_one/cordova/version.bat    |   2 -
 .../projects/android_uninstall/cordova/version  |  23 +-
 .../spec-plugman/util/config-changes.spec.js    |   2 +-
 cordova-lib/src/PluginInfo.js                   |  18 +-
 cordova-lib/src/configparser/ConfigParser.js    | 102 +-------
 .../src/configparser/ConfigParser.spec.js       |  99 ++++++++
 cordova-lib/src/cordova/create.js               |  14 +-
 .../cordova/metadata/amazon_fireos_parser.js    | 253 ++++++++-----------
 .../src/cordova/metadata/android_parser.js      |  15 --
 .../src/cordova/metadata/firefoxos_parser.js    |   6 +-
 cordova-lib/src/cordova/metadata/ios_parser.js  |  63 +----
 .../src/cordova/metadata/ubuntu_parser.js       |  20 +-
 .../src/cordova/metadata/windows_parser.js      |  40 ++-
 cordova-lib/src/cordova/metadata/wp8_parser.js  |  41 ++-
 cordova-lib/src/cordova/platform.js             |  46 ++--
 cordova-lib/src/cordova/platforms.js            |  20 +-
 cordova-lib/src/cordova/prepare.js              |   2 +-
 cordova-lib/src/cordova/restore.js              |  60 +++--
 cordova-lib/src/cordova/superspawn.js           |   7 -
 cordova-lib/src/plugman/create.js               |  16 +-
 cordova-lib/src/plugman/install.js              |   4 +-
 cordova-lib/src/plugman/platform.js             |  24 +-
 cordova-lib/src/plugman/platforms/ios.js        |   4 +-
 cordova-lib/src/plugman/platforms/ubuntu.js     |  37 +--
 cordova-lib/src/plugman/platforms/windows.js    |  10 +-
 cordova-lib/src/plugman/prepare.js              |  23 +-
 cordova-lib/src/plugman/registry/manifest.js    |   9 +-
 cordova-lib/src/plugman/util/action-stack.js    |  15 +-
 cordova-lib/src/plugman/util/android-project.js |  15 +-
 cordova-lib/src/plugman/util/config-changes.js  |  19 +-
 cordova-lib/src/plugman/util/plist-helpers.js   |   6 +-
 cordova-lib/src/util/windows/jsproj.js          |   6 +
 47 files changed, 502 insertions(+), 941 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 3cf588b..f96ddca 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,4 @@
 language: node_js
-git:
-  depth: 10
 node_js:
   - "0.10"
-before_install: cd cordova-lib
+before_install: cd cordova-lib
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index c28cae4..ec4e3df 100644
--- a/README.md
+++ b/README.md
@@ -21,8 +21,7 @@
 
 [![Build status](https://ci.appveyor.com/api/projects/status/q9s459ssqvs1t7j6/branch/master)](https://ci.appveyor.com/project/Humbedooh/cordova-lib)
 [![Build Status](https://travis-ci.org/apache/cordova-lib.svg?branch=master)](https://travis-ci.org/apache/cordova-lib)
-[![npm version](http://b.adge.me/npm/v/cordova-lib.svg)](https://www.npmjs.org/package/cordova-lib)  
-[BuildBot waterfall](http://ci.cordova.io/) with [cordova-mobile-spec](https://github.com/apache/cordova-mobile-spec) running on real Android and iOS devices.
+[![npm version](http://b.adge.me/npm/v/cordova-lib.svg)](https://www.npmjs.org/package/cordova-lib)
 
 # cordova-lib
 Contains npm modules used primarily by [cordova](https://github.com/apache/cordova-cli/) and [plugman](https://github.com/apache/cordova-plugman/).

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/RELEASENOTES.md
----------------------------------------------------------------------
diff --git a/cordova-lib/RELEASENOTES.md b/cordova-lib/RELEASENOTES.md
index 7beae1c..7dc6914 100644
--- a/cordova-lib/RELEASENOTES.md
+++ b/cordova-lib/RELEASENOTES.md
@@ -20,149 +20,6 @@
 -->
 # Cordova-lib Release Notes
 
-### 0.21.10 (Sep 05, 2014)
-* CB-7457 - cordova plugin add --searchpath does not recurse through subfolders when a plugin.xml is malformed in one of them
-* CB-7457 - Add malformed plugin for tests
-* [Windows8] Fix failing test to match updated functionality
-* CB-7420 Windows. Plugin <resource-file>s are removed from platform during prepare
-* Windows helper. Removes unnecessary $(MSBuildThisFileDirectory)
-* updated Releasenotes.md
-* updated version to 0.21.10-dev
-* CB-7457 - cordova plugin add --searchpath does not recurse through subfolders when a plugin.xml is malformed in one of them
-* CB-7457 - Add malformed plugin for tests
-* [Windows8] Fix failing test to match updated functionality
-* updated Releasenotes.md
-* updated version to 0.21.10-dev
-* updated version, updated ffos to use 3.6.1, updated cordova-js dependency to be strcit
-* CB-7383 Incremented package version to -dev
-* updated platforms.js to use 3.6.0
-*  Updated version and RELEASENOTES.md for release 0.21.8
-* CB-5535: Remove "--arc" from ios platform creation args
-* Windows helper. Removes unnecessary $(MSBuildThisFileDirectory)
-* CB-7420 Windows. Plugin <resource-file>s are removed from platform during prepare
-* CB-7416 Fixes file path reference when adding new source file
-* CB-7416 handleInstall tests for null platformTag. removed uncalled 'hasPlatformSection' from PluginInfo.js
-* Remove use of path.join for manifest.launch_path
-* CB-7347 Improve cordova platform add /path/to handling
-* CB-7118 (fix jshint warnings)
-* CB-7114 Android: add support of min/max/target SDK to config.xml
-* CB-7118 Use updated version of node-xcode
-* CB-7118 iOS: add target-device and MinimumOSVersion support to config.xml
-* ubuntu: support incremental builds
-* ubuntu: support target-dir for resource-file
-* ubuntu: use common.copyFile
-* ubuntu: check icon existence
-* ffos: Make author url optional
-* CB-7142 Add <variable> to <feature> for "plugin restore" command
-* Set git clone depth to 10 for Travis to make it faster
-* windows: update as per changed manifest file names
-* Don't spy and expect it to call the other spy ...
-* Well that looks like an error
-* Fixing failing tests: update_proj should be update_project
-* Fix failing tests. update_jsproj and update_csproj are now just update_proj
-* Fix jshint errors in amazon_fireos_parser : mixed single/double quotes
-* CB-6699 Include files from www folder via single element (use ** glob pattern)
-* Taking care of dashes in amazon-fireos platform name.
-* Upleveled amazon-fireos changes.
-* Fix link/copy parent check for windows
-* Style fixes - comments
-* Fix error in comments for munge functions
-* Add link to BuildBot at ci.cordova.io in README
-* CB-7255 Fixed writing plist unescaped
-* Allow plugin modules to be .json files
-* Style fixes - white space only
-* Add JSCS config file
-* CB-7260 Get cordova-android 3.5.1 instead of 3.5.0
-* CB-7228: Fixed issue with "cordova prepare --browserify"
-* CB-7234 added better outputs for plugin registry workflows
-* CB-7100: Use npm based lazy-load by default
-* CB-7091: Remove check_requirements() funcs from platform parsers
-* CB-7091: Remove check_requirements() funcs from platform parsers
-* CB-7140 Check plugin versions in local search path
-* CB-7001: Create a --browserify option for run action
-* CB-7228: Cordova prepare --browserify runs on all installed plugins
-* CB-7190: Add browserify support in cordova-lib/cordova-cli
-* Remove references to "firefoxos"
-* Browser platform is now being created from cli
-* Created new files for browser
-
-### 0.21.8 (Aug 29, 2014)
-* CB-5535: Remove "--arc" from ios platform creation args
-* CB-7416 Fixes file path reference when adding new source file
-* CB-7416 handleInstall tests for null platformTag. removed uncalled 'hasPlatformSection' from PluginInfo.js
-* Remove use of path.join for manifest.launch_path
-* CB-7347 Improve cordova platform add /path/to handling
-* CB-7118 (fix jshint warnings)
-* CB-7114 Android: add support of min/max/target SDK to config.xml
-* CB-7118 Use updated version of node-xcode
-* CB-7118 iOS: add target-device and MinimumOSVersion support to config.xml
-* ubuntu: support incremental builds
-* ubuntu: support target-dir for resource-file
-* ubuntu: use common.copyFile
-* ubuntu: check icon existence
-* ffos: Make author url optional
-* CB-7142 Add <variable> to <feature> for "plugin restore" command
-* Set git clone depth to 10 for Travis to make it faster
-* windows: update as per changed manifest file names
-* Don't spy and expect it to call the other spy ...
-* Well that looks like an error
-* Fixing failing tests: update_proj should be update_project
-* Fix failing tests. update_jsproj and update_csproj are now just update_proj
-* Fix jshint errors in amazon_fireos_parser : mixed single/double quotes
-* CB-6699 Include files from www folder via single element (use ** glob pattern)
-* Allow plugin modules to be .json files
-* Taking care of dashes in amazon-fireos platform name.
-* Upleveled amazon-fireos changes.
-* Fix link/copy parent check for windows
-* Style fixes - comments
-* Fix error in comments for munge functions
-* Add link to BuildBot at ci.cordova.io in README
-* CB-7255 Fixed writing plist unescaped
-* Style fixes - white space only
-* Add JSCS config file
-* CB-7228: Fixed issue with "cordova prepare --browserify"
-* CB-7001: Create a --browserify option for run action
-* CB-7228: Cordova prepare --browserify runs on all installed plugins
-* CB-7190: Add browserify support in cordova-lib/cordova-cli
-* CB-7260 Get cordova-android 3.5.1 instead of 3.5.0
-* CB-7001: Create a --browserify option for run action
-* CB-7228: Cordova prepare --browserify runs on all installed plugins
-* CB-7190: Add browserify support in cordova-lib/cordova-cli
-* CB-7234 added better outputs for plugin registry workflows
-* CB-7100: Use npm based lazy-load by default
-* CB-7091: Remove check_requirements() funcs from platform parsers
-* CB-7091: Remove check_requirements() funcs from platform parsers
-* CB-7140 Check plugin versions in local search path
-* small refactor for missing code block after conditional statement
-* CB-7203 isRelativePath needs to pass path through
-* CB-7199 control git/npm using platform.js
-* CB-7199 control git/npm using platform.js
-* Fix style errors - make jshint happy
-* CB-6756 Adds save and restore command for platforms.
-* Add VERSION files to fix failing tests (forgot to git add in b7781cb)
-* CB-7132 Fix regression regarding default resources
-* CB-7187 Make CoreLocation a required library only for cordova-ios < 3.6.0
-* Add AppVeyor badge to README
-* Add Travis and npm badges to README.md
-* fix(tests): cordova/lazy_load spec on Windows
-* Fix plugman/install spec
-* build configuration for AppVeyor
-* build configurations for Travis
-* CB-7124 Wrap the cordova platform string in Platform object
-* CB-7140: Switch to using PluginInfo in plugman/fetch.js
-* Minor style fixes in fetch.js
-* CB-7078: Disable serve.spec.js
-* CB-6512: platform add <path> was using wrong www/cordova.js
-* CB-7083 Missing SDKReference support on Windows Phone
-* CB-6874 Consolidate <Content> tag additions into 1 ItemGroup
-* CB-7100: Use npm based lazy-load by default
-* CB-7091: Remove check_requirements() funcs from platform parsers
-* CB-7091: Don't call check_requirements during platform add
-* Fix typo in comment.
-* CB-7087 Retire blackberry10/ directory
-* CB-6776: Fix uri/url renaming bug
-* Remove npm-shrinkwrap.json
-
 
 ### 0.21.4 (Jun 23, 2014)
 * CB-3571, CB-2606: support for splashscreens
@@ -221,5 +78,4 @@
 
 
 ### 0.21.1
-Initial release v0.21.1 (picks up from the same version number as plugman was).
-
+Initial release v0.21.1 (picks up from the same version number as plugman was).
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/package.json
----------------------------------------------------------------------
diff --git a/cordova-lib/package.json b/cordova-lib/package.json
index 0c7e380..1518065 100644
--- a/cordova-lib/package.json
+++ b/cordova-lib/package.json
@@ -2,7 +2,7 @@
   "author": "Apache Software Foundation",
   "name": "cordova-lib",
   "description": "Apache Cordova tools core lib and API",
-  "version": "0.21.11-dev",
+  "version": "0.21.8-dev",
   "repository": {
     "type": "git",
     "url": "git://git-wip-us.apache.org/repos/asf/cordova-lib.git"
@@ -25,17 +25,17 @@
     "npm": "1.3.4",
     "npmconf": "0.1.x",
     "osenv": "0.0.x",
-    "plist": "1.0.x",
+    "plist-with-patches": "0.5.x",
     "properties-parser": "~0.2.3",
     "q": "~0.9",
     "rc": "0.3.0",
     "request": "2.22.0",
     "semver": "2.0.x",
-    "shelljs": "0.3.x",
+    "shelljs": "0.1.x",
     "tar": "0.1.x",
     "underscore": "1.4.4",
-    "xcode": "0.6.7",
-    "cordova-js": "3.6.3",
+    "xcode": "0.6.6",
+    "cordova-js": "3.x.x",
     "unorm": ">=1.3"
   },
   "devDependencies": {

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-cordova/ConfigParser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/ConfigParser.spec.js b/cordova-lib/spec-cordova/ConfigParser.spec.js
deleted file mode 100644
index 7028034..0000000
--- a/cordova-lib/spec-cordova/ConfigParser.spec.js
+++ /dev/null
@@ -1,163 +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 path = require('path'),
-    fs = require('fs'),
-    ConfigParser = require('../src/configparser/ConfigParser'),
-    xml = path.join(__dirname, 'test-config.xml'),
-    xml_contents = fs.readFileSync(xml, 'utf-8');
-
-describe('config.xml parser', function () {
-    var readFile;
-    beforeEach(function() {
-        readFile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
-    });
-
-    it('should create an instance based on an xml file', function() {
-        var cfg;
-        expect(function () {
-            cfg = new ConfigParser(xml);
-        }).not.toThrow();
-        expect(cfg).toBeDefined();
-        expect(cfg.doc).toBeDefined();
-    });
-
-    describe('methods', function() {
-        var cfg;
-        beforeEach(function() {
-            cfg = new ConfigParser(xml);
-        });
-
-        describe('package name / id', function() {
-            it('should get the (default) packagename', function() {
-                expect(cfg.packageName()).toEqual('io.cordova.hellocordova');
-            });
-            it('should allow setting the packagename', function() {
-                cfg.setPackageName('this.is.bat.country');
-                expect(cfg.packageName()).toEqual('this.is.bat.country');
-            });
-        });
-
-        describe('version', function() {
-            it('should get the version', function() {
-                expect(cfg.version()).toEqual('0.0.1');
-            });
-            it('should allow setting the version', function() {
-                cfg.setVersion('2.0.1');
-                expect(cfg.version()).toEqual('2.0.1');
-            });
-        });
-
-        describe('app name', function() {
-            it('should get the (default) app name', function() {
-                expect(cfg.name()).toEqual('Hello Cordova');
-            });
-            it('should allow setting the app name', function() {
-                cfg.setName('this.is.bat.country');
-                expect(cfg.name()).toEqual('this.is.bat.country');
-            });
-        });
-        describe('preference', function() {
-            it('should get value of existing preference', function() {
-                expect(cfg.getPreference('fullscreen')).toEqual('true');
-            });
-            it('should get undefined as non existing preference', function() {
-                expect(cfg.getPreference('zimzooo!')).toEqual(undefined);
-            });
-        });
-        describe('platform specific preference', function() {
-            it('should get value of existing platform specific preference', function() {
-                expect(cfg.getPreference('android-minSdkVersion', 'android')).toEqual('10');
-            });
-        });
-        describe('feature',function(){
-            it('should read feature id list', function() {
-               var expectedList = [
-                   "org.apache.cordova.featurewithvars",
-                   "org.apache.cordova.featurewithurl",
-                   "org.apache.cordova.featurewithversion",
-                   "org.apache.cordova.featurewithurlandversion",
-                   "org.apache.cordova.justafeature"
-               ];
-               var list = cfg.getFeatureIdList();
-               expect(list.length).toEqual(expectedList.length);
-               expectedList.forEach(function(feature){
-                   expect(list).toContain(feature);
-               });
-            });
-            it('should read feature given id', function(){
-                var feature = cfg.getFeature("org.apache.cordova.justafeature");
-                expect(feature).toBeDefined();
-                expect(feature.name).toEqual("A simple feature");
-                expect(feature.id).toEqual("org.apache.cordova.justafeature");
-                expect(feature.params).toBeDefined();
-                expect(feature.params.id).toBeDefined();
-                expect(feature.params.id).toEqual("org.apache.cordova.justafeature");
-            });
-            it('should not read feature given undefined id', function(){
-                var feature = cfg.getFeature("org.apache.cordova.undefinedfeature");
-                expect(feature).not.toBeDefined();
-            });
-            it('should read feature with url and set \'url\' param', function(){
-                var feature = cfg.getFeature("org.apache.cordova.featurewithurl");
-                expect(feature.url).toEqual("http://cordova.apache.org/featurewithurl");
-                expect(feature.params).toBeDefined();
-                expect(feature.params.url).toBeDefined();
-                expect(feature.params.url).toEqual("http://cordova.apache.org/featurewithurl");
-            });
-            it('should read feature with version and set \'version\' param', function(){
-                var feature = cfg.getFeature("org.apache.cordova.featurewithversion");
-                expect(feature.version).toEqual("1.1.1");
-                expect(feature.params).toBeDefined();
-                expect(feature.params.version).toBeDefined();
-                expect(feature.params.version).toEqual("1.1.1");
-            });
-            it('should read feature variables', function () {
-                var feature = cfg.getFeature("org.apache.cordova.featurewithvars");
-                expect(feature.variables).toBeDefined();
-                expect(feature.variables.var).toBeDefined();
-                expect(feature.variables.var).toEqual("varvalue");
-            });
-            it('should allow adding a new feature', function(){
-                cfg.addFeature('myfeature');
-                var features = cfg.doc.findall('feature');
-                var featureNames = features.map(function(feature){
-                    return feature.attrib.name;
-                });
-                expect(featureNames).toContain('myfeature');
-            });
-            it('should allow adding features with params', function(){
-                cfg.addFeature('afeature', JSON.parse('[{"name":"paraname", "value":"paravalue"}]'));
-                var features = cfg.doc.findall('feature');
-                var feature  = (function(){
-                    var i = features.length;
-                    var f;
-                    while (--i >= 0) {
-                        f = features[i];
-                        if ('afeature' === f.attrib.name) return f;
-                    }
-                    return undefined;
-                })();
-                expect(feature).toBeDefined();
-                var params = feature.findall('param');
-                expect(params[0].attrib.name).toEqual('paraname');
-                expect(params[0].attrib.value).toEqual('paravalue');
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-cordova/fixtures/plugins/malformed/plugin.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/malformed/plugin.xml b/cordova-lib/spec-cordova/fixtures/plugins/malformed/plugin.xml
deleted file mode 100644
index d7c1884..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/malformed/plugin.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-< <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
-           id="org.apache.cordova.fakeplugin1"
-      version="0.1.0-dev">
-    <name>malformed</name>
-    <description>Cordova malformed plugin for tests</description>
-    <license>Apache 2.0</license>
-    <keywords>cordova,cli,test</keywords>
-</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/ios_parser.spec.js b/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
index b17ce0d..7cceb98 100644
--- a/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
+++ b/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
@@ -20,7 +20,7 @@ var platforms = require('../../src/cordova/platforms'),
     util = require('../../src/cordova/util'),
     path = require('path'),
     shell = require('shelljs'),
-    plist = require('plist'),
+    plist = require('plist-with-patches'),
     xcode = require('xcode'),
     et = require('elementtree'),
     fs = require('fs'),
@@ -89,7 +89,7 @@ describe('ios project parser', function () {
             var update_name, xc_write;
             beforeEach(function() {
                 mv = spyOn(shell, 'mv');
-                plist_parse = spyOn(plist, 'parse').andReturn({
+                plist_parse = spyOn(plist, 'parseFileSync').andReturn({
                 });
                 plist_build = spyOn(plist, 'build').andReturn('');
                 update_name = jasmine.createSpy('update_name');

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js b/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
index 2d9c3f3..b4b804f 100644
--- a/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
+++ b/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
@@ -132,9 +132,9 @@ describe('windows8 project parser', function() {
             });
         });
         describe('update_www method', function() {
-            var update_project;
+            var update_jsproj;
             beforeEach(function() {
-                update_project = spyOn(parser, 'update_project');
+                update_jsproj = spyOn(parser, 'update_jsproj');
             });
             it('should rm project-level www and cp in platform agnostic www', function() {
                 parser.update_www(path.join('lib','dir'));
@@ -147,6 +147,7 @@ describe('windows8 project parser', function() {
             beforeEach(function() {
                 config = spyOn(parser, 'update_from_config');
                 www = spyOn(parser, 'update_www');
+                www = spyOn(parser, 'update_jsproj');
                 shellls = spyOn(shell, 'ls').andReturn([]);
                 svn = spyOn(util, 'deleteSvnFolders');
                 exists.andReturn(false);

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js b/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
index dd85d26..bf05411 100644
--- a/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
+++ b/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
@@ -147,9 +147,9 @@ describe('wp8 project parser', function() {
             });
         });
         describe('update_www method', function() {
-            var update_project;
+            var update_csproj;
             beforeEach(function() {
-                update_project = spyOn(p, 'update_project');
+                update_csproj = spyOn(p, 'update_csproj');
             });
             it('should rm project-level www and cp in platform agnostic www', function() {
                 p.update_www();
@@ -158,11 +158,12 @@ describe('wp8 project parser', function() {
             });
         });
         describe('update_project method', function() {
-            var config, www, overrides, svn;
+            var config, www, overrides, svn, csproj;
             beforeEach(function() {
                 config = spyOn(p, 'update_from_config');
                 www = spyOn(p, 'update_www');
                 svn = spyOn(util, 'deleteSvnFolders');
+                csproj = spyOn(p, 'update_csproj');
                 exists.andReturn(false);
             });
             it('should call update_from_config', function(done) {

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-cordova/test-config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/test-config.xml b/cordova-lib/spec-cordova/test-config.xml
index 27838b7..5e01e48 100644
--- a/cordova-lib/spec-cordova/test-config.xml
+++ b/cordova-lib/spec-cordova/test-config.xml
@@ -22,28 +22,5 @@
     <icon id="logo" src="logo.png" width="255" height="255" />
     <platform name="android">
         <icon src="logo-android.png" width="255" height="255" density="mdpi" />
-        <preference name="android-minSdkVersion" value="10" />
-    </platform>
-
-    <!-- Features -->
-    <feature name="A feature with preference">
-        <param name="id" value="org.apache.cordova.featurewithvars"/>
-        <variable name="var" value="varvalue"/>
-    </feature>
-    <feature name="A feature with url">
-        <param name="id" value="org.apache.cordova.featurewithurl" />
-        <param name="url" value="http://cordova.apache.org/featurewithurl" />
-    </feature>
-    <feature name="A feature with version">
-        <param name="id" value="org.apache.cordova.featurewithversion" />
-        <param name="version" value="1.1.1" />
-    </feature>
-    <feature name="A feature with url and version">
-        <param name="id" value="org.apache.cordova.featurewithurlandversion" />
-        <param name="version" value="1.1.1" />
-        <param name="url" value="http://cordova.apache.org/featurewithurlandversion" />
-    </feature>
-    <feature name="A simple feature">
-        <param name="id" value="org.apache.cordova.justafeature" />
-    </feature>
-</widget>
+    </platform>    
+</widget>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/install-browserify.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/install-browserify.spec.js b/cordova-lib/spec-plugman/install-browserify.spec.js
index 356b7a4..1731707 100644
--- a/cordova-lib/spec-plugman/install-browserify.spec.js
+++ b/cordova-lib/spec-plugman/install-browserify.spec.js
@@ -53,8 +53,7 @@ var install = require('../src/plugman/install'),
     },
     promise,
     results = {},
-    dummy_id = 'com.phonegap.plugins.dummyplugin',
-    superspawn = require('../src/cordova/superspawn');
+    dummy_id = 'com.phonegap.plugins.dummyplugin';
 
 
 // Pre-crete the temp dir, without it the test fails.
@@ -151,15 +150,14 @@ describe('start', function() {
 
 describe('install', function() {
     var chmod, exec, proc, add_to_queue, prepare, actions_push, c_a, mkdir, cp, rm, fetchSpy, emit;
-    var spawnSpy;
 
     beforeEach(function() {
         prepare = spyOn(plugman, 'prepare').andReturn( Q(true) );
         prepareBrowserify = spyOn(plugman, 'prepareBrowserify');
         exec = spyOn(child_process, 'exec').andCallFake(function(cmd, cb) {
+
             cb(false, '', '');
         });
-        spawnSpy = spyOn(superspawn, 'spawn').andReturn(Q('3.1.0'));
         spyOn(fs, 'mkdirSync').andReturn(true);
         spyOn(shell, 'mkdir').andReturn(true);
         spyOn(platforms, 'copyFile').andReturn(true);

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/install.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/install.spec.js b/cordova-lib/spec-plugman/install.spec.js
index 7b83d2a..3fe8428 100644
--- a/cordova-lib/spec-plugman/install.spec.js
+++ b/cordova-lib/spec-plugman/install.spec.js
@@ -52,8 +52,7 @@ var install = require('../src/plugman/install'),
     },
     promise,
     results = {},
-    dummy_id = 'com.phonegap.plugins.dummyplugin',
-    superspawn = require('../src/cordova/superspawn');
+    dummy_id = 'com.phonegap.plugins.dummyplugin';
 
 
 // Pre-crete the temp dir, without it the test fails.
@@ -148,7 +147,6 @@ describe('start', function() {
 
 describe('install', function() {
     var chmod, exec, proc, add_to_queue, prepare, actions_push, c_a, mkdir, cp, rm, fetchSpy, emit;
-    var spawnSpy;
 
     beforeEach(function() {
         prepare = spyOn(plugman, 'prepare').andReturn( Q(true) );
@@ -156,7 +154,6 @@ describe('install', function() {
         exec = spyOn(child_process, 'exec').andCallFake(function(cmd, cb) {
             cb(false, '', '');
         });
-        spawnSpy = spyOn(superspawn, 'spawn').andReturn(Q('3.1.0'));
         spyOn(fs, 'mkdirSync').andReturn(true);
         spyOn(shell, 'mkdir').andReturn(true);
         spyOn(platforms, 'copyFile').andReturn(true);

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/platforms/ios.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/platforms/ios.spec.js b/cordova-lib/spec-plugman/platforms/ios.spec.js
index d0acd9e..cc8dcfd 100644
--- a/cordova-lib/spec-plugman/platforms/ios.spec.js
+++ b/cordova-lib/spec-plugman/platforms/ios.spec.js
@@ -23,7 +23,7 @@ var ios = require('../../src/plugman/platforms/ios'),
     et = require('elementtree'),
     shell = require('shelljs'),
     os = require('osenv'),
-    plist = require('plist'),
+    plist = require('plist-with-patches'),
     bplist = require('bplist-parser'),
     temp = path.join(os.tmpdir(), 'plugman'),
     plugins_dir = path.join(temp, 'cordova', 'plugins'),

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/platforms/windows8.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/platforms/windows8.spec.js b/cordova-lib/spec-plugman/platforms/windows8.spec.js
index fd550e9..ee68bd8 100644
--- a/cordova-lib/spec-plugman/platforms/windows8.spec.js
+++ b/cordova-lib/spec-plugman/platforms/windows8.spec.js
@@ -108,7 +108,7 @@ describe('windows8 project handler', function() {
                 var source = copyArray(valid_source);
                 var s = spyOn(common, 'copyFile');
                 windows8['source-file'].install(source[0], dummyplugin, temp, dummy_id, proj_files);
-                expect(s).toHaveBeenCalledWith(dummyplugin, 'src/windows8/dummer.js', temp, path.join('plugins', 'com.phonegap.plugins.dummyplugin', 'dummer.js'));
+                expect(s).toHaveBeenCalledWith(dummyplugin, 'src/windows8/dummer.js', temp, path.join('www', 'plugins', 'com.phonegap.plugins.dummyplugin', 'dummer.js'));
             });
             it('should throw if source-file src cannot be found', function() {
                 var source = copyArray(invalid_source);
@@ -118,7 +118,7 @@ describe('windows8 project handler', function() {
             });
             it('should throw if source-file target already exists', function() {
                 var source = copyArray(valid_source);
-                var target = path.join(temp, 'plugins', dummy_id, 'dummer.js');
+                var target = path.join(temp, 'www', 'plugins', dummy_id, 'dummer.js');
                 shell.mkdir('-p', path.dirname(target));
                 fs.writeFileSync(target, 'some bs', 'utf-8');
                 expect(function() {
@@ -144,7 +144,7 @@ describe('windows8 project handler', function() {
                 .then(function() {
                     var source = copyArray(valid_source);
                     windows8['source-file'].uninstall(source[0], temp, dummy_id, proj_files);
-                    expect(s).toHaveBeenCalledWith(temp, path.join('plugins',  'com.phonegap.plugins.dummyplugin', 'dummer.js'));
+                    expect(s).toHaveBeenCalledWith(temp, path.join('www', 'plugins',  'com.phonegap.plugins.dummyplugin', 'dummer.js'));
                     done();
                 });
             });

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/projects/android_install/cordova/version
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android_install/cordova/version b/cordova-lib/spec-plugman/projects/android_install/cordova/version
old mode 100755
new mode 100644
index 3c331da..01f68fd
--- a/cordova-lib/spec-plugman/projects/android_install/cordova/version
+++ b/cordova-lib/spec-plugman/projects/android_install/cordova/version
@@ -1,23 +1 @@
-#!/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.
-*/
-
-console.log('9.0.0');
-
+echo 9.0.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/projects/android_one/cordova/version.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android_one/cordova/version.bat b/cordova-lib/spec-plugman/projects/android_one/cordova/version.bat
deleted file mode 100644
index c637d7c..0000000
--- a/cordova-lib/spec-plugman/projects/android_one/cordova/version.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@ECHO OFF
-echo 9.0.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/projects/android_uninstall/cordova/version
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/projects/android_uninstall/cordova/version b/cordova-lib/spec-plugman/projects/android_uninstall/cordova/version
old mode 100755
new mode 100644
index 3b8e2c5..01f68fd
--- a/cordova-lib/spec-plugman/projects/android_uninstall/cordova/version
+++ b/cordova-lib/spec-plugman/projects/android_uninstall/cordova/version
@@ -1,22 +1 @@
-#!/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.
-*/
-
-console.log('9.0.0');
+echo 9.0.0
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/spec-plugman/util/config-changes.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-plugman/util/config-changes.spec.js b/cordova-lib/spec-plugman/util/config-changes.spec.js
index d745c18..c7137ee 100644
--- a/cordova-lib/spec-plugman/util/config-changes.spec.js
+++ b/cordova-lib/spec-plugman/util/config-changes.spec.js
@@ -28,7 +28,7 @@ var configChanges = require('../../src/plugman/util/config-changes'),
     events  = require('../../src/events'),
     et      = require('elementtree'),
     path    = require('path'),
-    plist = require('plist'),
+    plist = require('plist-with-patches'),
     shell   = require('shelljs'),
     xcode = require('xcode'),
     temp    = path.join(os.tmpdir(), 'plugman'),

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/PluginInfo.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/PluginInfo.js b/cordova-lib/src/PluginInfo.js
index 94d6fb1..dcc1da5 100644
--- a/cordova-lib/src/PluginInfo.js
+++ b/cordova-lib/src/PluginInfo.js
@@ -200,6 +200,13 @@ function PluginInfo(dirname) {
         var libFiles = _getTagsInPlatform(self._et, 'lib-file', platform, cloneAttribs);
         return libFiles;
     }
+
+    // Tell whether there is a <platform> section for the given platform.
+    self.hasPlatformSection = hasPlatformSection;
+    function hasPlatformSection(platform) {
+        var platformTag = pelem.find('./platform[@name="' + platform + '"]');
+        return !!platformTag;
+    }
     ///// End of PluginInfo methods /////
 
 
@@ -270,15 +277,10 @@ function loadPluginsDir(dirname) {
     var plugins = [];
     subdirs.forEach(function (subdir) {
         var d = path.join(dirname, subdir);
-        if (!fs.existsSync(path.join(d, 'plugin.xml'))) {
+        if (!fs.existsSync(path.join(d, 'plugin.xml')))
             return; // continue
-        }
-        try {
-        	var p = new PluginInfo(d);
-        	plugins.push(p);
-        } catch (e) {
-        	// ignore errors while parsing so we can continue with searching
-        }
+        var p = new PluginInfo(d);
+        plugins.push(p);
     });
     return plugins;
 }

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/configparser/ConfigParser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/configparser/ConfigParser.js b/cordova-lib/src/configparser/ConfigParser.js
index da6376e..84de2a6 100644
--- a/cordova-lib/src/configparser/ConfigParser.js
+++ b/cordova-lib/src/configparser/ConfigParser.js
@@ -27,15 +27,6 @@ var et = require('elementtree'),
     CordovaError = require('../CordovaError'),
     fs = require('fs');
 
-/**
- * Array of 'feature' params that are set as properties
- * @type {string[]}
- */
-var FEATURE_SPECIAL_PARAMS = [
-    'id',
-    'url',
-    'version'
-];
 
 /** Wraps a config.xml file */
 function ConfigParser(path) {
@@ -117,12 +108,8 @@ ConfigParser.prototype = {
     author: function() {
         return getNodeTextSafe(this.doc.find('author'));
     },
-    getPreference: function(name, platform) {
+    getPreference: function(name) {
         var preferences = this.doc.findall('preference');
-        if (platform) { // include platform specific preferences
-            preferences = preferences.concat(
-                this.doc.findall('platform[@name=\'' + platform + '\']/preference'));
-        }
         var ret = null;
         preferences.forEach(function (preference) {
             // Take the last one that matches.
@@ -230,93 +217,6 @@ ConfigParser.prototype = {
     },
 
     /**
-     * Returns a list of features (IDs)
-     * @return {string[]} Array of feature IDs
-     */
-    getFeatureIdList: function () {
-        var features = this.doc.findall('feature'),
-            feature, idTag, id,
-            result = [];
-
-        // Check for valid features that have IDs set
-        for (var i = 0, l = features.length; i < l; ++i) {
-            feature = features[i];
-            idTag = feature.find('./param[@name="id"]');
-            if (null === idTag) {
-                // Invalid feature
-                continue;
-            }
-            id = idTag.attrib.value;
-            if (!!id) {
-                // Has id and id is non-empty
-                result.push(id);
-            }
-        }
-
-        return result;
-    },
-
-    /**
-     * Gets feature info
-     * @param {string} id Feature id
-     * @returns {Feature} Feature object
-     */
-    getFeature: function(id) {
-        if (!id) {
-            return undefined;
-        }
-        var feature = this.doc.find('./feature/param[@name="id"][@value="' + id + '"]/..');
-        if (null === feature) {
-            return undefined;
-        }
-
-        var result = {};
-        result.id = id;
-        result.name = feature.attrib.name;
-
-        // Iterate params and fill-in 'params' structure
-        // For special cases like 'id', 'url, 'version' - copy to the main space
-        result.params = processChildren (
-            'param',
-            function(name, value) {
-                if (FEATURE_SPECIAL_PARAMS.indexOf(name) >= 0) {
-                    result[name] = value;
-                }
-            }
-        );
-
-        // Iterate preferences
-        result.variables = processChildren('variable');
-
-        return result;
-
-        /**
-         * Processes a set of children
-         * having a pair of 'name' and 'value' attributes
-         * filling in 'output' object
-         * @param {string} xPath Search expression
-         * @param {function} [specialProcessing] Performs some additional actions on each valid element
-         * @return {object} A transformed object
-         */
-        function processChildren (xPath, specialProcessing) {
-            var result = {};
-            var needsProcessing = 'function' === typeof specialProcessing;
-            var nodes = feature.findall(xPath);
-            nodes.forEach(function(param){
-                var name = param.attrib.name;
-                var value = param.attrib.value;
-                if (name) {
-                    result[name] = value;
-                    if (needsProcessing) {
-                        specialProcessing(name, value);
-                    }
-                }
-            });
-            return result;
-        }
-    },
-
-    /**
      *This does not check for duplicate feature entries
      */
     addFeature: function (name, params){

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/configparser/ConfigParser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/configparser/ConfigParser.spec.js b/cordova-lib/src/configparser/ConfigParser.spec.js
new file mode 100644
index 0000000..a1ba102
--- /dev/null
+++ b/cordova-lib/src/configparser/ConfigParser.spec.js
@@ -0,0 +1,99 @@
+/**
+    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 path = require('path'),
+    fs = require('fs'),
+    ConfigParser = require('../src/cordova/ConfigParser'),
+    xml = path.join(__dirname, 'test-config.xml'),
+    xml_contents = fs.readFileSync(xml, 'utf-8');
+
+describe('config.xml parser', function () {
+    var readFile;
+    beforeEach(function() {
+        readFile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
+    });
+
+    it('should create an instance based on an xml file', function() {
+        var cfg;
+        expect(function () {
+            cfg = new ConfigParser(xml);
+        }).not.toThrow();
+        expect(cfg).toBeDefined();
+        expect(cfg.doc).toBeDefined();
+    });
+
+    describe('methods', function() {
+        var cfg;
+        beforeEach(function() {
+            cfg = new ConfigParser(xml);
+        });
+
+        describe('package name / id', function() {
+            it('should get the (default) packagename', function() {
+                expect(cfg.packageName()).toEqual('io.cordova.hellocordova');
+            });
+            it('should allow setting the packagename', function() {
+                cfg.setPackageName('this.is.bat.country');
+                expect(cfg.packageName()).toEqual('this.is.bat.country');
+            });
+        });
+
+        describe('version', function() {
+            it('should get the version', function() {
+                expect(cfg.version()).toEqual('0.0.1');
+            });
+            it('should allow setting the version', function() {
+                cfg.setVersion('2.0.1');
+                expect(cfg.version()).toEqual('2.0.1');
+            });
+        });
+
+        describe('app name', function() {
+            it('should get the (default) app name', function() {
+                expect(cfg.name()).toEqual('Hello Cordova');
+            });
+            it('should allow setting the app name', function() {
+                cfg.setName('this.is.bat.country');
+                expect(cfg.name()).toEqual('this.is.bat.country');
+            });
+        });
+        describe('preference', function() {
+            it('should get value of existing preference', function() {
+                expect(cfg.getPreference('fullscreen')).toEqual('true');
+            });
+            it('should get undefined as non existing preference', function() {
+                expect(cfg.getPreference('zimzooo!')).toEqual(undefined);
+            });
+        });
+        describe('feature',function(){
+            it('should allow adding a new feature', function(){
+                cfg.addFeature('myfeature');
+                var features = cfg.doc.findall('feature');
+                expect(features[0].attrib.name).toEqual('myfeature');
+            });
+            it('should allow adding features with params', function(){
+                cfg.addFeature('afeature', JSON.parse('[{"name":"paraname", "value":"paravalue"}]'));
+                var features = cfg.doc.findall('feature');
+                expect(features[0].attrib.name).toEqual('afeature');
+                var params = features[0].findall('param');
+                expect(params[0].attrib.name).toEqual('paraname');
+                expect(params[0].attrib.value).toEqual('paravalue');
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/create.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/create.js b/cordova-lib/src/cordova/create.js
index c8cb694..7aef292 100644
--- a/cordova-lib/src/cordova/create.js
+++ b/cordova-lib/src/cordova/create.js
@@ -105,15 +105,11 @@ function create(dir, id, name, cfg) {
         config_json.lib.www.id = config_json.lib.www.id || 'dummy_id';
         symlink  = !!config_json.lib.www.link;
 
-        // Make sure that the source www/ is not a direct ancestor of the
-        // target www/, or else we will recursively copy forever. To do this,
-        // we make sure that the shortest relative path from source-to-target
-        // must start by going up at least one directory or with a drive
-        // letter for Windows.
-        var rel_path = path.relative(config_json.lib.www.url, www_dir);
-        var goes_up = rel_path.split(path.sep)[0] == '..';
-
-        if (!(goes_up || rel_path[1] == ':')) {
+        // Make sure that the source www/ is not a direct ancestor of the target www/, or else we will recursively copy forever.
+        // To do this, we make sure that the shortest relative path from source-to-target must start by going up at least one directory.
+        var relative_path_from_source_to_target = path.relative(config_json.lib.www.url, www_dir);
+        var does_relative_path_go_up_at_least_one_dir = relative_path_from_source_to_target.split(path.sep)[0] == '..';
+        if (!does_relative_path_go_up_at_least_one_dir) {
             throw new CordovaError(
                 'Project dir "' +
                 dir +

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js b/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
index 517cd49..3b39605 100644
--- a/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
+++ b/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
@@ -54,158 +54,16 @@ module.exports.prototype = {
     },
 
     findAndroidLaunchModePreference: function(config) {
-        var launchMode = config.getPreference('AndroidLaunchMode');
-        if (!launchMode) {
-            // Return a default value
-            return 'singleTop';
-        }
-    
-        var expectedValues = ['standard', 'singleTop', 'singleTask', 'singleInstance'];
-        var valid = expectedValues.indexOf(launchMode) !== -1;
-        if (!valid) {
-            events.emit('warn', 'Unrecognized value for AndroidLaunchMode preference: ' + launchMode);
-            events.emit('warn', '  Expected values are: ' + expectedValues.join(', '));
-            // Note: warn, but leave the launch mode as developer wanted, in case the list of options changes in the future
-        }
-    
-        return launchMode;
-    },
-    
-    // remove the default resource name from all drawable folders
-    // return the array of the densities in this project
-deleteDefaultResource:function(name) {
-    var densities = [];
-    var res = path.join(this.path, 'res');
-    var dirs = fs.readdirSync(res);
-    
-    for (var i=0; i<dirs.length; i++) {
-        var filename = dirs[i];
-        if (filename.indexOf('drawable-') === 0) {
-            var density = filename.substr(9);
-            densities.push(density);
-            var template = path.join(res, filename, name);
-            try {
-                fs.unlinkSync(template);
-                events.emit('verbose', 'deleted: ' + template);
-            } catch(e) {
-                // ignored. template screen does probably not exist
-            }
-        }
-    }
-    return densities;
-},
-    
-handleSplashes:function(config) {
-    var resources = config.getSplashScreens('android');
-    var destfilepath;
-    // if there are "splash" elements in config.xml
-    if (resources.length > 0) {
-        var densities = this.deleteDefaultResource('screen.png');
-        events.emit('verbose', 'splash screens: ' + JSON.stringify(resources));
-        var res = path.join(this.path, 'res');
-        
-        if (resources.defaultResource) {
-            destfilepath = path.join(res, 'drawable', 'screen.png');
-            events.emit('verbose', 'copying splash icon from ' + resources.defaultResource.src + ' to ' + destfilepath);
-            shell.cp('-f', resources.defaultResource.src, destfilepath);
-        }
-        for (var i=0; i<densities.length; i++) {
-            var density = densities[i];
-            var resource = resources.getByDensity(density);
-            if (resource) {
-                // copy splash screens.
-                destfilepath = path.join(res, 'drawable-' + density, 'screen.png');
-                events.emit('verbose', 'copying splash icon from ' + resource.src + ' to ' + destfilepath);
-                shell.cp('-f', resource.src, destfilepath);
-            }
-        }
-    }
-},
-    
-handleIcons: function(config) {
-    var icons = config.getIcons('android');
-    // if there are icon elements in config.xml
-    if (icons.length === 0) {
-        events.emit('verbose', 'This app does not have launcher icons defined');
-        return;
-    }
-    
-    var densities = this.deleteDefaultResource('icon.png');
-    
-    var android_icons = {};
-    var default_icon;
-    // http://developer.android.com/design/style/iconography.html
-    var densityToSizeMap = {
-        'ldpi' : 36,
-        'mdpi' : 48,
-        'hdpi' : 72,
-        'xhdpi' : 96
-    };
-    // find the best matching icon for a given density or size
-    // @output android_icons
-    var parseIcon = function(icon, icon_size, size, density) {
-        // do I have a platform icon for that density already
-        var previous = android_icons[density];
-        if (previous && previous.platform) {
-            return;
-        }
-        // already have one but this one is a platform icon
-        if (previous && icon.platform && icon.density == density) {
-            android_icons[density] = icon;
-            return;
-        }
-        // if density is explicitly defined take this one
-        if (density === icon.density) {
-            android_icons[density] = icon;
-            return;
-        }
-        if (size === parseInt(icon_size)) {
-            android_icons[density] = icon;
-        }
-    };
-    // iterate over all icon elements to find the default icon and call parseIcon
-    for (var i=0; i<icons.length; i++) {
-        var icon = icons[i];
-        var size = icon.width;
-        if (!size) {
-            size = icon.height;
-        }
-        if (!size && !icon.density) {
-            if (default_icon) {
-                events.emit('verbose', 'more than one default icon: ' + JSON.stringify(icon));
-            } else {
-                default_icon = icon;
-            }
-        } else {
-            for (var k=0; k<densities.length; k++) {
-                    parseIcon(icon, size, densityToSizeMap[densities[k]], densities[k]);
-                }
-            }
-        }
-        var projectRoot = util.isCordova(this.path);
-        var srcfilepath;
-        var destfilepath;
-        // copy the default icon to the drawable folder
-        if (default_icon) {
-            srcfilepath = path.join(projectRoot, default_icon.src);
-            destfilepath = path.join(this.path, 'res', 'drawable', 'icon.png');
-            events.emit('verbose', 'Copying default icon from ' + srcfilepath + ' to ' + destfilepath);
-            shell.cp('-f', srcfilepath, destfilepath);
-        }
-        // copyIcon does the actual copying into the drawable folders
-        var copyIcon = function(density) {
-            if (android_icons[density]) {
-                srcfilepath = path.join(projectRoot, android_icons[density].src);
-                destfilepath = path.join(this.path, 'res', 'drawable-'+density, 'icon.png');
-                events.emit('verbose', 'Copying icon from ' + srcfilepath + ' to ' + destfilepath);
-                shell.cp('-f', srcfilepath, destfilepath);
-            }
-        }.bind(this);
-        for (var j=0; j<densities.length; j++) {
-            copyIcon(densities[j]);
+        var ret = config.getPreference('AndroidLaunchMode');
+        var valid = ['standard', 'singleTop', 'singleTask', 'singleInstance'].indexOf(ret) !== -1;
+        if (ret && !valid) {
+            events.emit('warn', 'Unknown value for launchMode preference: ' + ret);
+            ret = null;
         }
+
+        return ret;
     },
-    
+
     update_from_config:function(config) {
         // TODO: share code for this func with Android. Or fix it and remove
         // the below JSHint hacks line.
@@ -220,9 +78,98 @@ handleIcons: function(config) {
         fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
         events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
 
-        this.handleSplashes(config);
-        this.handleIcons(config);
-        
+        var icons = config.getIcons('amazon-fireos');
+        // if there are icon elements in config.xml
+        if (icons) {
+          var android_icons = {};
+          var projectRoot = util.isCordova(this.path);
+          var default_icon;
+          var max_size;
+          var max_density;
+          // http://developer.android.com/design/style/iconography.html
+          var densities = {
+            'ldpi' : 36,
+            'mdpi' : 48,
+            'hdpi' : 72,
+            'xhdpi' : 96
+          };
+          for (var i=0; i<icons.length; i++) {
+            var icon = icons[i];
+            var destfilepath;
+            var size = icon.width;
+            if (!size) {
+              size = icon.height;
+            }
+            if (!size && !icon.density) {
+              if (default_icon) {
+                  events.emit('verbose', 'more than one default icon: ' + JSON.stringify(icon));
+              } else {
+                  default_icon = icon;
+              }
+            } else {
+              var parseIcon = function(icon, icon_size, size, density) {
+                // if density is explicitly defined, no need to calculate it from width/height
+                if (icon.density) {
+                    android_icons[icon.density] = icon;
+                    return;
+                }
+
+                var i = parseInt(icon_size);
+                if (size == parseInt(icon_size)) {
+                  var previous = android_icons[density];
+                  if (previous) {
+                    // already have that density. platform rules
+                    if (!previous.platform) {
+                      android_icons[density] = icon;
+                    } // else already have a platform icon of that density
+                  } else {
+                    android_icons[density] = icon;
+                  }
+                  android_icons[density] = icon;
+                  if (!max_size) {
+                    max_size = size;
+                    max_density = density;
+                  } else {
+                    if (max_size < size) {
+                      max_size = size;
+                      max_density = density;
+                    }
+                  }
+                }
+              };
+              for (var density in densities) {
+                parseIcon(icon, size, densities[density], density);
+              }
+            }
+          }
+
+          var copyIcon = function(density) {
+            var srcfilepath;
+            var destfilepath = path.join(this.path, 'res', 'drawable-'+density, 'icon.png');
+            if (android_icons[density]) {
+              srcfilepath = path.join(projectRoot, android_icons[density].src);
+            } else {
+              if (default_icon) {
+                srcfilepath = path.join(projectRoot, default_icon.src);
+              } else {
+                if (max_density) {
+                  srcfilepath = path.join(projectRoot, android_icons[max_density].src);
+                } else {
+                  events.emit('verbose', 'no icon found matching Android typical densities');
+                }
+              }
+            }
+            if (srcfilepath) {
+                events.emit('verbose', 'Copying icon from ' + srcfilepath + ' to ' + destfilepath);
+                shell.cp('-f', srcfilepath, destfilepath);
+            }
+          }.bind(this);
+          for (var density in densities) {
+            copyIcon(density);
+          }
+
+        }
+
         var manifest = xml.parseElementtreeSync(this.manifest);
         // Update the version by changing the AndroidManifest android:versionName
         var version = config.version();

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/android_parser.js b/cordova-lib/src/cordova/metadata/android_parser.js
index 9f338dd..12a6d1f 100644
--- a/cordova-lib/src/cordova/metadata/android_parser.js
+++ b/cordova-lib/src/cordova/metadata/android_parser.js
@@ -23,7 +23,6 @@
 
 var fs            = require('fs'),
     path          = require('path'),
-    et            = require('elementtree'),
     xml           = require('../../util/xml-helpers'),
     util          = require('../util'),
     events        = require('../../events'),
@@ -262,20 +261,6 @@ module.exports.prototype = {
             delete act.attrib["android:launchMode"]; // use Android default value (standard)
         }
 
-        // Set min/max/target SDK version 
-        //<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="19" ... />
-        var usesSdk = manifest.getroot().find('./uses-sdk');
-        ['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'].forEach(function(sdkPrefName) {
-            var sdkPrefValue = config.getPreference('android-' + sdkPrefName, 'android');
-            if (!sdkPrefValue) return;
-            
-            if (!usesSdk) { // if there is no required uses-sdk element, we should create it first
-                usesSdk = new et.Element('uses-sdk');
-                manifest.getroot().append(usesSdk);
-            }
-            usesSdk.attrib['android:' + sdkPrefName] = sdkPrefValue;
-        });
-
         // Write out AndroidManifest.xml
         fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
 

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/metadata/firefoxos_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/firefoxos_parser.js b/cordova-lib/src/cordova/metadata/firefoxos_parser.js
index b4e435e..0ec5b6d 100644
--- a/cordova-lib/src/cordova/metadata/firefoxos_parser.js
+++ b/cordova-lib/src/cordova/metadata/firefoxos_parser.js
@@ -49,8 +49,8 @@ module.exports.prototype = {
 
         // overwrite properties existing in config.xml
         var contentNode = config.doc.find('content');
-        var contentSrc = contentNode && contentNode.attrib['src'] || 'index.html';
-        manifest.launch_path = '/' + contentSrc;
+        var contentSrc = contentNode.attrib['src'];
+        manifest.launch_path = path.join('/', contentSrc) || '/index.html';
 
         manifest.installs_allowed_from = manifest.installs_allowed_from || ['*'];
         manifest.version = config.version();
@@ -61,7 +61,7 @@ module.exports.prototype = {
         };
 
         var authorNode = config.doc.find('author');
-        var authorUrl = authorNode && authorNode.attrib['href'];
+        var authorUrl = authorNode.attrib['href'];
 
         if (authorUrl) {
             manifest.developer.url = authorUrl;

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/metadata/ios_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/ios_parser.js b/cordova-lib/src/cordova/metadata/ios_parser.js
index b853fab..fa136dc 100644
--- a/cordova-lib/src/cordova/metadata/ios_parser.js
+++ b/cordova-lib/src/cordova/metadata/ios_parser.js
@@ -29,7 +29,7 @@ var fs            = require('fs'),
     util          = require('../util'),
     events        = require('../../events'),
     shell         = require('shelljs'),
-    plist         = require('plist'),
+    plist         = require('plist-with-patches'),
     Q             = require('q'),
     ConfigParser  = require('../../configparser/ConfigParser'),
     CordovaError  = require('../../CordovaError');
@@ -65,7 +65,7 @@ module.exports.prototype = {
 
         // Update package id (bundle id)
         var plistFile = path.join(this.cordovaproj, this.originalName + '-Info.plist');
-        var infoPlist = plist.parse(fs.readFileSync(plistFile, 'utf8'));
+        var infoPlist = plist.parseFileSync(plistFile);
         infoPlist['CFBundleIdentifier'] = pkg;
 
         // Update version (bundle version)
@@ -134,17 +134,11 @@ module.exports.prototype = {
                 shell.cp('-f', src, dest);
             }
         });
-        
-        var me = this;
-        return this.update_build_settings(config).then(function() {
-            if (name == me.originalName) {
-                events.emit('verbose', 'iOS Product Name has not changed (still "' + me.originalName + '")');
-                return Q();
-            }
 
+        if (name != this.originalName) {
             // Update product name inside pbxproj file
-            var proj = new xcode.project(me.pbxproj);
-            var parser = me;
+            var proj = new xcode.project(this.pbxproj);
+            var parser = this;
             var d = Q.defer();
             proj.parse(function(err,hash) {
                 if (err) {
@@ -169,7 +163,10 @@ module.exports.prototype = {
                 }
             });
             return d.promise;
-        });
+        } else {
+            events.emit('verbose', 'iOS Product Name has not changed (still "' + this.originalName + '")');
+            return Q();
+        }
     },
 
     // Returns the platform-specific www directory.
@@ -220,37 +217,6 @@ module.exports.prototype = {
             self.update_overrides();
             util.deleteSvnFolders(self.www_dir());
         });
-    },
-
-    update_build_settings:function(config) {
-        var targetDevice = parseTargetDevicePreference(config.getPreference('target-device', 'ios'));
-        var deploymentTarget = config.getPreference('deployment-target', 'ios');
-
-        // no build settings provided, we don't need to parse and update .pbxproj file
-        if (!targetDevice && !deploymentTarget) {
-            return Q();
-        }
-
-        var me = this;
-        var d = Q.defer();
-        var proj = new xcode.project(this.pbxproj);
-        proj.parse(function(err,hash) {
-            if (err) {
-                d.reject(new Error('An error occured during parsing of project.pbxproj. Start weeping. Output: ' + err));
-                return;
-            }
-            if (targetDevice) {
-                events.emit('verbose', 'Set TARGETED_DEVICE_FAMILY to ' + targetDevice + '.');
-                proj.updateBuildProperty('TARGETED_DEVICE_FAMILY', targetDevice);
-            }
-            if (deploymentTarget) {
-                events.emit('verbose', 'Set IPHONEOS_DEPLOYMENT_TARGET to "' + deploymentTarget + '".');
-                proj.updateBuildProperty('IPHONEOS_DEPLOYMENT_TARGET', deploymentTarget);
-            }
-            fs.writeFileSync(me.pbxproj, proj.writeSync(), 'utf-8');
-            d.resolve();
-        });
-        return d.promise;
     }
 };
 
@@ -260,14 +226,3 @@ module.exports.prototype = {
 function default_CFBundleVersion(version) {
     return version.split('-')[0];
 }
-
-// Converts cordova specific representation of target device to XCode value
-function parseTargetDevicePreference(value) {
-    if (!value) return null;
-    var map = { 'universal': '"1,2"', 'handset': '"1"', 'tablet': '"2"'};
-    if (map[value.toLowerCase()]) {
-        return map[value.toLowerCase()];
-    }
-    events.emit('warn', 'Unknown target-device preference value: "' + value + '".');
-    return null;
-}

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/metadata/ubuntu_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/ubuntu_parser.js b/cordova-lib/src/cordova/metadata/ubuntu_parser.js
index a199662..634a575 100644
--- a/cordova-lib/src/cordova/metadata/ubuntu_parser.js
+++ b/cordova-lib/src/cordova/metadata/ubuntu_parser.js
@@ -87,18 +87,14 @@ module.exports.prototype = {
                          architecture: arch,
                          description: sanitize(this.config.description()) };
 
-        var name = sanitize(this.config.name()); //FIXME: escaping
-        var content = '[Desktop Entry]\nName=' + name + '\nExec=./cordova-ubuntu www/\nTerminal=false\nType=Application\nX-Ubuntu-Touch=true';
-
-        if (this.config.doc.find('icon') && this.config.doc.find('icon').attrib.src) {
-            var iconPath = path.join(this.path, 'www', this.config.doc.find('icon').attrib.src);
-            if (fs.existsSync(iconPath))
-                content += '\nIcon=www/' + this.config.doc.find('icon').attrib.src;
-            else
-                return Q.reject(new Error('icon does not exist: ' + iconPath));
-        } else {
-            content += '\nIcon=qmlscene';
-            console.warn('missing icon element in config.xml');
+        var name = this.config.name().replace(/\n/g, ' '); //FIXME: escaping
+        var content = '[Desktop Entry]\nName=' + name + '\nExec=./cordova-ubuntu www/\nIcon=qmlscene\nTerminal=false\nType=Application\nX-Ubuntu-Touch=true';
+
+        name = sanitize(this.config.name()); //FIXME: escaping
+        content = '[Desktop Entry]\nName=' + name + '\nExec=./cordova-ubuntu www/\nTerminal=false\nType=Application\nX-Ubuntu-Touch=true';
+
+        if (this.config.doc.find('icon') && this.config.doc.find('icon').attrib.src && fs.existsSync(path.join(this.path, 'www', this.config.doc.find('icon').attrib.src))) {
+            content += '\nIcon=www/' + this.config.doc.find('icon').attrib.src;
         }
         fs.writeFileSync(path.join(this.path, 'manifest.json'), JSON.stringify(manifest));
         fs.writeFileSync(path.join(this.path, 'cordova.desktop'), content);

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/metadata/windows_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/windows_parser.js b/cordova-lib/src/cordova/metadata/windows_parser.js
index aefb94e..eaeacbb 100644
--- a/cordova-lib/src/cordova/metadata/windows_parser.js
+++ b/cordova-lib/src/cordova/metadata/windows_parser.js
@@ -30,7 +30,8 @@ var fs            = require('fs'),
     ConfigParser  = require('../../configparser/ConfigParser'),
     CordovaError  = require('../../CordovaError'),
     xml           = require('../../util/xml-helpers'),
-    hooker        = require('../hooker');
+    hooker        = require('../hooker'),
+    jsproj        = require('../../util/windows/jsproj');
 
 module.exports = function windows_parser(project) {
     try {
@@ -228,6 +229,42 @@ module.exports.prototype = {
         shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
     },
 
+    // Returns an array of all the files in the given directory with relative paths
+    // - name     : the name of the top level directory (i.e all files will start with this in their path)
+    // - dir     : the directory whos contents will be listed under 'name' directory
+    folder_contents:function(name, dir) {
+        var results = [];
+        var folder_dir = fs.readdirSync(dir);
+        for(var item in folder_dir) {
+            var stat = fs.statSync(path.join(dir, folder_dir[item]));
+            // Add all subfolder item paths if it's not a .svn dir.
+            if( stat.isDirectory() && (folder_dir[item] !== '.svn') ) {
+                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
+                for(var sub_item in sub_dir) {
+                    results.push(sub_dir[sub_item]);
+                }
+            } else if(stat.isFile()) {
+                results.push(path.join(name, folder_dir[item]));
+            }
+            // else { it is a FIFO, or a Socket, Symbolic Link or something ... }
+        }
+        return results;
+    },
+
+    // updates the jsproj file to explicitly list all www content.
+    update_jsproj:function() {
+        var projFile = new jsproj(this.projFilePath);
+        // remove any previous references to the www files
+        projFile.removeSourceFile(/^(\$\(MSBuildThisFileDirectory\))?www\\/i);
+
+        // now add all www references back in from the root www folder
+        var www_files = this.folder_contents('www', this.www_dir());
+        projFile.addSourceFile(www_files);
+
+        // save file
+        projFile.write();
+    },
+
     // calls the nessesary functions to update the windows8 project
     update_project:function(cfg) {
         // console.log("Updating windows8 project...");
@@ -245,6 +282,7 @@ module.exports.prototype = {
         return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['windows8'] })
         .then(function() {
             // overrides (merges) are handled in update_www()
+            that.update_jsproj();
             that.add_bom();
             util.deleteSvnFolders(that.www_dir());
         });

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/metadata/wp8_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/wp8_parser.js b/cordova-lib/src/cordova/metadata/wp8_parser.js
index 4d5b332..0d458ee 100644
--- a/cordova-lib/src/cordova/metadata/wp8_parser.js
+++ b/cordova-lib/src/cordova/metadata/wp8_parser.js
@@ -30,7 +30,8 @@ var fs            = require('fs'),
     ConfigParser  = require('../../configparser/ConfigParser'),
     CordovaError  = require('../../CordovaError'),
     xml           = require('../../util/xml-helpers'),
-    hooker        = require('../hooker');
+    hooker        = require('../hooker'),
+    csproj = require('../../util/windows/csproj');
 
 module.exports = function wp8_parser(project) {
     try {
@@ -196,6 +197,43 @@ module.exports.prototype = {
         shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
     },
 
+    // updates the csproj file to explicitly list all www content.
+    update_csproj:function() {
+        var projFile = new csproj(this.csproj_path);
+
+        // remove any previous references to the www files
+        projFile.removeSourceFile(new RegExp('www\\\\*', 'i'));
+
+        // now add all www references back in from the root www folder
+        var www_files = this.folder_contents('www', this.www_dir());
+        projFile.addSourceFile(www_files);
+        // save file
+        projFile.write();
+    },
+    // Returns an array of all the files in the given directory with relative paths
+    // - name     : the name of the top level directory (i.e all files will start with this in their path)
+    // - dir     : the directory whos contents will be listed under 'name' directory
+    folder_contents:function(name, dir) {
+        var results = [];
+        var folder_dir = fs.readdirSync(dir);
+        for(var item in folder_dir) {
+            var stat = fs.statSync(path.join(dir, folder_dir[item]));
+
+            if(stat.isDirectory()) {
+                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
+                //Add all subfolder item paths
+                for(var sub_item in sub_dir) {
+                    results.push(sub_dir[sub_item]);
+                }
+            }
+            else if(stat.isFile()) {
+                results.push(path.join(name, folder_dir[item]));
+            }
+            // else { it is a FIFO, or a Socket or something ... }
+        }
+        return results;
+    },
+
     // calls the nessesary functions to update the wp8 project
     // Returns a promise.
     update_project:function(cfg) {
@@ -212,6 +250,7 @@ module.exports.prototype = {
         var hooks = new hooker(projectRoot);
         return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['wp8']  })
         .then(function() {
+            that.update_csproj();
             util.deleteSvnFolders(that.www_dir());
         });
     }

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/platform.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/platform.js b/cordova-lib/src/cordova/platform.js
index 487803e..dca8ed4 100644
--- a/cordova-lib/src/cordova/platform.js
+++ b/cordova-lib/src/cordova/platform.js
@@ -46,6 +46,17 @@ for (var p in platforms) {
     module.exports[p] = platforms[p];
 }
 
+function getVersionFromScript(script, defaultValue) {
+    var versionPromise = Q(defaultValue);
+    if (fs.existsSync(script)) {
+        versionPromise = superspawn.spawn(script);
+    } else {
+        /* if you are here, it's probably because you're in Jasmine: fix your existsSync stub */
+        versionPromise = Q(defaultValue);
+    }
+    return versionPromise;
+}
+
 function add(hooks, projectRoot, targets, opts) {
     var msg;
     if ( !targets || !targets.length ) {
@@ -100,9 +111,6 @@ function add(hooks, projectRoot, targets, opts) {
                 // Package names for Cordova platforms look like "cordova-ios".
                 var nameParts = pkg.name.split('-');
                 var name = nameParts[1];
-                if (name == 'amazon') {
-                    name = 'amazon-fireos';
-                }
                 if( !platforms[name] ) {
                     throw new CordovaError(msg);
                 }
@@ -211,7 +219,7 @@ function check(hooks, projectRoot) {
                 d_cur = Q.defer();
             add(h, scratch, [p], {spawnoutput: {stdio: 'ignore'}})
             .then(function() {
-                superspawn.maybeSpawn(path.join(scratch, 'platforms', p, 'cordova', 'version'))
+                getVersionFromScript(path.join(scratch, 'platforms', p, 'cordova', 'version'), null)
                 .then(function(avail) {
                     if (!avail) {
                         /* Platform version script was silent, we can't work with this */
@@ -229,7 +237,7 @@ function check(hooks, projectRoot) {
                 d_avail.resolve('install-failed');
             });
 
-            superspawn.maybeSpawn(path.join(projectRoot, 'platforms', p, 'cordova', 'version'))
+            getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
             .then(function(v) {
                 d_cur.resolve(v || '');
             }).catch(function () {
@@ -292,7 +300,7 @@ function list(hooks, projectRoot) {
     .then(function() {
         // Acquire the version number of each platform we have installed, and output that too.
         return Q.all(platforms_on_fs.map(function(p) {
-            return superspawn.maybeSpawn(path.join(projectRoot, 'platforms', p, 'cordova', 'version'))
+            return getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
             .then(function(v) {
                 if (!v) return p;
                 return p + ' ' + v;
@@ -339,16 +347,12 @@ function platform(command, targets, opts) {
             var pPath = path.resolve(t);
             if (fs.existsSync(pPath)) return;
             // Neither path, nor platform name - throw.
-            var msg;
-            if (/[~:/\\.]/.test(t)) {
-                msg = 'Platform path "' + t + '" not found.';
-            } else {
-                msg = 'Platform "' + t +
+            var msg = 'Platform "' + t +
                 '" not recognized as a core cordova platform. See `' +
                 cordova_util.binname + ' platform list`.'
                 ;
-            }
             throw new CordovaError(msg);
+
         });
     } else if (command == 'add' || command == 'rm') {
         msg = 'You need to qualify `add` or `remove` with one or more platforms!';
@@ -416,6 +420,7 @@ function call_into_create(target, projectRoot, cfg, libDir, template_dir, opts)
         }
     } else if (target == 'ios') {
         platformVersion = fs.readFileSync(path.join(libDir, 'CordovaLib', 'VERSION'), 'UTF-8').trim();
+        args.push('--arc');
         if (semver.gt(platformVersion, '3.3.0')) {
             args.push('--cli');
         }
@@ -446,22 +451,7 @@ function call_into_create(target, projectRoot, cfg, libDir, template_dir, opts)
         return plugins.reduce(function(soFar, plugin) {
             return soFar.then(function() {
                 events.emit('verbose', 'Installing plugin "' + plugin + '" following successful platform add of ' + target);
-                plugin = path.basename(plugin);
-                var options = (function(){
-                    // Get plugin preferences from config features if have any
-                    // Pass them as cli_variables to plugman
-                    var feature = cfg.getFeature(plugin);
-                    var variables = feature && feature.variables;
-                    if (!!variables) {
-                        events.emit('verbose', 'Found variables for "' + plugin + '". Processing as cli_variables.');
-                        return {
-                            cli_variables: variables
-                        };
-                    }
-                    return null;
-                })();
-
-                return plugman.raw.install(target, output, plugin, plugins_dir, options);
+                return plugman.raw.install(target, output, path.basename(plugin), plugins_dir);
             });
         }, Q());
     });

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/platforms.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/platforms.js b/cordova-lib/src/cordova/platforms.js
index e52b0a8..2adbf42 100644
--- a/cordova-lib/src/cordova/platforms.js
+++ b/cordova-lib/src/cordova/platforms.js
@@ -26,60 +26,60 @@ module.exports = {
         hostos : ['darwin'],
         parser : './metadata/ios_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ios.git',
-        version: '3.6.1'
+        version: '3.5.0'
     },
     'android' : {
         parser : './metadata/android_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git',
-        version: '3.6.1'
+        version: '3.5.1'
     },
     'ubuntu' : {
         hostos : ['linux'],
         parser : './metadata/ubuntu_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ubuntu.git',
-        version: '3.6.1'
+        version: '3.5.0'
     },
     'amazon-fireos' : {
         parser : './metadata/amazon_fireos_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-amazon-fireos.git',
-        version: '3.6.1'
+        version: '3.5.0'
     },
     'wp8' : {
         hostos : ['win32'],
         parser : './metadata/wp8_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',
-        version: '3.6.1',
+        version: '3.5.0',
         altplatform: 'wp',
         subdirectory: 'wp8'
     },
     'blackberry10' : {
         parser : './metadata/blackberry10_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-blackberry.git',
-        version: '3.6.1'
+        version: '3.5.0'
     },
     'www':{
         hostos : [],
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-app-hello-world.git',
         source : 'git',
-        version: '3.6.1'
+        version: '3.5.0'
     },
     'firefoxos':{
         parser: './metadata/firefoxos_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-firefoxos.git',
-        version: '3.6.1'
+        version: '3.5.0'
     },
     'windows8':{
         hostos : ['win32'],
         parser: './metadata/windows_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-windows.git',
-        version: '3.6.1',
+        version: 'master',
         subdirectory: 'windows'
     },
     'windows':{
         hostos : ['win32'],
         parser: './metadata/windows_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-windows.git',
-        version: '3.6.1',
+        version: 'master',
         subdirectory: 'windows'
     },
     'browser':{

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/a0177955/cordova-lib/src/cordova/prepare.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/prepare.js b/cordova-lib/src/cordova/prepare.js
index 09be122..c69a4d7 100644
--- a/cordova-lib/src/cordova/prepare.js
+++ b/cordova-lib/src/cordova/prepare.js
@@ -126,7 +126,7 @@ function prepare(options) {
     });
 }
 
-var BLACKLIST = ['platform', 'feature'];
+var BLACKLIST = ['platform'];
 var SINGLETONS = ['content', 'author'];
 function mergeXml(src, dest, platform, clobber) {
     // Do nothing for blacklisted tags.