You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ja...@apache.org on 2018/02/07 09:22:22 UTC

[cordova-windows] branch master updated: CB-11968: Add support for config-file in config.xml (#235)

This is an automated email from the ASF dual-hosted git repository.

janpio pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-windows.git


The following commit(s) were added to refs/heads/master by this push:
     new 8322103  CB-11968: Add support for config-file in config.xml (#235)
8322103 is described below

commit 83221035342bceac986085822b0c29aa2db030a0
Author: Nikita Matrosov <v-...@microsoft.com>
AuthorDate: Wed Feb 7 12:22:19 2018 +0300

    CB-11968: Add support for config-file in config.xml (#235)
    
    * CB-11968: Add support for config-file in config.xml
    
    * CB-11968 Add unit test for config-file
    
    * Update cordova-common to 2.2.1
---
 node_modules/big-integer/BigInteger.d.ts           | 2369 ++++++++++++++++++++
 node_modules/big-integer/BigInteger.js             |  121 +-
 node_modules/big-integer/BigInteger.min.js         |    2 +-
 node_modules/big-integer/README.md                 |   11 +-
 node_modules/big-integer/bower.json                |    1 -
 node_modules/big-integer/package.json              |   78 +-
 node_modules/big-integer/tsconfig.json             |   25 +
 node_modules/cordova-common/.eslintignore          |    1 +
 node_modules/cordova-common/.eslintrc.yml          |   11 +
 node_modules/cordova-common/.jshintignore          |    1 -
 node_modules/cordova-common/.npmignore             |    2 -
 node_modules/cordova-common/.ratignore             |    1 +
 node_modules/cordova-common/.travis.yml            |   16 +
 node_modules/cordova-common/README.md              |    4 +
 node_modules/cordova-common/RELEASENOTES.md        |   36 +
 node_modules/cordova-common/appveyor.yml           |   19 +
 node_modules/cordova-common/package.json           |  115 +-
 node_modules/cordova-common/src/.jshintrc          |   10 -
 node_modules/cordova-common/src/ActionStack.js     |   30 +-
 .../src/ConfigChanges/ConfigChanges.js             |  145 +-
 .../cordova-common/src/ConfigChanges/ConfigFile.js |  125 +-
 .../src/ConfigChanges/ConfigKeeper.js              |    9 +-
 .../cordova-common/src/ConfigChanges/munge-util.js |   45 +-
 .../src/ConfigParser/ConfigParser.js               |  265 ++-
 node_modules/cordova-common/src/CordovaCheck.js    |   14 +-
 .../src/CordovaError/CordovaError.js               |   25 +-
 .../CordovaExternalToolErrorContext.js             |    6 +-
 node_modules/cordova-common/src/CordovaLogger.js   |   18 +-
 node_modules/cordova-common/src/FileUpdater.js     |  141 +-
 node_modules/cordova-common/src/PlatformJson.js    |   71 +-
 .../cordova-common/src/PluginInfo/PluginInfo.js    |  200 +-
 .../src/PluginInfo/PluginInfoProvider.js           |   14 +-
 node_modules/cordova-common/src/PluginManager.js   |   93 +-
 node_modules/cordova-common/src/events.js          |    4 +-
 node_modules/cordova-common/src/superspawn.js      |   31 +-
 .../cordova-common/src/util/addProperty.js         |    4 +-
 .../cordova-common/src/util/plist-helpers.js       |   51 +-
 .../cordova-common/src/util/xml-helpers.js         |  137 +-
 package.json                                       |    2 +-
 spec/unit/ConfigChanges.spec.js                    |    9 +-
 spec/unit/WindowsConfigParser.spec.js              |   15 +
 template/cordova/Api.js                            |    3 +
 template/cordova/lib/AppxManifest.js               |   93 +
 template/cordova/lib/ConfigParser.js               |    6 +
 template/cordova/lib/PluginInfo.js                 |   99 +-
 45 files changed, 3498 insertions(+), 980 deletions(-)

diff --git a/node_modules/big-integer/BigInteger.d.ts b/node_modules/big-integer/BigInteger.d.ts
new file mode 100644
index 0000000..d70e401
--- /dev/null
+++ b/node_modules/big-integer/BigInteger.d.ts
@@ -0,0 +1,2369 @@
+/**
+ * Type definitions for BigInteger.js
+ * Definitions by: Tommy Frazier <https://github.com/toefraz>
+ */
+export = bigInt;
+export as namespace bigInt;
+
+declare var bigInt: bigInt.BigIntegerStatic;
+
+declare namespace bigInt {
+    type BigNumber = number | string | BigInteger;
+
+    interface BigIntegerStatic {
+        /**
+         * Equivalent to bigInt(0).
+         */
+        (): BigInteger;
+
+        /**
+         * Parse a Javascript number into a bigInt.
+         */
+        (number: number): BigInteger;
+
+        /**
+         * Parse a string into a bigInt.
+         */
+        (string: string, base?: BigNumber): BigInteger;
+
+        /**
+         * no-op.
+         */
+        (bigInt: BigInteger): BigInteger;
+
+        /**
+         * Constructs a bigInt from an array of digits in specified base.
+         * The optional isNegative flag will make the number negative.
+         */
+        fromArray: (digits: BigNumber[], base?: BigNumber, isNegative?: boolean) => BigInteger;
+
+        /**
+         * Finds the greatest common denominator of a and b.
+         */
+        gcd: (a: BigNumber, b: BigNumber) => BigInteger;
+
+
+        /**
+         * Returns true if x is a BigInteger, false otherwise.
+         */
+        isInstance: (x: any) => boolean;
+
+        /**
+         * Finds the least common multiple of a and b.
+         */
+        lcm: (a: BigNumber, b: BigNumber) => BigInteger;
+
+        /**
+         * Returns the largest of a and b.
+         */
+        max: (a: BigNumber, b: BigNumber) => BigInteger;
+
+        /**
+         * Returns the smallest of a and b.
+         */
+        min: (a: BigNumber, b: BigNumber) => BigInteger;
+
+        /**
+         * Equivalent to bigInt(-1).
+         */
+        minusOne:  BigInteger;
+
+        /**
+         * Equivalent to bigInt(1).
+         */
+        one:  BigInteger;
+
+        /**
+         * Returns a random number between min and max.
+         */
+        randBetween: (min: BigNumber, max: BigNumber) => BigInteger;
+
+        /**
+         * Equivalent to bigInt(0).
+         */
+        zero: BigInteger;
+    }
+
+    interface BigInteger {
+        /**
+         * Returns the absolute value of a bigInt.
+         */
+        abs(): BigInteger;
+
+        /**
+         * Performs addition.
+         */
+        add(number: BigNumber): BigInteger;
+
+        /**
+         * Performs the bitwise AND operation.
+         */
+        and(number: BigNumber): BigInteger;
+
+        /**
+         * Performs a comparison between two numbers. If the numbers are equal, it returns 0.
+         * If the first number is greater, it returns 1. If the first number is lesser, it returns -1.
+         */
+        compare(number: BigNumber): number;
+
+        /**
+         * Performs a comparison between the absolute value of two numbers.
+         */
+        compareAbs(number: BigNumber): number;
+
+        /**
+         * Alias for the compare method.
+         */
+        compareTo(number: BigNumber): number;
+
+        /**
+         * Performs integer division, disregarding the remainder.
+         */
+        divide(number: BigNumber): BigInteger;
+
+        /**
+         * Performs division and returns an object with two properties: quotient and remainder.
+         * The sign of the remainder will match the sign of the dividend.
+         */
+        divmod(number: BigNumber): {quotient: BigInteger, remainder: BigInteger};
+
+        /**
+         * Alias for the equals method.
+         */
+        eq(number: BigNumber): boolean;
+
+        /**
+         * Checks if two numbers are equal.
+         */
+        equals(number: BigNumber): boolean;
+
+        /**
+         * Alias for the greaterOrEquals method.
+         */
+        geq(number: BigNumber): boolean;
+
+        /**
+         * Checks if the first number is greater than the second.
+         */
+        greater(number: BigNumber): boolean;
+
+        /**
+         * Checks if the first number is greater than or equal to the second.
+         */
+        greaterOrEquals(number: BigNumber): boolean;
+
+        /**
+         * Alias for the greater method.
+         */
+        gt(number: BigNumber): boolean;
+
+        /**
+         * Returns true if the first number is divisible by the second number, false otherwise.
+         */
+        isDivisibleBy(number: BigNumber): boolean;
+
+        /**
+         * Returns true if the number is even, false otherwise.
+         */
+        isEven(): boolean;
+
+        /**
+         * Returns true if the number is negative, false otherwise.
+         * Returns false for 0 and true for -0.
+         */
+        isNegative(): boolean;
+
+        /**
+         * Returns true if the number is odd, false otherwise.
+         */
+        isOdd(): boolean;
+
+        /**
+         * Return true if the number is positive, false otherwise.
+         * Returns true for 0 and false for -0.
+         */
+        isPositive(): boolean;
+
+        /**
+         * Returns true if the number is prime, false otherwise.
+         */
+        isPrime(): boolean;
+
+        /**
+         * Returns true if the number is very likely to be prime, false otherwise.
+         */
+        isProbablePrime(iterations?: number): boolean;
+
+        /**
+         * Returns true if the number is 1 or -1, false otherwise.
+         */
+        isUnit(): boolean;
+
+        /**
+         * Return true if the number is 0 or -0, false otherwise.
+         */
+        isZero(): boolean;
+
+        /**
+         * Alias for the lesserOrEquals method.
+         */
+        leq(number: BigNumber): boolean;
+
+        /**
+         * Checks if the first number is lesser than the second.
+         */
+        lesser(number: BigNumber): boolean;
+
+        /**
+         * Checks if the first number is less than or equal to the second.
+         */
+        lesserOrEquals(number: BigNumber): boolean;
+
+        /**
+         * Alias for the lesser method.
+         */
+        lt(number: BigNumber): boolean;
+
+        /**
+         * Alias for the subtract method.
+         */
+        minus(number: BigNumber): BigInteger;
+
+        /**
+         * Performs division and returns the remainder, disregarding the quotient.
+         * The sign of the remainder will match the sign of the dividend.
+         */
+        mod(number: BigNumber): BigInteger;
+
+        /**
+         * Finds the multiplicative inverse of the number modulo mod.
+         */
+        modInv(number: BigNumber): BigInteger;
+
+        /**
+         * Takes the number to the power exp modulo mod.
+         */
+        modPow(exp: BigNumber, mod: BigNumber): BigInteger;
+
+        /**
+         * Performs multiplication.
+         */
+        multiply(number: BigNumber): BigInteger;
+
+        /**
+         * Reverses the sign of the number.
+         */
+        negate(): BigInteger;
+
+        /**
+         * Alias for the notEquals method.
+         */
+        neq(number: BigNumber): boolean;
+
+        /**
+         * Adds one to the number.
+         */
+        next(): BigInteger;
+
+        /**
+         * Performs the bitwise NOT operation.
+         */
+        not(): BigInteger;
+
+        /**
+         * Checks if two numbers are not equal.
+         */
+        notEquals(number: BigNumber): boolean;
+
+        /**
+         * Performs the bitwise OR operation.
+         */
+        or(number: BigNumber): BigInteger;
+
+        /**
+         * Alias for the divide method.
+         */
+        over(number: BigNumber): BigInteger;
+
+        /**
+         * Alias for the add method.
+         */
+        plus(number: BigNumber): BigInteger;
+
+        /**
+         * Performs exponentiation. If the exponent is less than 0, pow returns 0.
+         * bigInt.zero.pow(0) returns 1.
+         */
+        pow(number: BigNumber): BigInteger;
+
+        /**
+         * Subtracts one from the number.
+         */
+        prev(): BigInteger;
+
+        /**
+         * Alias for the mod method.
+         */
+        remainder(number: BigNumber): BigInteger;
+
+        /**
+         * Shifts the number left by n places in its binary representation.
+         * If a negative number is provided, it will shift right.
+         *
+         * Throws an error if number is outside of the range [-9007199254740992, 9007199254740992].
+         */
+        shiftLeft(number: BigNumber): BigInteger;
+
+        /**
+         * Shifts the number right by n places in its binary representation.
+         * If a negative number is provided, it will shift left.
+         *
+         * Throws an error if number is outside of the range [-9007199254740992, 9007199254740992].
+         */
+        shiftRight(number: BigNumber): BigInteger;
+
+        /**
+         * Squares the number.
+         */
+        square(): BigInteger;
+
+        /**
+         * Performs subtraction.
+         */
+        subtract(number: BigNumber): BigInteger;
+
+        /**
+         * Alias for the multiply method.
+         */
+        times(number: BigNumber): BigInteger;
+
+        /**
+         * Converts a bigInt into a native Javascript number. Loses precision for numbers outside the range.
+         */
+        toJSNumber(): number;
+
+        /**
+         * Converts a bigInt to a string.
+         */
+        toString(radix?: number): string;
+		
+		/**
+         * Converts a bigInt to a string. This method is called behind the scenes in JSON.stringify.
+         */
+        toJSON(): string;
+
+        /**
+         * Converts a bigInt to a native Javascript number. This override allows you to use native
+         * arithmetic operators without explicit conversion.
+         */
+        valueOf(): number;
+
+        /**
+         * Performs the bitwise XOR operation.
+         */
+        xor(number: BigNumber): BigInteger;
+    }
+
+    // Array constant accessors
+    interface BigIntegerStatic {
+        '-999': BigInteger;
+        '-998': BigInteger;
+        '-997': BigInteger;
+        '-996': BigInteger;
+        '-995': BigInteger;
+        '-994': BigInteger;
+        '-993': BigInteger;
+        '-992': BigInteger;
+        '-991': BigInteger;
+        '-990': BigInteger;
+        '-989': BigInteger;
+        '-988': BigInteger;
+        '-987': BigInteger;
+        '-986': BigInteger;
+        '-985': BigInteger;
+        '-984': BigInteger;
+        '-983': BigInteger;
+        '-982': BigInteger;
+        '-981': BigInteger;
+        '-980': BigInteger;
+        '-979': BigInteger;
+        '-978': BigInteger;
+        '-977': BigInteger;
+        '-976': BigInteger;
+        '-975': BigInteger;
+        '-974': BigInteger;
+        '-973': BigInteger;
+        '-972': BigInteger;
+        '-971': BigInteger;
+        '-970': BigInteger;
+        '-969': BigInteger;
+        '-968': BigInteger;
+        '-967': BigInteger;
+        '-966': BigInteger;
+        '-965': BigInteger;
+        '-964': BigInteger;
+        '-963': BigInteger;
+        '-962': BigInteger;
+        '-961': BigInteger;
+        '-960': BigInteger;
+        '-959': BigInteger;
+        '-958': BigInteger;
+        '-957': BigInteger;
+        '-956': BigInteger;
+        '-955': BigInteger;
+        '-954': BigInteger;
+        '-953': BigInteger;
+        '-952': BigInteger;
+        '-951': BigInteger;
+        '-950': BigInteger;
+        '-949': BigInteger;
+        '-948': BigInteger;
+        '-947': BigInteger;
+        '-946': BigInteger;
+        '-945': BigInteger;
+        '-944': BigInteger;
+        '-943': BigInteger;
+        '-942': BigInteger;
+        '-941': BigInteger;
+        '-940': BigInteger;
+        '-939': BigInteger;
+        '-938': BigInteger;
+        '-937': BigInteger;
+        '-936': BigInteger;
+        '-935': BigInteger;
+        '-934': BigInteger;
+        '-933': BigInteger;
+        '-932': BigInteger;
+        '-931': BigInteger;
+        '-930': BigInteger;
+        '-929': BigInteger;
+        '-928': BigInteger;
+        '-927': BigInteger;
+        '-926': BigInteger;
+        '-925': BigInteger;
+        '-924': BigInteger;
+        '-923': BigInteger;
+        '-922': BigInteger;
+        '-921': BigInteger;
+        '-920': BigInteger;
+        '-919': BigInteger;
+        '-918': BigInteger;
+        '-917': BigInteger;
+        '-916': BigInteger;
+        '-915': BigInteger;
+        '-914': BigInteger;
+        '-913': BigInteger;
+        '-912': BigInteger;
+        '-911': BigInteger;
+        '-910': BigInteger;
+        '-909': BigInteger;
+        '-908': BigInteger;
+        '-907': BigInteger;
+        '-906': BigInteger;
+        '-905': BigInteger;
+        '-904': BigInteger;
+        '-903': BigInteger;
+        '-902': BigInteger;
+        '-901': BigInteger;
+        '-900': BigInteger;
+        '-899': BigInteger;
+        '-898': BigInteger;
+        '-897': BigInteger;
+        '-896': BigInteger;
+        '-895': BigInteger;
+        '-894': BigInteger;
+        '-893': BigInteger;
+        '-892': BigInteger;
+        '-891': BigInteger;
+        '-890': BigInteger;
+        '-889': BigInteger;
+        '-888': BigInteger;
+        '-887': BigInteger;
+        '-886': BigInteger;
+        '-885': BigInteger;
+        '-884': BigInteger;
+        '-883': BigInteger;
+        '-882': BigInteger;
+        '-881': BigInteger;
+        '-880': BigInteger;
+        '-879': BigInteger;
+        '-878': BigInteger;
+        '-877': BigInteger;
+        '-876': BigInteger;
+        '-875': BigInteger;
+        '-874': BigInteger;
+        '-873': BigInteger;
+        '-872': BigInteger;
+        '-871': BigInteger;
+        '-870': BigInteger;
+        '-869': BigInteger;
+        '-868': BigInteger;
+        '-867': BigInteger;
+        '-866': BigInteger;
+        '-865': BigInteger;
+        '-864': BigInteger;
+        '-863': BigInteger;
+        '-862': BigInteger;
+        '-861': BigInteger;
+        '-860': BigInteger;
+        '-859': BigInteger;
+        '-858': BigInteger;
+        '-857': BigInteger;
+        '-856': BigInteger;
+        '-855': BigInteger;
+        '-854': BigInteger;
+        '-853': BigInteger;
+        '-852': BigInteger;
+        '-851': BigInteger;
+        '-850': BigInteger;
+        '-849': BigInteger;
+        '-848': BigInteger;
+        '-847': BigInteger;
+        '-846': BigInteger;
+        '-845': BigInteger;
+        '-844': BigInteger;
+        '-843': BigInteger;
+        '-842': BigInteger;
+        '-841': BigInteger;
+        '-840': BigInteger;
+        '-839': BigInteger;
+        '-838': BigInteger;
+        '-837': BigInteger;
+        '-836': BigInteger;
+        '-835': BigInteger;
+        '-834': BigInteger;
+        '-833': BigInteger;
+        '-832': BigInteger;
+        '-831': BigInteger;
+        '-830': BigInteger;
+        '-829': BigInteger;
+        '-828': BigInteger;
+        '-827': BigInteger;
+        '-826': BigInteger;
+        '-825': BigInteger;
+        '-824': BigInteger;
+        '-823': BigInteger;
+        '-822': BigInteger;
+        '-821': BigInteger;
+        '-820': BigInteger;
+        '-819': BigInteger;
+        '-818': BigInteger;
+        '-817': BigInteger;
+        '-816': BigInteger;
+        '-815': BigInteger;
+        '-814': BigInteger;
+        '-813': BigInteger;
+        '-812': BigInteger;
+        '-811': BigInteger;
+        '-810': BigInteger;
+        '-809': BigInteger;
+        '-808': BigInteger;
+        '-807': BigInteger;
+        '-806': BigInteger;
+        '-805': BigInteger;
+        '-804': BigInteger;
+        '-803': BigInteger;
+        '-802': BigInteger;
+        '-801': BigInteger;
+        '-800': BigInteger;
+        '-799': BigInteger;
+        '-798': BigInteger;
+        '-797': BigInteger;
+        '-796': BigInteger;
+        '-795': BigInteger;
+        '-794': BigInteger;
+        '-793': BigInteger;
+        '-792': BigInteger;
+        '-791': BigInteger;
+        '-790': BigInteger;
+        '-789': BigInteger;
+        '-788': BigInteger;
+        '-787': BigInteger;
+        '-786': BigInteger;
+        '-785': BigInteger;
+        '-784': BigInteger;
+        '-783': BigInteger;
+        '-782': BigInteger;
+        '-781': BigInteger;
+        '-780': BigInteger;
+        '-779': BigInteger;
+        '-778': BigInteger;
+        '-777': BigInteger;
+        '-776': BigInteger;
+        '-775': BigInteger;
+        '-774': BigInteger;
+        '-773': BigInteger;
+        '-772': BigInteger;
+        '-771': BigInteger;
+        '-770': BigInteger;
+        '-769': BigInteger;
+        '-768': BigInteger;
+        '-767': BigInteger;
+        '-766': BigInteger;
+        '-765': BigInteger;
+        '-764': BigInteger;
+        '-763': BigInteger;
+        '-762': BigInteger;
+        '-761': BigInteger;
+        '-760': BigInteger;
+        '-759': BigInteger;
+        '-758': BigInteger;
+        '-757': BigInteger;
+        '-756': BigInteger;
+        '-755': BigInteger;
+        '-754': BigInteger;
+        '-753': BigInteger;
+        '-752': BigInteger;
+        '-751': BigInteger;
+        '-750': BigInteger;
+        '-749': BigInteger;
+        '-748': BigInteger;
+        '-747': BigInteger;
+        '-746': BigInteger;
+        '-745': BigInteger;
+        '-744': BigInteger;
+        '-743': BigInteger;
+        '-742': BigInteger;
+        '-741': BigInteger;
+        '-740': BigInteger;
+        '-739': BigInteger;
+        '-738': BigInteger;
+        '-737': BigInteger;
+        '-736': BigInteger;
+        '-735': BigInteger;
+        '-734': BigInteger;
+        '-733': BigInteger;
+        '-732': BigInteger;
+        '-731': BigInteger;
+        '-730': BigInteger;
+        '-729': BigInteger;
+        '-728': BigInteger;
+        '-727': BigInteger;
+        '-726': BigInteger;
+        '-725': BigInteger;
+        '-724': BigInteger;
+        '-723': BigInteger;
+        '-722': BigInteger;
+        '-721': BigInteger;
+        '-720': BigInteger;
+        '-719': BigInteger;
+        '-718': BigInteger;
+        '-717': BigInteger;
+        '-716': BigInteger;
+        '-715': BigInteger;
+        '-714': BigInteger;
+        '-713': BigInteger;
+        '-712': BigInteger;
+        '-711': BigInteger;
+        '-710': BigInteger;
+        '-709': BigInteger;
+        '-708': BigInteger;
+        '-707': BigInteger;
+        '-706': BigInteger;
+        '-705': BigInteger;
+        '-704': BigInteger;
+        '-703': BigInteger;
+        '-702': BigInteger;
+        '-701': BigInteger;
+        '-700': BigInteger;
+        '-699': BigInteger;
+        '-698': BigInteger;
+        '-697': BigInteger;
+        '-696': BigInteger;
+        '-695': BigInteger;
+        '-694': BigInteger;
+        '-693': BigInteger;
+        '-692': BigInteger;
+        '-691': BigInteger;
+        '-690': BigInteger;
+        '-689': BigInteger;
+        '-688': BigInteger;
+        '-687': BigInteger;
+        '-686': BigInteger;
+        '-685': BigInteger;
+        '-684': BigInteger;
+        '-683': BigInteger;
+        '-682': BigInteger;
+        '-681': BigInteger;
+        '-680': BigInteger;
+        '-679': BigInteger;
+        '-678': BigInteger;
+        '-677': BigInteger;
+        '-676': BigInteger;
+        '-675': BigInteger;
+        '-674': BigInteger;
+        '-673': BigInteger;
+        '-672': BigInteger;
+        '-671': BigInteger;
+        '-670': BigInteger;
+        '-669': BigInteger;
+        '-668': BigInteger;
+        '-667': BigInteger;
+        '-666': BigInteger;
+        '-665': BigInteger;
+        '-664': BigInteger;
+        '-663': BigInteger;
+        '-662': BigInteger;
+        '-661': BigInteger;
+        '-660': BigInteger;
+        '-659': BigInteger;
+        '-658': BigInteger;
+        '-657': BigInteger;
+        '-656': BigInteger;
+        '-655': BigInteger;
+        '-654': BigInteger;
+        '-653': BigInteger;
+        '-652': BigInteger;
+        '-651': BigInteger;
+        '-650': BigInteger;
+        '-649': BigInteger;
+        '-648': BigInteger;
+        '-647': BigInteger;
+        '-646': BigInteger;
+        '-645': BigInteger;
+        '-644': BigInteger;
+        '-643': BigInteger;
+        '-642': BigInteger;
+        '-641': BigInteger;
+        '-640': BigInteger;
+        '-639': BigInteger;
+        '-638': BigInteger;
+        '-637': BigInteger;
+        '-636': BigInteger;
+        '-635': BigInteger;
+        '-634': BigInteger;
+        '-633': BigInteger;
+        '-632': BigInteger;
+        '-631': BigInteger;
+        '-630': BigInteger;
+        '-629': BigInteger;
+        '-628': BigInteger;
+        '-627': BigInteger;
+        '-626': BigInteger;
+        '-625': BigInteger;
+        '-624': BigInteger;
+        '-623': BigInteger;
+        '-622': BigInteger;
+        '-621': BigInteger;
+        '-620': BigInteger;
+        '-619': BigInteger;
+        '-618': BigInteger;
+        '-617': BigInteger;
+        '-616': BigInteger;
+        '-615': BigInteger;
+        '-614': BigInteger;
+        '-613': BigInteger;
+        '-612': BigInteger;
+        '-611': BigInteger;
+        '-610': BigInteger;
+        '-609': BigInteger;
+        '-608': BigInteger;
+        '-607': BigInteger;
+        '-606': BigInteger;
+        '-605': BigInteger;
+        '-604': BigInteger;
+        '-603': BigInteger;
+        '-602': BigInteger;
+        '-601': BigInteger;
+        '-600': BigInteger;
+        '-599': BigInteger;
+        '-598': BigInteger;
+        '-597': BigInteger;
+        '-596': BigInteger;
+        '-595': BigInteger;
+        '-594': BigInteger;
+        '-593': BigInteger;
+        '-592': BigInteger;
+        '-591': BigInteger;
+        '-590': BigInteger;
+        '-589': BigInteger;
+        '-588': BigInteger;
+        '-587': BigInteger;
+        '-586': BigInteger;
+        '-585': BigInteger;
+        '-584': BigInteger;
+        '-583': BigInteger;
+        '-582': BigInteger;
+        '-581': BigInteger;
+        '-580': BigInteger;
+        '-579': BigInteger;
+        '-578': BigInteger;
+        '-577': BigInteger;
+        '-576': BigInteger;
+        '-575': BigInteger;
+        '-574': BigInteger;
+        '-573': BigInteger;
+        '-572': BigInteger;
+        '-571': BigInteger;
+        '-570': BigInteger;
+        '-569': BigInteger;
+        '-568': BigInteger;
+        '-567': BigInteger;
+        '-566': BigInteger;
+        '-565': BigInteger;
+        '-564': BigInteger;
+        '-563': BigInteger;
+        '-562': BigInteger;
+        '-561': BigInteger;
+        '-560': BigInteger;
+        '-559': BigInteger;
+        '-558': BigInteger;
+        '-557': BigInteger;
+        '-556': BigInteger;
+        '-555': BigInteger;
+        '-554': BigInteger;
+        '-553': BigInteger;
+        '-552': BigInteger;
+        '-551': BigInteger;
+        '-550': BigInteger;
+        '-549': BigInteger;
+        '-548': BigInteger;
+        '-547': BigInteger;
+        '-546': BigInteger;
+        '-545': BigInteger;
+        '-544': BigInteger;
+        '-543': BigInteger;
+        '-542': BigInteger;
+        '-541': BigInteger;
+        '-540': BigInteger;
+        '-539': BigInteger;
+        '-538': BigInteger;
+        '-537': BigInteger;
+        '-536': BigInteger;
+        '-535': BigInteger;
+        '-534': BigInteger;
+        '-533': BigInteger;
+        '-532': BigInteger;
+        '-531': BigInteger;
+        '-530': BigInteger;
+        '-529': BigInteger;
+        '-528': BigInteger;
+        '-527': BigInteger;
+        '-526': BigInteger;
+        '-525': BigInteger;
+        '-524': BigInteger;
+        '-523': BigInteger;
+        '-522': BigInteger;
+        '-521': BigInteger;
+        '-520': BigInteger;
+        '-519': BigInteger;
+        '-518': BigInteger;
+        '-517': BigInteger;
+        '-516': BigInteger;
+        '-515': BigInteger;
+        '-514': BigInteger;
+        '-513': BigInteger;
+        '-512': BigInteger;
+        '-511': BigInteger;
+        '-510': BigInteger;
+        '-509': BigInteger;
+        '-508': BigInteger;
+        '-507': BigInteger;
+        '-506': BigInteger;
+        '-505': BigInteger;
+        '-504': BigInteger;
+        '-503': BigInteger;
+        '-502': BigInteger;
+        '-501': BigInteger;
+        '-500': BigInteger;
+        '-499': BigInteger;
+        '-498': BigInteger;
+        '-497': BigInteger;
+        '-496': BigInteger;
+        '-495': BigInteger;
+        '-494': BigInteger;
+        '-493': BigInteger;
+        '-492': BigInteger;
+        '-491': BigInteger;
+        '-490': BigInteger;
+        '-489': BigInteger;
+        '-488': BigInteger;
+        '-487': BigInteger;
+        '-486': BigInteger;
+        '-485': BigInteger;
+        '-484': BigInteger;
+        '-483': BigInteger;
+        '-482': BigInteger;
+        '-481': BigInteger;
+        '-480': BigInteger;
+        '-479': BigInteger;
+        '-478': BigInteger;
+        '-477': BigInteger;
+        '-476': BigInteger;
+        '-475': BigInteger;
+        '-474': BigInteger;
+        '-473': BigInteger;
+        '-472': BigInteger;
+        '-471': BigInteger;
+        '-470': BigInteger;
+        '-469': BigInteger;
+        '-468': BigInteger;
+        '-467': BigInteger;
+        '-466': BigInteger;
+        '-465': BigInteger;
+        '-464': BigInteger;
+        '-463': BigInteger;
+        '-462': BigInteger;
+        '-461': BigInteger;
+        '-460': BigInteger;
+        '-459': BigInteger;
+        '-458': BigInteger;
+        '-457': BigInteger;
+        '-456': BigInteger;
+        '-455': BigInteger;
+        '-454': BigInteger;
+        '-453': BigInteger;
+        '-452': BigInteger;
+        '-451': BigInteger;
+        '-450': BigInteger;
+        '-449': BigInteger;
+        '-448': BigInteger;
+        '-447': BigInteger;
+        '-446': BigInteger;
+        '-445': BigInteger;
+        '-444': BigInteger;
+        '-443': BigInteger;
+        '-442': BigInteger;
+        '-441': BigInteger;
+        '-440': BigInteger;
+        '-439': BigInteger;
+        '-438': BigInteger;
+        '-437': BigInteger;
+        '-436': BigInteger;
+        '-435': BigInteger;
+        '-434': BigInteger;
+        '-433': BigInteger;
+        '-432': BigInteger;
+        '-431': BigInteger;
+        '-430': BigInteger;
+        '-429': BigInteger;
+        '-428': BigInteger;
+        '-427': BigInteger;
+        '-426': BigInteger;
+        '-425': BigInteger;
+        '-424': BigInteger;
+        '-423': BigInteger;
+        '-422': BigInteger;
+        '-421': BigInteger;
+        '-420': BigInteger;
+        '-419': BigInteger;
+        '-418': BigInteger;
+        '-417': BigInteger;
+        '-416': BigInteger;
+        '-415': BigInteger;
+        '-414': BigInteger;
+        '-413': BigInteger;
+        '-412': BigInteger;
+        '-411': BigInteger;
+        '-410': BigInteger;
+        '-409': BigInteger;
+        '-408': BigInteger;
+        '-407': BigInteger;
+        '-406': BigInteger;
+        '-405': BigInteger;
+        '-404': BigInteger;
+        '-403': BigInteger;
+        '-402': BigInteger;
+        '-401': BigInteger;
+        '-400': BigInteger;
+        '-399': BigInteger;
+        '-398': BigInteger;
+        '-397': BigInteger;
+        '-396': BigInteger;
+        '-395': BigInteger;
+        '-394': BigInteger;
+        '-393': BigInteger;
+        '-392': BigInteger;
+        '-391': BigInteger;
+        '-390': BigInteger;
+        '-389': BigInteger;
+        '-388': BigInteger;
+        '-387': BigInteger;
+        '-386': BigInteger;
+        '-385': BigInteger;
+        '-384': BigInteger;
+        '-383': BigInteger;
+        '-382': BigInteger;
+        '-381': BigInteger;
+        '-380': BigInteger;
+        '-379': BigInteger;
+        '-378': BigInteger;
+        '-377': BigInteger;
+        '-376': BigInteger;
+        '-375': BigInteger;
+        '-374': BigInteger;
+        '-373': BigInteger;
+        '-372': BigInteger;
+        '-371': BigInteger;
+        '-370': BigInteger;
+        '-369': BigInteger;
+        '-368': BigInteger;
+        '-367': BigInteger;
+        '-366': BigInteger;
+        '-365': BigInteger;
+        '-364': BigInteger;
+        '-363': BigInteger;
+        '-362': BigInteger;
+        '-361': BigInteger;
+        '-360': BigInteger;
+        '-359': BigInteger;
+        '-358': BigInteger;
+        '-357': BigInteger;
+        '-356': BigInteger;
+        '-355': BigInteger;
+        '-354': BigInteger;
+        '-353': BigInteger;
+        '-352': BigInteger;
+        '-351': BigInteger;
+        '-350': BigInteger;
+        '-349': BigInteger;
+        '-348': BigInteger;
+        '-347': BigInteger;
+        '-346': BigInteger;
+        '-345': BigInteger;
+        '-344': BigInteger;
+        '-343': BigInteger;
+        '-342': BigInteger;
+        '-341': BigInteger;
+        '-340': BigInteger;
+        '-339': BigInteger;
+        '-338': BigInteger;
+        '-337': BigInteger;
+        '-336': BigInteger;
+        '-335': BigInteger;
+        '-334': BigInteger;
+        '-333': BigInteger;
+        '-332': BigInteger;
+        '-331': BigInteger;
+        '-330': BigInteger;
+        '-329': BigInteger;
+        '-328': BigInteger;
+        '-327': BigInteger;
+        '-326': BigInteger;
+        '-325': BigInteger;
+        '-324': BigInteger;
+        '-323': BigInteger;
+        '-322': BigInteger;
+        '-321': BigInteger;
+        '-320': BigInteger;
+        '-319': BigInteger;
+        '-318': BigInteger;
+        '-317': BigInteger;
+        '-316': BigInteger;
+        '-315': BigInteger;
+        '-314': BigInteger;
+        '-313': BigInteger;
+        '-312': BigInteger;
+        '-311': BigInteger;
+        '-310': BigInteger;
+        '-309': BigInteger;
+        '-308': BigInteger;
+        '-307': BigInteger;
+        '-306': BigInteger;
+        '-305': BigInteger;
+        '-304': BigInteger;
+        '-303': BigInteger;
+        '-302': BigInteger;
+        '-301': BigInteger;
+        '-300': BigInteger;
+        '-299': BigInteger;
+        '-298': BigInteger;
+        '-297': BigInteger;
+        '-296': BigInteger;
+        '-295': BigInteger;
+        '-294': BigInteger;
+        '-293': BigInteger;
+        '-292': BigInteger;
+        '-291': BigInteger;
+        '-290': BigInteger;
+        '-289': BigInteger;
+        '-288': BigInteger;
+        '-287': BigInteger;
+        '-286': BigInteger;
+        '-285': BigInteger;
+        '-284': BigInteger;
+        '-283': BigInteger;
+        '-282': BigInteger;
+        '-281': BigInteger;
+        '-280': BigInteger;
+        '-279': BigInteger;
+        '-278': BigInteger;
+        '-277': BigInteger;
+        '-276': BigInteger;
+        '-275': BigInteger;
+        '-274': BigInteger;
+        '-273': BigInteger;
+        '-272': BigInteger;
+        '-271': BigInteger;
+        '-270': BigInteger;
+        '-269': BigInteger;
+        '-268': BigInteger;
+        '-267': BigInteger;
+        '-266': BigInteger;
+        '-265': BigInteger;
+        '-264': BigInteger;
+        '-263': BigInteger;
+        '-262': BigInteger;
+        '-261': BigInteger;
+        '-260': BigInteger;
+        '-259': BigInteger;
+        '-258': BigInteger;
+        '-257': BigInteger;
+        '-256': BigInteger;
+        '-255': BigInteger;
+        '-254': BigInteger;
+        '-253': BigInteger;
+        '-252': BigInteger;
+        '-251': BigInteger;
+        '-250': BigInteger;
+        '-249': BigInteger;
+        '-248': BigInteger;
+        '-247': BigInteger;
+        '-246': BigInteger;
+        '-245': BigInteger;
+        '-244': BigInteger;
+        '-243': BigInteger;
+        '-242': BigInteger;
+        '-241': BigInteger;
+        '-240': BigInteger;
+        '-239': BigInteger;
+        '-238': BigInteger;
+        '-237': BigInteger;
+        '-236': BigInteger;
+        '-235': BigInteger;
+        '-234': BigInteger;
+        '-233': BigInteger;
+        '-232': BigInteger;
+        '-231': BigInteger;
+        '-230': BigInteger;
+        '-229': BigInteger;
+        '-228': BigInteger;
+        '-227': BigInteger;
+        '-226': BigInteger;
+        '-225': BigInteger;
+        '-224': BigInteger;
+        '-223': BigInteger;
+        '-222': BigInteger;
+        '-221': BigInteger;
+        '-220': BigInteger;
+        '-219': BigInteger;
+        '-218': BigInteger;
+        '-217': BigInteger;
+        '-216': BigInteger;
+        '-215': BigInteger;
+        '-214': BigInteger;
+        '-213': BigInteger;
+        '-212': BigInteger;
+        '-211': BigInteger;
+        '-210': BigInteger;
+        '-209': BigInteger;
+        '-208': BigInteger;
+        '-207': BigInteger;
+        '-206': BigInteger;
+        '-205': BigInteger;
+        '-204': BigInteger;
+        '-203': BigInteger;
+        '-202': BigInteger;
+        '-201': BigInteger;
+        '-200': BigInteger;
+        '-199': BigInteger;
+        '-198': BigInteger;
+        '-197': BigInteger;
+        '-196': BigInteger;
+        '-195': BigInteger;
+        '-194': BigInteger;
+        '-193': BigInteger;
+        '-192': BigInteger;
+        '-191': BigInteger;
+        '-190': BigInteger;
+        '-189': BigInteger;
+        '-188': BigInteger;
+        '-187': BigInteger;
+        '-186': BigInteger;
+        '-185': BigInteger;
+        '-184': BigInteger;
+        '-183': BigInteger;
+        '-182': BigInteger;
+        '-181': BigInteger;
+        '-180': BigInteger;
+        '-179': BigInteger;
+        '-178': BigInteger;
+        '-177': BigInteger;
+        '-176': BigInteger;
+        '-175': BigInteger;
+        '-174': BigInteger;
+        '-173': BigInteger;
+        '-172': BigInteger;
+        '-171': BigInteger;
+        '-170': BigInteger;
+        '-169': BigInteger;
+        '-168': BigInteger;
+        '-167': BigInteger;
+        '-166': BigInteger;
+        '-165': BigInteger;
+        '-164': BigInteger;
+        '-163': BigInteger;
+        '-162': BigInteger;
+        '-161': BigInteger;
+        '-160': BigInteger;
+        '-159': BigInteger;
+        '-158': BigInteger;
+        '-157': BigInteger;
+        '-156': BigInteger;
+        '-155': BigInteger;
+        '-154': BigInteger;
+        '-153': BigInteger;
+        '-152': BigInteger;
+        '-151': BigInteger;
+        '-150': BigInteger;
+        '-149': BigInteger;
+        '-148': BigInteger;
+        '-147': BigInteger;
+        '-146': BigInteger;
+        '-145': BigInteger;
+        '-144': BigInteger;
+        '-143': BigInteger;
+        '-142': BigInteger;
+        '-141': BigInteger;
+        '-140': BigInteger;
+        '-139': BigInteger;
+        '-138': BigInteger;
+        '-137': BigInteger;
+        '-136': BigInteger;
+        '-135': BigInteger;
+        '-134': BigInteger;
+        '-133': BigInteger;
+        '-132': BigInteger;
+        '-131': BigInteger;
+        '-130': BigInteger;
+        '-129': BigInteger;
+        '-128': BigInteger;
+        '-127': BigInteger;
+        '-126': BigInteger;
+        '-125': BigInteger;
+        '-124': BigInteger;
+        '-123': BigInteger;
+        '-122': BigInteger;
+        '-121': BigInteger;
+        '-120': BigInteger;
+        '-119': BigInteger;
+        '-118': BigInteger;
+        '-117': BigInteger;
+        '-116': BigInteger;
+        '-115': BigInteger;
+        '-114': BigInteger;
+        '-113': BigInteger;
+        '-112': BigInteger;
+        '-111': BigInteger;
+        '-110': BigInteger;
+        '-109': BigInteger;
+        '-108': BigInteger;
+        '-107': BigInteger;
+        '-106': BigInteger;
+        '-105': BigInteger;
+        '-104': BigInteger;
+        '-103': BigInteger;
+        '-102': BigInteger;
+        '-101': BigInteger;
+        '-100': BigInteger;
+        '-99': BigInteger;
+        '-98': BigInteger;
+        '-97': BigInteger;
+        '-96': BigInteger;
+        '-95': BigInteger;
+        '-94': BigInteger;
+        '-93': BigInteger;
+        '-92': BigInteger;
+        '-91': BigInteger;
+        '-90': BigInteger;
+        '-89': BigInteger;
+        '-88': BigInteger;
+        '-87': BigInteger;
+        '-86': BigInteger;
+        '-85': BigInteger;
+        '-84': BigInteger;
+        '-83': BigInteger;
+        '-82': BigInteger;
+        '-81': BigInteger;
+        '-80': BigInteger;
+        '-79': BigInteger;
+        '-78': BigInteger;
+        '-77': BigInteger;
+        '-76': BigInteger;
+        '-75': BigInteger;
+        '-74': BigInteger;
+        '-73': BigInteger;
+        '-72': BigInteger;
+        '-71': BigInteger;
+        '-70': BigInteger;
+        '-69': BigInteger;
+        '-68': BigInteger;
+        '-67': BigInteger;
+        '-66': BigInteger;
+        '-65': BigInteger;
+        '-64': BigInteger;
+        '-63': BigInteger;
+        '-62': BigInteger;
+        '-61': BigInteger;
+        '-60': BigInteger;
+        '-59': BigInteger;
+        '-58': BigInteger;
+        '-57': BigInteger;
+        '-56': BigInteger;
+        '-55': BigInteger;
+        '-54': BigInteger;
+        '-53': BigInteger;
+        '-52': BigInteger;
+        '-51': BigInteger;
+        '-50': BigInteger;
+        '-49': BigInteger;
+        '-48': BigInteger;
+        '-47': BigInteger;
+        '-46': BigInteger;
+        '-45': BigInteger;
+        '-44': BigInteger;
+        '-43': BigInteger;
+        '-42': BigInteger;
+        '-41': BigInteger;
+        '-40': BigInteger;
+        '-39': BigInteger;
+        '-38': BigInteger;
+        '-37': BigInteger;
+        '-36': BigInteger;
+        '-35': BigInteger;
+        '-34': BigInteger;
+        '-33': BigInteger;
+        '-32': BigInteger;
+        '-31': BigInteger;
+        '-30': BigInteger;
+        '-29': BigInteger;
+        '-28': BigInteger;
+        '-27': BigInteger;
+        '-26': BigInteger;
+        '-25': BigInteger;
+        '-24': BigInteger;
+        '-23': BigInteger;
+        '-22': BigInteger;
+        '-21': BigInteger;
+        '-20': BigInteger;
+        '-19': BigInteger;
+        '-18': BigInteger;
+        '-17': BigInteger;
+        '-16': BigInteger;
+        '-15': BigInteger;
+        '-14': BigInteger;
+        '-13': BigInteger;
+        '-12': BigInteger;
+        '-11': BigInteger;
+        '-10': BigInteger;
+        '-9': BigInteger;
+        '-8': BigInteger;
+        '-7': BigInteger;
+        '-6': BigInteger;
+        '-5': BigInteger;
+        '-4': BigInteger;
+        '-3': BigInteger;
+        '-2': BigInteger;
+        '-1': BigInteger;
+        '0': BigInteger;
+        '1': BigInteger;
+        '2': BigInteger;
+        '3': BigInteger;
+        '4': BigInteger;
+        '5': BigInteger;
+        '6': BigInteger;
+        '7': BigInteger;
+        '8': BigInteger;
+        '9': BigInteger;
+        '10': BigInteger;
+        '11': BigInteger;
+        '12': BigInteger;
+        '13': BigInteger;
+        '14': BigInteger;
+        '15': BigInteger;
+        '16': BigInteger;
+        '17': BigInteger;
+        '18': BigInteger;
+        '19': BigInteger;
+        '20': BigInteger;
+        '21': BigInteger;
+        '22': BigInteger;
+        '23': BigInteger;
+        '24': BigInteger;
+        '25': BigInteger;
+        '26': BigInteger;
+        '27': BigInteger;
+        '28': BigInteger;
+        '29': BigInteger;
+        '30': BigInteger;
+        '31': BigInteger;
+        '32': BigInteger;
+        '33': BigInteger;
+        '34': BigInteger;
+        '35': BigInteger;
+        '36': BigInteger;
+        '37': BigInteger;
+        '38': BigInteger;
+        '39': BigInteger;
+        '40': BigInteger;
+        '41': BigInteger;
+        '42': BigInteger;
+        '43': BigInteger;
+        '44': BigInteger;
+        '45': BigInteger;
+        '46': BigInteger;
+        '47': BigInteger;
+        '48': BigInteger;
+        '49': BigInteger;
+        '50': BigInteger;
+        '51': BigInteger;
+        '52': BigInteger;
+        '53': BigInteger;
+        '54': BigInteger;
+        '55': BigInteger;
+        '56': BigInteger;
+        '57': BigInteger;
+        '58': BigInteger;
+        '59': BigInteger;
+        '60': BigInteger;
+        '61': BigInteger;
+        '62': BigInteger;
+        '63': BigInteger;
+        '64': BigInteger;
+        '65': BigInteger;
+        '66': BigInteger;
+        '67': BigInteger;
+        '68': BigInteger;
+        '69': BigInteger;
+        '70': BigInteger;
+        '71': BigInteger;
+        '72': BigInteger;
+        '73': BigInteger;
+        '74': BigInteger;
+        '75': BigInteger;
+        '76': BigInteger;
+        '77': BigInteger;
+        '78': BigInteger;
+        '79': BigInteger;
+        '80': BigInteger;
+        '81': BigInteger;
+        '82': BigInteger;
+        '83': BigInteger;
+        '84': BigInteger;
+        '85': BigInteger;
+        '86': BigInteger;
+        '87': BigInteger;
+        '88': BigInteger;
+        '89': BigInteger;
+        '90': BigInteger;
+        '91': BigInteger;
+        '92': BigInteger;
+        '93': BigInteger;
+        '94': BigInteger;
+        '95': BigInteger;
+        '96': BigInteger;
+        '97': BigInteger;
+        '98': BigInteger;
+        '99': BigInteger;
+        '100': BigInteger;
+        '101': BigInteger;
+        '102': BigInteger;
+        '103': BigInteger;
+        '104': BigInteger;
+        '105': BigInteger;
+        '106': BigInteger;
+        '107': BigInteger;
+        '108': BigInteger;
+        '109': BigInteger;
+        '110': BigInteger;
+        '111': BigInteger;
+        '112': BigInteger;
+        '113': BigInteger;
+        '114': BigInteger;
+        '115': BigInteger;
+        '116': BigInteger;
+        '117': BigInteger;
+        '118': BigInteger;
+        '119': BigInteger;
+        '120': BigInteger;
+        '121': BigInteger;
+        '122': BigInteger;
+        '123': BigInteger;
+        '124': BigInteger;
+        '125': BigInteger;
+        '126': BigInteger;
+        '127': BigInteger;
+        '128': BigInteger;
+        '129': BigInteger;
+        '130': BigInteger;
+        '131': BigInteger;
+        '132': BigInteger;
+        '133': BigInteger;
+        '134': BigInteger;
+        '135': BigInteger;
+        '136': BigInteger;
+        '137': BigInteger;
+        '138': BigInteger;
+        '139': BigInteger;
+        '140': BigInteger;
+        '141': BigInteger;
+        '142': BigInteger;
+        '143': BigInteger;
+        '144': BigInteger;
+        '145': BigInteger;
+        '146': BigInteger;
+        '147': BigInteger;
+        '148': BigInteger;
+        '149': BigInteger;
+        '150': BigInteger;
+        '151': BigInteger;
+        '152': BigInteger;
+        '153': BigInteger;
+        '154': BigInteger;
+        '155': BigInteger;
+        '156': BigInteger;
+        '157': BigInteger;
+        '158': BigInteger;
+        '159': BigInteger;
+        '160': BigInteger;
+        '161': BigInteger;
+        '162': BigInteger;
+        '163': BigInteger;
+        '164': BigInteger;
+        '165': BigInteger;
+        '166': BigInteger;
+        '167': BigInteger;
+        '168': BigInteger;
+        '169': BigInteger;
+        '170': BigInteger;
+        '171': BigInteger;
+        '172': BigInteger;
+        '173': BigInteger;
+        '174': BigInteger;
+        '175': BigInteger;
+        '176': BigInteger;
+        '177': BigInteger;
+        '178': BigInteger;
+        '179': BigInteger;
+        '180': BigInteger;
+        '181': BigInteger;
+        '182': BigInteger;
+        '183': BigInteger;
+        '184': BigInteger;
+        '185': BigInteger;
+        '186': BigInteger;
+        '187': BigInteger;
+        '188': BigInteger;
+        '189': BigInteger;
+        '190': BigInteger;
+        '191': BigInteger;
+        '192': BigInteger;
+        '193': BigInteger;
+        '194': BigInteger;
+        '195': BigInteger;
+        '196': BigInteger;
+        '197': BigInteger;
+        '198': BigInteger;
+        '199': BigInteger;
+        '200': BigInteger;
+        '201': BigInteger;
+        '202': BigInteger;
+        '203': BigInteger;
+        '204': BigInteger;
+        '205': BigInteger;
+        '206': BigInteger;
+        '207': BigInteger;
+        '208': BigInteger;
+        '209': BigInteger;
+        '210': BigInteger;
+        '211': BigInteger;
+        '212': BigInteger;
+        '213': BigInteger;
+        '214': BigInteger;
+        '215': BigInteger;
+        '216': BigInteger;
+        '217': BigInteger;
+        '218': BigInteger;
+        '219': BigInteger;
+        '220': BigInteger;
+        '221': BigInteger;
+        '222': BigInteger;
+        '223': BigInteger;
+        '224': BigInteger;
+        '225': BigInteger;
+        '226': BigInteger;
+        '227': BigInteger;
+        '228': BigInteger;
+        '229': BigInteger;
+        '230': BigInteger;
+        '231': BigInteger;
+        '232': BigInteger;
+        '233': BigInteger;
+        '234': BigInteger;
+        '235': BigInteger;
+        '236': BigInteger;
+        '237': BigInteger;
+        '238': BigInteger;
+        '239': BigInteger;
+        '240': BigInteger;
+        '241': BigInteger;
+        '242': BigInteger;
+        '243': BigInteger;
+        '244': BigInteger;
+        '245': BigInteger;
+        '246': BigInteger;
+        '247': BigInteger;
+        '248': BigInteger;
+        '249': BigInteger;
+        '250': BigInteger;
+        '251': BigInteger;
+        '252': BigInteger;
+        '253': BigInteger;
+        '254': BigInteger;
+        '255': BigInteger;
+        '256': BigInteger;
+        '257': BigInteger;
+        '258': BigInteger;
+        '259': BigInteger;
+        '260': BigInteger;
+        '261': BigInteger;
+        '262': BigInteger;
+        '263': BigInteger;
+        '264': BigInteger;
+        '265': BigInteger;
+        '266': BigInteger;
+        '267': BigInteger;
+        '268': BigInteger;
+        '269': BigInteger;
+        '270': BigInteger;
+        '271': BigInteger;
+        '272': BigInteger;
+        '273': BigInteger;
+        '274': BigInteger;
+        '275': BigInteger;
+        '276': BigInteger;
+        '277': BigInteger;
+        '278': BigInteger;
+        '279': BigInteger;
+        '280': BigInteger;
+        '281': BigInteger;
+        '282': BigInteger;
+        '283': BigInteger;
+        '284': BigInteger;
+        '285': BigInteger;
+        '286': BigInteger;
+        '287': BigInteger;
+        '288': BigInteger;
+        '289': BigInteger;
+        '290': BigInteger;
+        '291': BigInteger;
+        '292': BigInteger;
+        '293': BigInteger;
+        '294': BigInteger;
+        '295': BigInteger;
+        '296': BigInteger;
+        '297': BigInteger;
+        '298': BigInteger;
+        '299': BigInteger;
+        '300': BigInteger;
+        '301': BigInteger;
+        '302': BigInteger;
+        '303': BigInteger;
+        '304': BigInteger;
+        '305': BigInteger;
+        '306': BigInteger;
+        '307': BigInteger;
+        '308': BigInteger;
+        '309': BigInteger;
+        '310': BigInteger;
+        '311': BigInteger;
+        '312': BigInteger;
+        '313': BigInteger;
+        '314': BigInteger;
+        '315': BigInteger;
+        '316': BigInteger;
+        '317': BigInteger;
+        '318': BigInteger;
+        '319': BigInteger;
+        '320': BigInteger;
+        '321': BigInteger;
+        '322': BigInteger;
+        '323': BigInteger;
+        '324': BigInteger;
+        '325': BigInteger;
+        '326': BigInteger;
+        '327': BigInteger;
+        '328': BigInteger;
+        '329': BigInteger;
+        '330': BigInteger;
+        '331': BigInteger;
+        '332': BigInteger;
+        '333': BigInteger;
+        '334': BigInteger;
+        '335': BigInteger;
+        '336': BigInteger;
+        '337': BigInteger;
+        '338': BigInteger;
+        '339': BigInteger;
+        '340': BigInteger;
+        '341': BigInteger;
+        '342': BigInteger;
+        '343': BigInteger;
+        '344': BigInteger;
+        '345': BigInteger;
+        '346': BigInteger;
+        '347': BigInteger;
+        '348': BigInteger;
+        '349': BigInteger;
+        '350': BigInteger;
+        '351': BigInteger;
+        '352': BigInteger;
+        '353': BigInteger;
+        '354': BigInteger;
+        '355': BigInteger;
+        '356': BigInteger;
+        '357': BigInteger;
+        '358': BigInteger;
+        '359': BigInteger;
+        '360': BigInteger;
+        '361': BigInteger;
+        '362': BigInteger;
+        '363': BigInteger;
+        '364': BigInteger;
+        '365': BigInteger;
+        '366': BigInteger;
+        '367': BigInteger;
+        '368': BigInteger;
+        '369': BigInteger;
+        '370': BigInteger;
+        '371': BigInteger;
+        '372': BigInteger;
+        '373': BigInteger;
+        '374': BigInteger;
+        '375': BigInteger;
+        '376': BigInteger;
+        '377': BigInteger;
+        '378': BigInteger;
+        '379': BigInteger;
+        '380': BigInteger;
+        '381': BigInteger;
+        '382': BigInteger;
+        '383': BigInteger;
+        '384': BigInteger;
+        '385': BigInteger;
+        '386': BigInteger;
+        '387': BigInteger;
+        '388': BigInteger;
+        '389': BigInteger;
+        '390': BigInteger;
+        '391': BigInteger;
+        '392': BigInteger;
+        '393': BigInteger;
+        '394': BigInteger;
+        '395': BigInteger;
+        '396': BigInteger;
+        '397': BigInteger;
+        '398': BigInteger;
+        '399': BigInteger;
+        '400': BigInteger;
+        '401': BigInteger;
+        '402': BigInteger;
+        '403': BigInteger;
+        '404': BigInteger;
+        '405': BigInteger;
+        '406': BigInteger;
+        '407': BigInteger;
+        '408': BigInteger;
+        '409': BigInteger;
+        '410': BigInteger;
+        '411': BigInteger;
+        '412': BigInteger;
+        '413': BigInteger;
+        '414': BigInteger;
+        '415': BigInteger;
+        '416': BigInteger;
+        '417': BigInteger;
+        '418': BigInteger;
+        '419': BigInteger;
+        '420': BigInteger;
+        '421': BigInteger;
+        '422': BigInteger;
+        '423': BigInteger;
+        '424': BigInteger;
+        '425': BigInteger;
+        '426': BigInteger;
+        '427': BigInteger;
+        '428': BigInteger;
+        '429': BigInteger;
+        '430': BigInteger;
+        '431': BigInteger;
+        '432': BigInteger;
+        '433': BigInteger;
+        '434': BigInteger;
+        '435': BigInteger;
+        '436': BigInteger;
+        '437': BigInteger;
+        '438': BigInteger;
+        '439': BigInteger;
+        '440': BigInteger;
+        '441': BigInteger;
+        '442': BigInteger;
+        '443': BigInteger;
+        '444': BigInteger;
+        '445': BigInteger;
+        '446': BigInteger;
+        '447': BigInteger;
+        '448': BigInteger;
+        '449': BigInteger;
+        '450': BigInteger;
+        '451': BigInteger;
+        '452': BigInteger;
+        '453': BigInteger;
+        '454': BigInteger;
+        '455': BigInteger;
+        '456': BigInteger;
+        '457': BigInteger;
+        '458': BigInteger;
+        '459': BigInteger;
+        '460': BigInteger;
+        '461': BigInteger;
+        '462': BigInteger;
+        '463': BigInteger;
+        '464': BigInteger;
+        '465': BigInteger;
+        '466': BigInteger;
+        '467': BigInteger;
+        '468': BigInteger;
+        '469': BigInteger;
+        '470': BigInteger;
+        '471': BigInteger;
+        '472': BigInteger;
+        '473': BigInteger;
+        '474': BigInteger;
+        '475': BigInteger;
+        '476': BigInteger;
+        '477': BigInteger;
+        '478': BigInteger;
+        '479': BigInteger;
+        '480': BigInteger;
+        '481': BigInteger;
+        '482': BigInteger;
+        '483': BigInteger;
+        '484': BigInteger;
+        '485': BigInteger;
+        '486': BigInteger;
+        '487': BigInteger;
+        '488': BigInteger;
+        '489': BigInteger;
+        '490': BigInteger;
+        '491': BigInteger;
+        '492': BigInteger;
+        '493': BigInteger;
+        '494': BigInteger;
+        '495': BigInteger;
+        '496': BigInteger;
+        '497': BigInteger;
+        '498': BigInteger;
+        '499': BigInteger;
+        '500': BigInteger;
+        '501': BigInteger;
+        '502': BigInteger;
+        '503': BigInteger;
+        '504': BigInteger;
+        '505': BigInteger;
+        '506': BigInteger;
+        '507': BigInteger;
+        '508': BigInteger;
+        '509': BigInteger;
+        '510': BigInteger;
+        '511': BigInteger;
+        '512': BigInteger;
+        '513': BigInteger;
+        '514': BigInteger;
+        '515': BigInteger;
+        '516': BigInteger;
+        '517': BigInteger;
+        '518': BigInteger;
+        '519': BigInteger;
+        '520': BigInteger;
+        '521': BigInteger;
+        '522': BigInteger;
+        '523': BigInteger;
+        '524': BigInteger;
+        '525': BigInteger;
+        '526': BigInteger;
+        '527': BigInteger;
+        '528': BigInteger;
+        '529': BigInteger;
+        '530': BigInteger;
+        '531': BigInteger;
+        '532': BigInteger;
+        '533': BigInteger;
+        '534': BigInteger;
+        '535': BigInteger;
+        '536': BigInteger;
+        '537': BigInteger;
+        '538': BigInteger;
+        '539': BigInteger;
+        '540': BigInteger;
+        '541': BigInteger;
+        '542': BigInteger;
+        '543': BigInteger;
+        '544': BigInteger;
+        '545': BigInteger;
+        '546': BigInteger;
+        '547': BigInteger;
+        '548': BigInteger;
+        '549': BigInteger;
+        '550': BigInteger;
+        '551': BigInteger;
+        '552': BigInteger;
+        '553': BigInteger;
+        '554': BigInteger;
+        '555': BigInteger;
+        '556': BigInteger;
+        '557': BigInteger;
+        '558': BigInteger;
+        '559': BigInteger;
+        '560': BigInteger;
+        '561': BigInteger;
+        '562': BigInteger;
+        '563': BigInteger;
+        '564': BigInteger;
+        '565': BigInteger;
+        '566': BigInteger;
+        '567': BigInteger;
+        '568': BigInteger;
+        '569': BigInteger;
+        '570': BigInteger;
+        '571': BigInteger;
+        '572': BigInteger;
+        '573': BigInteger;
+        '574': BigInteger;
+        '575': BigInteger;
+        '576': BigInteger;
+        '577': BigInteger;
+        '578': BigInteger;
+        '579': BigInteger;
+        '580': BigInteger;
+        '581': BigInteger;
+        '582': BigInteger;
+        '583': BigInteger;
+        '584': BigInteger;
+        '585': BigInteger;
+        '586': BigInteger;
+        '587': BigInteger;
+        '588': BigInteger;
+        '589': BigInteger;
+        '590': BigInteger;
+        '591': BigInteger;
+        '592': BigInteger;
+        '593': BigInteger;
+        '594': BigInteger;
+        '595': BigInteger;
+        '596': BigInteger;
+        '597': BigInteger;
+        '598': BigInteger;
+        '599': BigInteger;
+        '600': BigInteger;
+        '601': BigInteger;
+        '602': BigInteger;
+        '603': BigInteger;
+        '604': BigInteger;
+        '605': BigInteger;
+        '606': BigInteger;
+        '607': BigInteger;
+        '608': BigInteger;
+        '609': BigInteger;
+        '610': BigInteger;
+        '611': BigInteger;
+        '612': BigInteger;
+        '613': BigInteger;
+        '614': BigInteger;
+        '615': BigInteger;
+        '616': BigInteger;
+        '617': BigInteger;
+        '618': BigInteger;
+        '619': BigInteger;
+        '620': BigInteger;
+        '621': BigInteger;
+        '622': BigInteger;
+        '623': BigInteger;
+        '624': BigInteger;
+        '625': BigInteger;
+        '626': BigInteger;
+        '627': BigInteger;
+        '628': BigInteger;
+        '629': BigInteger;
+        '630': BigInteger;
+        '631': BigInteger;
+        '632': BigInteger;
+        '633': BigInteger;
+        '634': BigInteger;
+        '635': BigInteger;
+        '636': BigInteger;
+        '637': BigInteger;
+        '638': BigInteger;
+        '639': BigInteger;
+        '640': BigInteger;
+        '641': BigInteger;
+        '642': BigInteger;
+        '643': BigInteger;
+        '644': BigInteger;
+        '645': BigInteger;
+        '646': BigInteger;
+        '647': BigInteger;
+        '648': BigInteger;
+        '649': BigInteger;
+        '650': BigInteger;
+        '651': BigInteger;
+        '652': BigInteger;
+        '653': BigInteger;
+        '654': BigInteger;
+        '655': BigInteger;
+        '656': BigInteger;
+        '657': BigInteger;
+        '658': BigInteger;
+        '659': BigInteger;
+        '660': BigInteger;
+        '661': BigInteger;
+        '662': BigInteger;
+        '663': BigInteger;
+        '664': BigInteger;
+        '665': BigInteger;
+        '666': BigInteger;
+        '667': BigInteger;
+        '668': BigInteger;
+        '669': BigInteger;
+        '670': BigInteger;
+        '671': BigInteger;
+        '672': BigInteger;
+        '673': BigInteger;
+        '674': BigInteger;
+        '675': BigInteger;
+        '676': BigInteger;
+        '677': BigInteger;
+        '678': BigInteger;
+        '679': BigInteger;
+        '680': BigInteger;
+        '681': BigInteger;
+        '682': BigInteger;
+        '683': BigInteger;
+        '684': BigInteger;
+        '685': BigInteger;
+        '686': BigInteger;
+        '687': BigInteger;
+        '688': BigInteger;
+        '689': BigInteger;
+        '690': BigInteger;
+        '691': BigInteger;
+        '692': BigInteger;
+        '693': BigInteger;
+        '694': BigInteger;
+        '695': BigInteger;
+        '696': BigInteger;
+        '697': BigInteger;
+        '698': BigInteger;
+        '699': BigInteger;
+        '700': BigInteger;
+        '701': BigInteger;
+        '702': BigInteger;
+        '703': BigInteger;
+        '704': BigInteger;
+        '705': BigInteger;
+        '706': BigInteger;
+        '707': BigInteger;
+        '708': BigInteger;
+        '709': BigInteger;
+        '710': BigInteger;
+        '711': BigInteger;
+        '712': BigInteger;
+        '713': BigInteger;
+        '714': BigInteger;
+        '715': BigInteger;
+        '716': BigInteger;
+        '717': BigInteger;
+        '718': BigInteger;
+        '719': BigInteger;
+        '720': BigInteger;
+        '721': BigInteger;
+        '722': BigInteger;
+        '723': BigInteger;
+        '724': BigInteger;
+        '725': BigInteger;
+        '726': BigInteger;
+        '727': BigInteger;
+        '728': BigInteger;
+        '729': BigInteger;
+        '730': BigInteger;
+        '731': BigInteger;
+        '732': BigInteger;
+        '733': BigInteger;
+        '734': BigInteger;
+        '735': BigInteger;
+        '736': BigInteger;
+        '737': BigInteger;
+        '738': BigInteger;
+        '739': BigInteger;
+        '740': BigInteger;
+        '741': BigInteger;
+        '742': BigInteger;
+        '743': BigInteger;
+        '744': BigInteger;
+        '745': BigInteger;
+        '746': BigInteger;
+        '747': BigInteger;
+        '748': BigInteger;
+        '749': BigInteger;
+        '750': BigInteger;
+        '751': BigInteger;
+        '752': BigInteger;
+        '753': BigInteger;
+        '754': BigInteger;
+        '755': BigInteger;
+        '756': BigInteger;
+        '757': BigInteger;
+        '758': BigInteger;
+        '759': BigInteger;
+        '760': BigInteger;
+        '761': BigInteger;
+        '762': BigInteger;
+        '763': BigInteger;
+        '764': BigInteger;
+        '765': BigInteger;
+        '766': BigInteger;
+        '767': BigInteger;
+        '768': BigInteger;
+        '769': BigInteger;
+        '770': BigInteger;
+        '771': BigInteger;
+        '772': BigInteger;
+        '773': BigInteger;
+        '774': BigInteger;
+        '775': BigInteger;
+        '776': BigInteger;
+        '777': BigInteger;
+        '778': BigInteger;
+        '779': BigInteger;
+        '780': BigInteger;
+        '781': BigInteger;
+        '782': BigInteger;
+        '783': BigInteger;
+        '784': BigInteger;
+        '785': BigInteger;
+        '786': BigInteger;
+        '787': BigInteger;
+        '788': BigInteger;
+        '789': BigInteger;
+        '790': BigInteger;
+        '791': BigInteger;
+        '792': BigInteger;
+        '793': BigInteger;
+        '794': BigInteger;
+        '795': BigInteger;
+        '796': BigInteger;
+        '797': BigInteger;
+        '798': BigInteger;
+        '799': BigInteger;
+        '800': BigInteger;
+        '801': BigInteger;
+        '802': BigInteger;
+        '803': BigInteger;
+        '804': BigInteger;
+        '805': BigInteger;
+        '806': BigInteger;
+        '807': BigInteger;
+        '808': BigInteger;
+        '809': BigInteger;
+        '810': BigInteger;
+        '811': BigInteger;
+        '812': BigInteger;
+        '813': BigInteger;
+        '814': BigInteger;
+        '815': BigInteger;
+        '816': BigInteger;
+        '817': BigInteger;
+        '818': BigInteger;
+        '819': BigInteger;
+        '820': BigInteger;
+        '821': BigInteger;
+        '822': BigInteger;
+        '823': BigInteger;
+        '824': BigInteger;
+        '825': BigInteger;
+        '826': BigInteger;
+        '827': BigInteger;
+        '828': BigInteger;
+        '829': BigInteger;
+        '830': BigInteger;
+        '831': BigInteger;
+        '832': BigInteger;
+        '833': BigInteger;
+        '834': BigInteger;
+        '835': BigInteger;
+        '836': BigInteger;
+        '837': BigInteger;
+        '838': BigInteger;
+        '839': BigInteger;
+        '840': BigInteger;
+        '841': BigInteger;
+        '842': BigInteger;
+        '843': BigInteger;
+        '844': BigInteger;
+        '845': BigInteger;
+        '846': BigInteger;
+        '847': BigInteger;
+        '848': BigInteger;
+        '849': BigInteger;
+        '850': BigInteger;
+        '851': BigInteger;
+        '852': BigInteger;
+        '853': BigInteger;
+        '854': BigInteger;
+        '855': BigInteger;
+        '856': BigInteger;
+        '857': BigInteger;
+        '858': BigInteger;
+        '859': BigInteger;
+        '860': BigInteger;
+        '861': BigInteger;
+        '862': BigInteger;
+        '863': BigInteger;
+        '864': BigInteger;
+        '865': BigInteger;
+        '866': BigInteger;
+        '867': BigInteger;
+        '868': BigInteger;
+        '869': BigInteger;
+        '870': BigInteger;
+        '871': BigInteger;
+        '872': BigInteger;
+        '873': BigInteger;
+        '874': BigInteger;
+        '875': BigInteger;
+        '876': BigInteger;
+        '877': BigInteger;
+        '878': BigInteger;
+        '879': BigInteger;
+        '880': BigInteger;
+        '881': BigInteger;
+        '882': BigInteger;
+        '883': BigInteger;
+        '884': BigInteger;
+        '885': BigInteger;
+        '886': BigInteger;
+        '887': BigInteger;
+        '888': BigInteger;
+        '889': BigInteger;
+        '890': BigInteger;
+        '891': BigInteger;
+        '892': BigInteger;
+        '893': BigInteger;
+        '894': BigInteger;
+        '895': BigInteger;
+        '896': BigInteger;
+        '897': BigInteger;
+        '898': BigInteger;
+        '899': BigInteger;
+        '900': BigInteger;
+        '901': BigInteger;
+        '902': BigInteger;
+        '903': BigInteger;
+        '904': BigInteger;
+        '905': BigInteger;
+        '906': BigInteger;
+        '907': BigInteger;
+        '908': BigInteger;
+        '909': BigInteger;
+        '910': BigInteger;
+        '911': BigInteger;
+        '912': BigInteger;
+        '913': BigInteger;
+        '914': BigInteger;
+        '915': BigInteger;
+        '916': BigInteger;
+        '917': BigInteger;
+        '918': BigInteger;
+        '919': BigInteger;
+        '920': BigInteger;
+        '921': BigInteger;
+        '922': BigInteger;
+        '923': BigInteger;
+        '924': BigInteger;
+        '925': BigInteger;
+        '926': BigInteger;
+        '927': BigInteger;
+        '928': BigInteger;
+        '929': BigInteger;
+        '930': BigInteger;
+        '931': BigInteger;
+        '932': BigInteger;
+        '933': BigInteger;
+        '934': BigInteger;
+        '935': BigInteger;
+        '936': BigInteger;
+        '937': BigInteger;
+        '938': BigInteger;
+        '939': BigInteger;
+        '940': BigInteger;
+        '941': BigInteger;
+        '942': BigInteger;
+        '943': BigInteger;
+        '944': BigInteger;
+        '945': BigInteger;
+        '946': BigInteger;
+        '947': BigInteger;
+        '948': BigInteger;
+        '949': BigInteger;
+        '950': BigInteger;
+        '951': BigInteger;
+        '952': BigInteger;
+        '953': BigInteger;
+        '954': BigInteger;
+        '955': BigInteger;
+        '956': BigInteger;
+        '957': BigInteger;
+        '958': BigInteger;
+        '959': BigInteger;
+        '960': BigInteger;
+        '961': BigInteger;
+        '962': BigInteger;
+        '963': BigInteger;
+        '964': BigInteger;
+        '965': BigInteger;
+        '966': BigInteger;
+        '967': BigInteger;
+        '968': BigInteger;
+        '969': BigInteger;
+        '970': BigInteger;
+        '971': BigInteger;
+        '972': BigInteger;
+        '973': BigInteger;
+        '974': BigInteger;
+        '975': BigInteger;
+        '976': BigInteger;
+        '977': BigInteger;
+        '978': BigInteger;
+        '979': BigInteger;
+        '980': BigInteger;
+        '981': BigInteger;
+        '982': BigInteger;
+        '983': BigInteger;
+        '984': BigInteger;
+        '985': BigInteger;
+        '986': BigInteger;
+        '987': BigInteger;
+        '988': BigInteger;
+        '989': BigInteger;
+        '990': BigInteger;
+        '991': BigInteger;
+        '992': BigInteger;
+        '993': BigInteger;
+        '994': BigInteger;
+        '995': BigInteger;
+        '996': BigInteger;
+        '997': BigInteger;
+        '998': BigInteger;
+        '999': BigInteger;
+    }
+}
diff --git a/node_modules/big-integer/BigInteger.js b/node_modules/big-integer/BigInteger.js
index ad29f97..9a65a5f 100644
--- a/node_modules/big-integer/BigInteger.js
+++ b/node_modules/big-integer/BigInteger.js
@@ -118,7 +118,7 @@ var bigInt = (function (undefined) {
     }
 
     BigInteger.prototype.add = function (v) {
-        var value, n = parseValue(v);
+        var n = parseValue(v);
         if (this.sign !== n.sign) {
             return this.subtract(n.negate());
         }
@@ -177,7 +177,7 @@ var bigInt = (function (undefined) {
     }
 
     function subtractAny(a, b, sign) {
-        var value, isSmall;
+        var value;
         if (compareAbs(a, b) >= 0) {
             value = subtract(a,b);
         } else {
@@ -326,7 +326,7 @@ var bigInt = (function (undefined) {
     }
 
     BigInteger.prototype.multiply = function (v) {
-        var value, n = parseValue(v),
+        var n = parseValue(v),
             a = this.value, b = n.value,
             sign = this.sign !== n.sign,
             abs;
@@ -467,6 +467,7 @@ var bigInt = (function (undefined) {
             guess, xlen, highx, highy, check;
         while (a_l) {
             part.unshift(a[--a_l]);
+            trim(part);
             if (compareAbs(part, b) < 0) {
                 result.push(0);
                 continue;
@@ -825,20 +826,24 @@ var bigInt = (function (undefined) {
     BigInteger.prototype.modInv = function (n) {
         var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
         while (!newR.equals(bigInt.zero)) {
-        	q = r.divide(newR);
-          lastT = t;
-          lastR = r;
-          t = newT;
-          r = newR;
-          newT = lastT.subtract(q.multiply(newT));
-          newR = lastR.subtract(q.multiply(newR));
+            q = r.divide(newR);
+            lastT = t;
+            lastR = r;
+            t = newT;
+            r = newR;
+            newT = lastT.subtract(q.multiply(newT));
+            newR = lastR.subtract(q.multiply(newR));
         }
         if (!r.equals(1)) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
         if (t.compare(0) === -1) {
-        	t = t.add(n);
+            t = t.add(n);
+        }
+        if (this.isNegative()) {
+            return t.negate();
         }
         return t;
-    }
+    };
+
     SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
 
     BigInteger.prototype.next = function () {
@@ -868,7 +873,7 @@ var bigInt = (function (undefined) {
     };
 
     var powersOfTwo = [1];
-    while (powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
+    while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
     var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
 
     function shift_isSmall(n) {
@@ -915,31 +920,29 @@ var bigInt = (function (undefined) {
         var xSign = x.isNegative(), ySign = y.isNegative();
         var xRem = xSign ? x.not() : x,
             yRem = ySign ? y.not() : y;
-        var xBits = [], yBits = [];
-        var xStop = false, yStop = false;
-        while (!xStop || !yStop) {
-            if (xRem.isZero()) { // virtual sign extension for simulating two's complement
-                xStop = true;
-                xBits.push(xSign ? 1 : 0);
+        var xDigit = 0, yDigit = 0;
+        var xDivMod = null, yDivMod = null;
+        var result = [];
+        while (!xRem.isZero() || !yRem.isZero()) {
+            xDivMod = divModAny(xRem, highestPower2);
+            xDigit = xDivMod[1].toJSNumber();
+            if (xSign) {
+                xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
             }
-            else if (xSign) xBits.push(xRem.isEven() ? 1 : 0); // two's complement for negative numbers
-            else xBits.push(xRem.isEven() ? 0 : 1);
 
-            if (yRem.isZero()) {
-                yStop = true;
-                yBits.push(ySign ? 1 : 0);
+            yDivMod = divModAny(yRem, highestPower2);
+            yDigit = yDivMod[1].toJSNumber();
+            if (ySign) {
+                yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
             }
-            else if (ySign) yBits.push(yRem.isEven() ? 1 : 0);
-            else yBits.push(yRem.isEven() ? 0 : 1);
 
-            xRem = xRem.over(2);
-            yRem = yRem.over(2);
+            xRem = xDivMod[0];
+            yRem = yDivMod[0];
+            result.push(fn(xDigit, yDigit));
         }
-        var result = [];
-        for (var i = 0; i < xBits.length; i++) result.push(fn(xBits[i], yBits[i]));
-        var sum = bigInt(result.pop()).negate().times(bigInt(2).pow(result.length));
-        while (result.length) {
-            sum = sum.add(bigInt(result.pop()).times(bigInt(2).pow(result.length)));
+        var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
+        for (var i = result.length - 1; i >= 0; i -= 1) {
+            sum = sum.multiply(highestPower2).add(bigInt(result[i]));
         }
         return sum;
     }
@@ -977,7 +980,7 @@ var bigInt = (function (undefined) {
         b = parseValue(b);
         return a.greater(b) ? a : b;
     }
-    function min(a,b) {
+    function min(a, b) {
         a = parseValue(a);
         b = parseValue(b);
         return a.lesser(b) ? a : b;
@@ -1018,8 +1021,8 @@ var bigInt = (function (undefined) {
         a = parseValue(a);
         b = parseValue(b);
         var low = min(a, b), high = max(a, b);
-        var range = high.subtract(low);
-        if (range.isSmall) return low.add(Math.round(Math.random() * range));
+        var range = high.subtract(low).add(1);
+        if (range.isSmall) return low.add(Math.floor(Math.random() * range));
         var length = range.value.length - 1;
         var result = [], restricted = true;
         for (var i = length; i >= 0; i--) {
@@ -1032,16 +1035,32 @@ var bigInt = (function (undefined) {
         return low.add(typeof result === "number" ? new SmallInteger(result) : new BigInteger(result, false));
     }
     var parseBase = function (text, base) {
-        var val = Integer[0], pow = Integer[1],
-            length = text.length;
+        var length = text.length;
+		var i;
+		var absBase = Math.abs(base);
+		for(var i = 0; i < length; i++) {
+			var c = text[i].toLowerCase();
+			if(c === "-") continue;
+			if(/[a-z0-9]/.test(c)) {
+			    if(/[0-9]/.test(c) && +c >= absBase) {
+					if(c === "1" && absBase === 1) continue;
+                    throw new Error(c + " is not a valid digit in base " + base + ".");
+				} else if(c.charCodeAt(0) - 87 >= absBase) {
+					throw new Error(c + " is not a valid digit in base " + base + ".");
+				}
+			}
+		}
         if (2 <= base && base <= 36) {
             if (length <= LOG_MAX_INT / Math.log(base)) {
+				var result = parseInt(text, base);
+				if(isNaN(result)) {
+					throw new Error(c + " is not a valid digit in base " + base + ".");
+				}
                 return new SmallInteger(parseInt(text, base));
             }
         }
         base = parseValue(base);
         var digits = [];
-        var i;
         var isNegative = text[0] === "-";
         for (i = isNegative ? 1 : 0; i < text.length; i++) {
             var c = text[i].toLowerCase(),
@@ -1055,13 +1074,17 @@ var bigInt = (function (undefined) {
             }
             else throw new Error(c + " is not a valid character");
         }
-        digits.reverse();
-        for (i = 0; i < digits.length; i++) {
+        return parseBaseFromArray(digits, base, isNegative);
+    };
+
+    function parseBaseFromArray(digits, base, isNegative) {
+        var val = Integer[0], pow = Integer[1], i;
+        for (i = digits.length - 1; i >= 0; i--) {
             val = val.add(digits[i].times(pow));
             pow = pow.times(base);
         }
         return isNegative ? val.negate() : val;
-    };
+    }
 
     function stringify(digit) {
         var v = digit.value;
@@ -1118,11 +1141,13 @@ var bigInt = (function (undefined) {
         var sign = this.sign ? "-" : "";
         return sign + str;
     };
+
     SmallInteger.prototype.toString = function (radix) {
         if (radix === undefined) radix = 10;
         if (radix != 10) return toBase(this, radix);
         return String(this.value);
     };
+    BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function() { return this.toString(); }
 
     BigInteger.prototype.valueOf = function () {
         return +this.toString();
@@ -1205,6 +1230,11 @@ var bigInt = (function (undefined) {
     Integer.lcm = lcm;
     Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger; };
     Integer.randBetween = randBetween;
+
+    Integer.fromArray = function (digits, base, isNegative) {
+        return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
+    };
+
     return Integer;
 })();
 
@@ -1212,3 +1242,10 @@ var bigInt = (function (undefined) {
 if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
     module.exports = bigInt;
 }
+
+//amd check
+if ( typeof define === "function" && define.amd ) {
+  define( "big-integer", [], function() {
+    return bigInt;
+  });
+}
diff --git a/node_modules/big-integer/BigInteger.min.js b/node_modules/big-integer/BigInteger.min.js
index 908d242..a868e44 100644
--- a/node_modules/big-integer/BigInteger.min.js
+++ b/node_modules/big-integer/BigInteger.min.js
@@ -1 +1 @@
-var bigInt=function(e){"use strict";function o(e,t){return typeof e=="undefined"?o[0]:typeof t!="undefined"?+t===10?Y(e):$(e,t):Y(e)}function u(e,t){this.value=e,this.sign=t,this.isSmall=!1}function a(e){this.value=e,this.sign=e<0,this.isSmall=!0}function f(e){return-r<e&&e<r}function l(e){return e<1e7?[e]:e<1e14?[e%1e7,Math.floor(e/1e7)]:[e%1e7,Math.floor(e/1e7)%1e7,Math.floor(e/1e14)]}function c(e){h(e);var n=e.length;if(n<4&&_(e,i)<0)switch(n){case 0:return 0;case 1:return e[0];case 2 [...]
\ No newline at end of file
+var bigInt=function(undefined){"use strict";var BASE=1e7,LOG_BASE=7,MAX_INT=9007199254740992,MAX_INT_ARR=smallToArray(MAX_INT),LOG_MAX_INT=Math.log(MAX_INT);function Integer(v,radix){if(typeof v==="undefined")return Integer[0];if(typeof radix!=="undefined")return+radix===10?parseValue(v):parseBase(v,radix);return parseValue(v)}function BigInteger(value,sign){this.value=value;this.sign=sign;this.isSmall=false}BigInteger.prototype=Object.create(Integer.prototype);function SmallInteger(valu [...]
\ No newline at end of file
diff --git a/node_modules/big-integer/README.md b/node_modules/big-integer/README.md
index 51eb657..5824f7e 100644
--- a/node_modules/big-integer/README.md
+++ b/node_modules/big-integer/README.md
@@ -211,7 +211,7 @@ Returns `true` if the number is prime, `false` otherwise.
 
 #### `isProbablePrime([iterations])`
 
-Returns `true` if the number is very likely to be positive, `false` otherwise.
+Returns `true` if the number is very likely to be prime, `false` otherwise.
 Argument is optional and determines the amount of iterations of the test (default: `5`). The more iterations, the lower chance of getting a false positive.
 This uses the [Fermat primality test](https://en.wikipedia.org/wiki/Fermat_primality_test).
 
@@ -421,6 +421,13 @@ Performs the bitwise XOR operation. The operands are treated as if they were rep
  
 ### Static Methods
 
+#### `fromArray(digits, base = 10, isNegative?)`
+
+Constructs a bigInt from an array of digits in base `base`. The optional `isNegative` flag will make the number negative.
+
+ - `bigInt.fromArray([1, 2, 3, 4, 5], 10)` => `12345`
+ - `bigInt.fromArray([1, 0, 0], 2, true)` => `-4`
+
 #### `gcd(a, b)`
 
 Finds the greatest common denominator of `a` and `b`.
@@ -510,4 +517,4 @@ There are performance benchmarks that can be viewed from the `benchmarks/index.h
 
 ## License
 
-This project is public domain. For more details, read about the [Unlicense](http://unlicense.org/).
\ No newline at end of file
+This project is public domain. For more details, read about the [Unlicense](http://unlicense.org/).
diff --git a/node_modules/big-integer/bower.json b/node_modules/big-integer/bower.json
index c7c7291..22dc58f 100644
--- a/node_modules/big-integer/bower.json
+++ b/node_modules/big-integer/bower.json
@@ -24,7 +24,6 @@
     "bower_components",
     "test",
     "coverage",
-    "spec",
     "tests"
   ]
 }
diff --git a/node_modules/big-integer/package.json b/node_modules/big-integer/package.json
index b6ab5a2..ae81359 100644
--- a/node_modules/big-integer/package.json
+++ b/node_modules/big-integer/package.json
@@ -1,50 +1,32 @@
 {
   "_args": [
     [
-      {
-        "raw": "big-integer@^1.6.7",
-        "scope": null,
-        "escapedName": "big-integer",
-        "name": "big-integer",
-        "rawSpec": "^1.6.7",
-        "spec": ">=1.6.7 <2.0.0",
-        "type": "range"
-      },
-      "/Users/kotikov.vladimir/repos/cordova/cordova-windows/node_modules/bplist-parser"
+      "big-integer@1.6.26",
+      "/Users/nikitamatrosov/cordova/cordova-windows"
     ]
   ],
-  "_from": "big-integer@>=1.6.7 <2.0.0",
-  "_id": "big-integer@1.6.17",
-  "_inCache": true,
+  "_from": "big-integer@1.6.26",
+  "_id": "big-integer@1.6.26",
+  "_inBundle": false,
+  "_integrity": "sha1-OvFnL6Ytry1eyvrPblqg0l4Cwcg=",
   "_location": "/big-integer",
-  "_nodeVersion": "4.4.5",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/big-integer-1.6.17.tgz_1478721202721_0.8068355675786734"
-  },
-  "_npmUser": {
-    "name": "peterolson",
-    "email": "peter.e.c.olson+npm@gmail.com"
-  },
-  "_npmVersion": "2.15.5",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "big-integer@^1.6.7",
-    "scope": null,
-    "escapedName": "big-integer",
+    "type": "version",
+    "registry": true,
+    "raw": "big-integer@1.6.26",
     "name": "big-integer",
-    "rawSpec": "^1.6.7",
-    "spec": ">=1.6.7 <2.0.0",
-    "type": "range"
+    "escapedName": "big-integer",
+    "rawSpec": "1.6.26",
+    "saveSpec": null,
+    "fetchSpec": "1.6.26"
   },
   "_requiredBy": [
     "/bplist-parser"
   ],
-  "_resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.17.tgz",
-  "_shasum": "f0dcf5109a949e42a993ee3e8fb2070452817b51",
-  "_shrinkwrap": null,
-  "_spec": "big-integer@^1.6.7",
-  "_where": "/Users/kotikov.vladimir/repos/cordova/cordova-windows/node_modules/bplist-parser",
+  "_resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.26.tgz",
+  "_spec": "1.6.26",
+  "_where": "/Users/nikitamatrosov/cordova/cordova-windows",
   "author": {
     "name": "Peter Olson",
     "email": "peter.e.c.olson+npm@gmail.com"
@@ -54,26 +36,24 @@
     "url": "https://github.com/peterolson/BigInteger.js/issues"
   },
   "contributors": [],
-  "dependencies": {},
   "description": "An arbitrary length integer library for Javascript",
   "devDependencies": {
+    "@types/lodash": "^4.14.64",
+    "@types/node": "^7.0.22",
     "coveralls": "^2.11.4",
     "jasmine": "2.1.x",
     "jasmine-core": "^2.3.4",
     "karma": "^0.13.3",
     "karma-coverage": "^0.4.2",
     "karma-jasmine": "^0.3.6",
-    "karma-phantomjs-launcher": "~0.1"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "f0dcf5109a949e42a993ee3e8fb2070452817b51",
-    "tarball": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.17.tgz"
+    "karma-phantomjs-launcher": "^1.0.4",
+    "lodash": "^4.17.4",
+    "typescript": "^2.3.3",
+    "uglifyjs": "^2.4.10"
   },
   "engines": {
     "node": ">=0.6"
   },
-  "gitHead": "d25d0bfcd96f31001ec8572c8d01de4770d99e63",
   "homepage": "https://github.com/peterolson/BigInteger.js#readme",
   "keywords": [
     "math",
@@ -88,21 +68,15 @@
   ],
   "license": "Unlicense",
   "main": "./BigInteger",
-  "maintainers": [
-    {
-      "name": "peterolson",
-      "email": "peter.e.c.olson+npm@gmail.com"
-    }
-  ],
   "name": "big-integer",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+ssh://git@github.com/peterolson/BigInteger.js.git"
   },
   "scripts": {
-    "test": "karma start my.conf.js"
+    "minify": "uglifyjs BigInteger.js -o BigInteger.min.js",
+    "test": "tsc && node_modules/.bin/karma start my.conf.js && node spec/tsDefinitions.js"
   },
-  "version": "1.6.17"
+  "typings": "./BigInteger.d.ts",
+  "version": "1.6.26"
 }
diff --git a/node_modules/big-integer/tsconfig.json b/node_modules/big-integer/tsconfig.json
new file mode 100644
index 0000000..62636e8
--- /dev/null
+++ b/node_modules/big-integer/tsconfig.json
@@ -0,0 +1,25 @@
+{
+    "compilerOptions": {
+        "module": "commonjs",
+        "lib": [
+            "es6"
+        ],
+        "noImplicitAny": true,
+        "noImplicitThis": true,
+        "strictNullChecks": false,
+        "baseUrl": "./",
+        "moduleResolution": "node",
+        "allowJs": true,
+        "typeRoots": [
+            "./"
+        ],
+        "types": [
+            "node"
+        ],
+        "forceConsistentCasingInFileNames": true
+    },
+    "files": [
+        "BigInteger.d.ts",
+        "spec/tsDefinitions.ts"
+    ]
+}
\ No newline at end of file
diff --git a/node_modules/cordova-common/.eslintignore b/node_modules/cordova-common/.eslintignore
new file mode 100644
index 0000000..161d0c6
--- /dev/null
+++ b/node_modules/cordova-common/.eslintignore
@@ -0,0 +1 @@
+spec/fixtures/*
\ No newline at end of file
diff --git a/node_modules/cordova-common/.eslintrc.yml b/node_modules/cordova-common/.eslintrc.yml
new file mode 100644
index 0000000..7701c82
--- /dev/null
+++ b/node_modules/cordova-common/.eslintrc.yml
@@ -0,0 +1,11 @@
+root: true
+extends: semistandard
+rules:
+  indent:
+    - error
+    - 4
+  camelcase: off
+  padded-blocks: off
+  operator-linebreak: off
+  no-throw-literal: off
+  
\ No newline at end of file
diff --git a/node_modules/cordova-common/.jshintignore b/node_modules/cordova-common/.jshintignore
deleted file mode 100644
index d606f61..0000000
--- a/node_modules/cordova-common/.jshintignore
+++ /dev/null
@@ -1 +0,0 @@
-spec/fixtures/*
diff --git a/node_modules/cordova-common/.npmignore b/node_modules/cordova-common/.npmignore
deleted file mode 100644
index 5d14118..0000000
--- a/node_modules/cordova-common/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-spec
-coverage
diff --git a/node_modules/cordova-common/.ratignore b/node_modules/cordova-common/.ratignore
index d9f5e52..f107416 100644
--- a/node_modules/cordova-common/.ratignore
+++ b/node_modules/cordova-common/.ratignore
@@ -1,3 +1,4 @@
 fixtures
 coverage
 jasmine.json
+appveyor.yml
diff --git a/node_modules/cordova-common/.travis.yml b/node_modules/cordova-common/.travis.yml
new file mode 100644
index 0000000..4592c3e
--- /dev/null
+++ b/node_modules/cordova-common/.travis.yml
@@ -0,0 +1,16 @@
+language: node_js
+sudo: false
+git:
+  depth: 10
+node_js:
+  - "4"
+  - "6"
+  - "8"
+install:
+  - npm install
+  - npm install -g codecov
+script:
+  - npm test
+  - npm run cover
+after_script:
+  - codecov
diff --git a/node_modules/cordova-common/README.md b/node_modules/cordova-common/README.md
index c5dcfd5..5659c57 100644
--- a/node_modules/cordova-common/README.md
+++ b/node_modules/cordova-common/README.md
@@ -19,6 +19,10 @@
 #
 -->
 
+[![Build status](https://ci.appveyor.com/api/projects/status/wxkmo0jalsr8gane?svg=true)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/cordova-common/branch/master)
+[![Build Status](https://travis-ci.org/apache/cordova-common.svg?branch=master)](https://travis-ci.org/apache/cordova-common)
+[![NPM](https://nodei.co/npm/cordova-common.png)](https://nodei.co/npm/cordova-common/)
+
 # cordova-common
 Expoeses shared functionality used by [cordova-lib](https://github.com/apache/cordova-lib/) and Cordova platforms.
 ## Exposed APIs
diff --git a/node_modules/cordova-common/RELEASENOTES.md b/node_modules/cordova-common/RELEASENOTES.md
index 3aca768..5dda362 100644
--- a/node_modules/cordova-common/RELEASENOTES.md
+++ b/node_modules/cordova-common/RELEASENOTES.md
@@ -20,6 +20,42 @@
 -->
 # Cordova-common Release Notes
 
+### 2.2.1 (Dec 14, 2017)
+* [CB-13674](https://issues.apache.org/jira/browse/CB-13674): updated dependencies
+
+### 2.2.0 (Nov 22, 2017)
+* [CB-13471](https://issues.apache.org/jira/browse/CB-13471) File Provider fix belongs in cordova-common 
+* [CB-11244](https://issues.apache.org/jira/browse/CB-11244) Spot fix for upcoming `cordova-android@7` changes. https://github.com/apache/cordova-android/pull/389
+
+### 2.1.1 (Oct 04, 2017)
+* [CB-13145](https://issues.apache.org/jira/browse/CB-13145) added `getFrameworks` to unit tests
+* [CB-13145](https://issues.apache.org/jira/browse/CB-13145) added variable replacing to framework tag
+
+### 2.1.0 (August 30, 2017)
+* [CB-13145](https://issues.apache.org/jira/browse/CB-13145) added variable replacing to `framework` tag
+* [CB-13211](https://issues.apache.org/jira/browse/CB-13211) Add `allows-arbitrary-loads-for-media` attribute parsing for `getAccesses`
+* [CB-11968](https://issues.apache.org/jira/browse/CB-11968) Added support for `<config-file>` in `config.xml`
+* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) set up `eslint` and removed `jshint`
+* [CB-12785](https://issues.apache.org/jira/browse/CB-12785) added `.gitignore`, `travis`, and `appveyor` support
+* [CB-12250](https://issues.apache.org/jira/browse/CB-12250) & [CB-12409](https://issues.apache.org/jira/browse/CB-12409) *iOS*: Fix bug with escaping properties from `plist` file
+* [CB-12762](https://issues.apache.org/jira/browse/CB-12762) updated `common`, `fetch`, and `serve` `pkgJson` to point `pkgJson` repo items to github mirrors
+* [CB-12766](https://issues.apache.org/jira/browse/CB-12766) Consistently write `JSON` with 2 spaces indentation
+
+### 2.0.3 (May 02, 2017)
+* [CB-8978](https://issues.apache.org/jira/browse/CB-8978) Add option to get `resource-file` from `root`
+* [CB-11908](https://issues.apache.org/jira/browse/CB-11908) Add tests for `edit-config` in `config.xml`
+* [CB-12665](https://issues.apache.org/jira/browse/CB-12665) removed `enginestrict` since it is deprecated
+
+### 2.0.2 (Apr 14, 2017)
+* [CB-11233](https://issues.apache.org/jira/browse/CB-11233) - Support installing frameworks into 'Embedded Binaries' section of the Xcode project
+* [CB-10438](https://issues.apache.org/jira/browse/CB-10438) - Install correct dependency version. Removed shell.remove, added pkg.json to dependency tests 1-3, and updated install.js (.replace) to fix tests in uninstall.spec.js and update to workw with jasmine 2.0
+* [CB-11120](https://issues.apache.org/jira/browse/CB-11120) - Allow short/display name in config.xml
+* [CB-11346](https://issues.apache.org/jira/browse/CB-11346) - Remove known platforms check
+* [CB-11977](https://issues.apache.org/jira/browse/CB-11977) - updated engines and enginescript for common, fetch, and serve
+
+### 2.0.1 (Mar 09, 2017)
+* [CB-12557](https://issues.apache.org/jira/browse/CB-12557) add both stdout and stderr properties to the error object passed to superspawn reject handler.
+
 ### 2.0.0 (Jan 17, 2017)
 * [CB-8978](https://issues.apache.org/jira/browse/CB-8978) Add `resource-file` parsing to `config.xml`
 * [CB-12018](https://issues.apache.org/jira/browse/CB-12018): updated `jshint` and updated tests to work with `jasmine@2` instead of `jasmine-node`
diff --git a/node_modules/cordova-common/appveyor.yml b/node_modules/cordova-common/appveyor.yml
new file mode 100644
index 0000000..ffe5194
--- /dev/null
+++ b/node_modules/cordova-common/appveyor.yml
@@ -0,0 +1,19 @@
+# appveyor file
+# http://www.appveyor.com/docs/appveyor-yml
+
+environment:
+  matrix:
+  - nodejs_version: "4"
+  - nodejs_version: "6"
+  - nodejs_version: "8"
+  
+install:
+  - ps: Install-Product node $env:nodejs_version
+  - npm install
+
+build: off
+
+test_script:
+  - node --version
+  - npm --version
+  - npm test
diff --git a/node_modules/cordova-common/package.json b/node_modules/cordova-common/package.json
index b11116a..0ed8a8e 100644
--- a/node_modules/cordova-common/package.json
+++ b/node_modules/cordova-common/package.json
@@ -1,51 +1,28 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "cordova-common@*",
-        "scope": null,
-        "escapedName": "cordova-common",
-        "name": "cordova-common",
-        "rawSpec": "*",
-        "spec": "*",
-        "type": "range"
-      },
-      "/Users/kotikov.vladimir/repos/cordova/cordova-windows"
-    ]
-  ],
-  "_from": "cordova-common@*",
-  "_id": "cordova-common@2.0.0",
-  "_inCache": true,
+  "_from": "cordova-common@2.2.1",
+  "_id": "cordova-common@2.2.1",
+  "_inBundle": false,
+  "_integrity": "sha1-cAm8WRcpyqcoWliM/Wp7VM2DTww=",
   "_location": "/cordova-common",
-  "_nodeVersion": "6.6.0",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/cordova-common-2.0.0.tgz_1485216738805_0.9605799505952746"
-  },
-  "_npmUser": {
-    "name": "stevegill",
-    "email": "stevengill97@gmail.com"
-  },
-  "_npmVersion": "4.1.1",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "cordova-common@*",
-    "scope": null,
-    "escapedName": "cordova-common",
+    "type": "version",
+    "registry": true,
+    "raw": "cordova-common@2.2.1",
     "name": "cordova-common",
-    "rawSpec": "*",
-    "spec": "*",
-    "type": "range"
+    "escapedName": "cordova-common",
+    "rawSpec": "2.2.1",
+    "saveSpec": null,
+    "fetchSpec": "2.2.1"
   },
   "_requiredBy": [
     "#USER",
     "/"
   ],
-  "_resolved": "https://registry.npmjs.org/cordova-common/-/cordova-common-2.0.0.tgz",
-  "_shasum": "125097eb4b50b7353cec226ed21649192293ae97",
-  "_shrinkwrap": null,
-  "_spec": "cordova-common@*",
-  "_where": "/Users/kotikov.vladimir/repos/cordova/cordova-windows",
+  "_resolved": "https://registry.npmjs.org/cordova-common/-/cordova-common-2.2.1.tgz",
+  "_shasum": "7009bc591729caa7285a588cfd6a7b54cd834f0c",
+  "_spec": "cordova-common@2.2.1",
+  "_where": "/Users/nikitamatrosov/cordova/cordova-windows",
   "author": {
     "name": "Apache Software Foundation"
   },
@@ -53,12 +30,13 @@
     "url": "https://issues.apache.org/jira/browse/CB",
     "email": "dev@cordova.apache.org"
   },
+  "bundleDependencies": false,
   "contributors": [],
   "dependencies": {
     "ansi": "^0.3.1",
     "bplist-parser": "^0.1.0",
     "cordova-registry-mapper": "^1.1.8",
-    "elementtree": "^0.1.6",
+    "elementtree": "0.1.6",
     "glob": "^5.0.13",
     "minimatch": "^3.0.0",
     "osenv": "^0.1.3",
@@ -69,66 +47,37 @@
     "underscore": "^1.8.3",
     "unorm": "^1.3.3"
   },
+  "deprecated": false,
   "description": "Apache Cordova tools and platforms shared routines",
   "devDependencies": {
+    "eslint": "^4.0.0",
+    "eslint-config-semistandard": "^11.0.0",
+    "eslint-config-standard": "^10.2.1",
+    "eslint-plugin-import": "^2.3.0",
+    "eslint-plugin-node": "^5.0.0",
+    "eslint-plugin-promise": "^3.5.0",
+    "eslint-plugin-standard": "^3.0.1",
     "istanbul": "^0.4.5",
     "jasmine": "^2.5.2",
-    "jshint": "^2.8.0",
     "promise-matchers": "^0.9.6",
     "rewire": "^2.5.1"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "125097eb4b50b7353cec226ed21649192293ae97",
-    "tarball": "https://registry.npmjs.org/cordova-common/-/cordova-common-2.0.0.tgz"
-  },
   "engines": {
-    "node": ">=0.9.9"
+    "node": ">=4.0.0"
   },
+  "homepage": "https://github.com/apache/cordova-lib#readme",
   "license": "Apache-2.0",
   "main": "cordova-common.js",
-  "maintainers": [
-    {
-      "name": "bowserj",
-      "email": "bowserj@apache.org"
-    },
-    {
-      "name": "filmaj",
-      "email": "maj.fil@gmail.com"
-    },
-    {
-      "name": "kotikov.vladimir",
-      "email": "kotikov.vladimir@gmail.com"
-    },
-    {
-      "name": "purplecabbage",
-      "email": "purplecabbage@gmail.com"
-    },
-    {
-      "name": "shazron",
-      "email": "shazron@gmail.com"
-    },
-    {
-      "name": "stevegill",
-      "email": "stevengill97@gmail.com"
-    },
-    {
-      "name": "timbarham",
-      "email": "npmjs@barhams.info"
-    }
-  ],
   "name": "cordova-common",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
-    "url": "git://git-wip-us.apache.org/repos/asf/cordova-common.git"
+    "url": "git+https://github.com/apache/cordova-lib.git"
   },
   "scripts": {
     "cover": "istanbul cover --root src --print detail jasmine",
-    "jasmine": "jasmine --captureExceptions --color",
-    "jshint": "jshint src && jshint spec",
-    "test": "npm run jshint && npm run jasmine"
+    "eslint": "eslint src && eslint spec",
+    "jasmine": "jasmine JASMINE_CONFIG_PATH=spec/support/jasmine.json",
+    "test": "npm run eslint && npm run jasmine"
   },
-  "version": "2.0.0"
+  "version": "2.2.1"
 }
diff --git a/node_modules/cordova-common/src/.jshintrc b/node_modules/cordova-common/src/.jshintrc
deleted file mode 100644
index 89a121c..0000000
--- a/node_modules/cordova-common/src/.jshintrc
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "node": true
-  , "bitwise": true
-  , "undef": true
-  , "trailing": true
-  , "quotmark": true
-  , "indent": 4
-  , "unused": "vars"
-  , "latedef": "nofunc"
-}
diff --git a/node_modules/cordova-common/src/ActionStack.js b/node_modules/cordova-common/src/ActionStack.js
index 5ef6f84..6983c5c 100644
--- a/node_modules/cordova-common/src/ActionStack.js
+++ b/node_modules/cordova-common/src/ActionStack.js
@@ -19,32 +19,32 @@
 
 /* jshint quotmark:false */
 
-var events = require('./events'),
-    Q = require('q');
+var events = require('./events');
+var Q = require('q');
 
-function ActionStack() {
+function ActionStack () {
     this.stack = [];
     this.completed = [];
 }
 
 ActionStack.prototype = {
-    createAction:function(handler, action_params, reverter, revert_params) {
+    createAction: function (handler, action_params, reverter, revert_params) {
         return {
-            handler:{
-                run:handler,
-                params:action_params
+            handler: {
+                run: handler,
+                params: action_params
             },
-            reverter:{
-                run:reverter,
-                params:revert_params
+            reverter: {
+                run: reverter,
+                params: revert_params
             }
         };
     },
-    push:function(tx) {
+    push: function (tx) {
         this.stack.push(tx);
     },
     // Returns a promise.
-    process:function(platform) {
+    process: function (platform) {
         events.emit('verbose', 'Beginning processing of action stack for ' + platform + ' project...');
 
         while (this.stack.length) {
@@ -54,19 +54,19 @@ ActionStack.prototype = {
 
             try {
                 handler.apply(null, action_params);
-            } catch(e) {
+            } catch (e) {
                 events.emit('warn', 'Error during processing of action! Attempting to revert...');
                 this.stack.unshift(action);
                 var issue = 'Uh oh!\n';
                 // revert completed tasks
-                while(this.completed.length) {
+                while (this.completed.length) {
                     var undo = this.completed.shift();
                     var revert = undo.reverter.run;
                     var revert_params = undo.reverter.params;
 
                     try {
                         revert.apply(null, revert_params);
-                    } catch(err) {
+                    } catch (err) {
                         events.emit('warn', 'Error during reversion of action! We probably really messed up your project now, sorry! D:');
                         issue += 'A reversion action failed: ' + err.message + '\n';
                     }
diff --git a/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js b/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js
index 4a58132..1780d25 100644
--- a/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js
+++ b/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js
@@ -15,7 +15,7 @@
     KIND, either express or implied.  See the License for the
     specific language governing permissions and limitations
     under the License.
-*/ 
+*/
 
 /*
  * This module deals with shared configuration / dependency "stuff". That is:
@@ -29,19 +29,17 @@
  * reference counts.
  */
 
-/* jshint sub:true */
-
-var path = require('path'),
-    et   = require('elementtree'),
-    ConfigKeeper = require('./ConfigKeeper'),
-    CordovaLogger = require('../CordovaLogger');
+var path = require('path');
+var et = require('elementtree');
+var ConfigKeeper = require('./ConfigKeeper');
+var events = require('../events');
 
 var mungeutil = require('./munge-util');
 var xml_helpers = require('../util/xml-helpers');
 
 exports.PlatformMunger = PlatformMunger;
 
-exports.process = function(plugins_dir, project_dir, platform, platformJson, pluginInfoProvider) {
+exports.process = function (plugins_dir, project_dir, platform, platformJson, pluginInfoProvider) {
     var munger = new PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider);
     munger.process(plugins_dir);
     munger.save_all();
@@ -53,7 +51,7 @@ exports.process = function(plugins_dir, project_dir, platform, platformJson, plu
 * Can deal with config file of a single project.
 * Parsed config files are cached in a ConfigKeeper object.
 ******************************************************************************/
-function PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider) {
+function PlatformMunger (platform, project_dir, platformJson, pluginInfoProvider) {
     this.platform = platform;
     this.project_dir = project_dir;
     this.config_keeper = new ConfigKeeper(project_dir);
@@ -63,7 +61,7 @@ function PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider)
 
 // Write out all unsaved files.
 PlatformMunger.prototype.save_all = PlatformMunger_save_all;
-function PlatformMunger_save_all() {
+function PlatformMunger_save_all () {
     this.config_keeper.save_all();
     this.platformJson.save();
 }
@@ -71,7 +69,7 @@ function PlatformMunger_save_all() {
 // Apply a munge object to a single config file.
 // The remove parameter tells whether to add the change or remove it.
 PlatformMunger.prototype.apply_file_munge = PlatformMunger_apply_file_munge;
-function PlatformMunger_apply_file_munge(file, munge, remove) {
+function PlatformMunger_apply_file_munge (file, munge, remove) {
     var self = this;
 
     for (var selector in munge.parents) {
@@ -86,16 +84,15 @@ function PlatformMunger_apply_file_munge(file, munge, remove) {
     }
 }
 
-
 PlatformMunger.prototype.remove_plugin_changes = remove_plugin_changes;
-function remove_plugin_changes(pluginInfo, is_top_level) {
+function remove_plugin_changes (pluginInfo, is_top_level) {
     var self = this;
     var platform_config = self.platformJson.root;
     var plugin_vars = is_top_level ?
         platform_config.installed_plugins[pluginInfo.id] :
         platform_config.dependent_plugins[pluginInfo.id];
     var edit_config_changes = null;
-    if(pluginInfo.getEditConfigs) {
+    if (pluginInfo.getEditConfigs) {
         edit_config_changes = pluginInfo.getEditConfigs(self.platform);
     }
 
@@ -114,14 +111,13 @@ function remove_plugin_changes(pluginInfo, is_top_level) {
     return self;
 }
 
-
 PlatformMunger.prototype.add_plugin_changes = add_plugin_changes;
-function add_plugin_changes(pluginInfo, plugin_vars, is_top_level, should_increment, plugin_force) {
+function add_plugin_changes (pluginInfo, plugin_vars, is_top_level, should_increment, plugin_force) {
     var self = this;
     var platform_config = self.platformJson.root;
 
     var edit_config_changes = null;
-    if(pluginInfo.getEditConfigs) {
+    if (pluginInfo.getEditConfigs) {
         edit_config_changes = pluginInfo.getEditConfigs(self.platform);
     }
 
@@ -130,8 +126,7 @@ function add_plugin_changes(pluginInfo, plugin_vars, is_top_level, should_increm
     if (!edit_config_changes || edit_config_changes.length === 0) {
         // get config munge, aka how should this plugin change various config files
         config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars);
-    }
-    else {
+    } else {
         var isConflictingInfo = is_conflicting(edit_config_changes, platform_config.config_munge, self, plugin_force);
 
         if (isConflictingInfo.conflictWithConfigxml) {
@@ -139,7 +134,7 @@ function add_plugin_changes(pluginInfo, plugin_vars, is_top_level, should_increm
                 ' cannot be added. <edit-config> changes in this plugin conflicts with <edit-config> changes in config.xml. Conflicts must be resolved before plugin can be added.');
         }
         if (plugin_force) {
-            CordovaLogger.get().log(CordovaLogger.WARN, '--force is used. edit-config will overwrite conflicts if any. Conflicting plugins may not work as expected.');
+            events.emit('warn', '--force is used. edit-config will overwrite conflicts if any. Conflicting plugins may not work as expected.');
 
             // remove conflicting munges
             var conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.conflictingMunge);
@@ -149,13 +144,11 @@ function add_plugin_changes(pluginInfo, plugin_vars, is_top_level, should_increm
 
             // force add new munges
             config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
-        }
-        else if(isConflictingInfo.conflictFound) {
+        } else if (isConflictingInfo.conflictFound) {
             throw new Error('There was a conflict trying to modify attributes with <edit-config> in plugin ' + pluginInfo.id +
             '. The conflicting plugin, ' + isConflictingInfo.conflictingPlugin + ', already modified the same attributes. The conflict must be resolved before ' +
             pluginInfo.id + ' can be added. You may use --force to add the plugin and overwrite the conflicting attributes.');
-        }
-        else {
+        } else {
             // no conflicts, will handle edit-config
             config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars, edit_config_changes);
         }
@@ -168,27 +161,32 @@ function add_plugin_changes(pluginInfo, plugin_vars, is_top_level, should_increm
     return self;
 }
 
-
 // Handle edit-config changes from config.xml
 PlatformMunger.prototype.add_config_changes = add_config_changes;
-function add_config_changes(config, should_increment) {
+function add_config_changes (config, should_increment) {
     var self = this;
     var platform_config = self.platformJson.root;
 
     var config_munge;
-    var edit_config_changes = null;
-    if(config.getEditConfigs) {
-        edit_config_changes = config.getEditConfigs(self.platform);
+    var changes = [];
+
+    if (config.getEditConfigs) {
+        var edit_config_changes = config.getEditConfigs(self.platform);
+        if (edit_config_changes) {
+            changes = changes.concat(edit_config_changes);
+        }
     }
 
-    if (!edit_config_changes || edit_config_changes.length === 0) {
-        // There are no edit-config changes to add, return here
-        return self;
+    if (config.getConfigFiles) {
+        var config_files_changes = config.getConfigFiles(self.platform);
+        if (config_files_changes) {
+            changes = changes.concat(config_files_changes);
+        }
     }
-    else {
-        var isConflictingInfo = is_conflicting(edit_config_changes, platform_config.config_munge, self, true /*always force overwrite other edit-config*/);
 
-        if(isConflictingInfo.conflictFound) {
+    if (changes && changes.length > 0) {
+        var isConflictingInfo = is_conflicting(changes, platform_config.config_munge, self, true /* always force overwrite other edit-config */);
+        if (isConflictingInfo.conflictFound) {
             var conflict_munge;
             var conflict_file;
 
@@ -200,7 +198,7 @@ function add_config_changes(config, should_increment) {
                 }
             }
             if (Object.keys(isConflictingInfo.conflictingMunge.files).length !== 0) {
-                CordovaLogger.get().log(CordovaLogger.WARN, 'Conflict found, edit-config changes from config.xml will overwrite plugin.xml changes');
+                events.emit('warn', 'Conflict found, edit-config changes from config.xml will overwrite plugin.xml changes');
 
                 // remove conflicting plugin.xml munges
                 conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.conflictingMunge);
@@ -209,17 +207,17 @@ function add_config_changes(config, should_increment) {
                 }
             }
         }
-        // Add config.xml edit-config munges
-        config_munge = self.generate_config_xml_munge(config, edit_config_changes, 'config.xml');
     }
 
+    // Add config.xml edit-config and config-file munges
+    config_munge = self.generate_config_xml_munge(config, changes, 'config.xml');
     self = munge_helper(should_increment, self, platform_config, config_munge);
 
     // Move to installed/dependent_plugins
     return self;
 }
 
-function munge_helper(should_increment, self, platform_config, config_munge) {
+function munge_helper (should_increment, self, platform_config, config_munge) {
     // global munge looks at all changes to config files
 
     // TODO: The should_increment param is only used by cordova-cli and is going away soon.
@@ -241,11 +239,10 @@ function munge_helper(should_increment, self, platform_config, config_munge) {
     return self;
 }
 
-
 // Load the global munge from platform json and apply all of it.
 // Used by cordova prepare to re-generate some config file from platform
 // defaults and the global munge.
-PlatformMunger.prototype.reapply_global_munge = reapply_global_munge ;
+PlatformMunger.prototype.reapply_global_munge = reapply_global_munge;
 function reapply_global_munge () {
     var self = this;
 
@@ -261,58 +258,56 @@ function reapply_global_munge () {
 // generate_plugin_config_munge
 // Generate the munge object from config.xml
 PlatformMunger.prototype.generate_config_xml_munge = generate_config_xml_munge;
-function generate_config_xml_munge(config, edit_config_changes, type) {
-
+function generate_config_xml_munge (config, config_changes, type) {
     var munge = { files: {} };
-    var changes = edit_config_changes;
     var id;
 
-    if(!changes) {
+    if (!config_changes) {
         return munge;
     }
 
     if (type === 'config.xml') {
         id = type;
-    }
-    else {
+    } else {
         id = config.id;
     }
 
-    changes.forEach(function(change) {
-        change.xmls.forEach(function(xml) {
+    config_changes.forEach(function (change) {
+        change.xmls.forEach(function (xml) {
             // 1. stringify each xml
-            var stringified = (new et.ElementTree(xml)).write({xml_declaration:false});
+            var stringified = (new et.ElementTree(xml)).write({xml_declaration: false});
             // 2. add into munge
             if (change.mode) {
                 mungeutil.deep_add(munge, change.file, change.target, { xml: stringified, count: 1, mode: change.mode, id: id });
+            } else {
+                mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after });
             }
         });
     });
     return munge;
 }
 
-
 // generate_plugin_config_munge
 // Generate the munge object from plugin.xml + vars
 PlatformMunger.prototype.generate_plugin_config_munge = generate_plugin_config_munge;
-function generate_plugin_config_munge(pluginInfo, vars, edit_config_changes) {
+function generate_plugin_config_munge (pluginInfo, vars, edit_config_changes) {
     var self = this;
 
     vars = vars || {};
     var munge = { files: {} };
     var changes = pluginInfo.getConfigFiles(self.platform);
 
-    if(edit_config_changes) {
+    if (edit_config_changes) {
         Array.prototype.push.apply(changes, edit_config_changes);
     }
 
-    changes.forEach(function(change) {
-        change.xmls.forEach(function(xml) {
+    changes.forEach(function (change) {
+        change.xmls.forEach(function (xml) {
             // 1. stringify each xml
-            var stringified = (new et.ElementTree(xml)).write({xml_declaration:false});
+            var stringified = (new et.ElementTree(xml)).write({xml_declaration: false});
             // interp vars
             if (vars) {
-                Object.keys(vars).forEach(function(key) {
+                Object.keys(vars).forEach(function (key) {
                     var regExp = new RegExp('\\$' + key, 'g');
                     stringified = stringified.replace(regExp, vars[key]);
                 });
@@ -322,8 +317,7 @@ function generate_plugin_config_munge(pluginInfo, vars, edit_config_changes) {
                 if (change.mode !== 'remove') {
                     mungeutil.deep_add(munge, change.file, change.target, { xml: stringified, count: 1, mode: change.mode, plugin: pluginInfo.id });
                 }
-            }
-            else {
+            } else {
                 mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after });
             }
         });
@@ -331,7 +325,7 @@ function generate_plugin_config_munge(pluginInfo, vars, edit_config_changes) {
     return munge;
 }
 
-function is_conflicting(editchanges, config_munge, self, force) {
+function is_conflicting (editchanges, config_munge, self, force) {
     var files = config_munge.files;
     var conflictFound = false;
     var conflictWithConfigxml = false;
@@ -340,7 +334,7 @@ function is_conflicting(editchanges, config_munge, self, force) {
     var conflictingParent;
     var conflictingPlugin;
 
-    editchanges.forEach(function(editchange) {
+    editchanges.forEach(function (editchange) {
         if (files[editchange.file]) {
             var parents = files[editchange.file].parents;
             var target = parents[editchange.target];
@@ -361,8 +355,7 @@ function is_conflicting(editchanges, config_munge, self, force) {
                         }
                     }
                 }
-            }
-            else {
+            } else {
                 conflictingParent = editchange.target;
             }
 
@@ -374,13 +367,11 @@ function is_conflicting(editchanges, config_munge, self, force) {
                     if (target[0].id === 'config.xml') {
                         // Keep track of config.xml/config.xml edit-config conflicts
                         mungeutil.deep_add(configxmlMunge, editchange.file, conflictingParent, target[0]);
-                    }
-                    else {
+                    } else {
                         // Keep track of config.xml x plugin.xml edit-config conflicts
                         mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
                     }
-                }
-                else {
+                } else {
                     if (target[0].id === 'config.xml') {
                         // plugin.xml cannot overwrite config.xml changes even if --force is used
                         conflictWithConfigxml = true;
@@ -390,36 +381,38 @@ function is_conflicting(editchanges, config_munge, self, force) {
                     if (force) {
                         // Need to find all conflicts when --force is used, track conflicting munges
                         mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
-                    }
-                    else {
+                    } else {
                         // plugin cannot overwrite other plugin changes without --force
                         conflictingPlugin = target[0].plugin;
-                        return;
+
                     }
                 }
             }
         }
     });
 
-    return {conflictFound: conflictFound, conflictingPlugin: conflictingPlugin, conflictingMunge: conflictingMunge,
-        configxmlMunge: configxmlMunge, conflictWithConfigxml:conflictWithConfigxml};
+    return {conflictFound: conflictFound,
+        conflictingPlugin: conflictingPlugin,
+        conflictingMunge: conflictingMunge,
+        configxmlMunge: configxmlMunge,
+        conflictWithConfigxml: conflictWithConfigxml};
 }
 
 // Go over the prepare queue and apply the config munges for each plugin
 // that has been (un)installed.
 PlatformMunger.prototype.process = PlatformMunger_process;
-function PlatformMunger_process(plugins_dir) {
+function PlatformMunger_process (plugins_dir) {
     var self = this;
     var platform_config = self.platformJson.root;
 
     // Uninstallation first
-    platform_config.prepare_queue.uninstalled.forEach(function(u) {
+    platform_config.prepare_queue.uninstalled.forEach(function (u) {
         var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin));
         self.remove_plugin_changes(pluginInfo, u.topLevel);
     });
 
     // Now handle installation
-    platform_config.prepare_queue.installed.forEach(function(u) {
+    platform_config.prepare_queue.installed.forEach(function (u) {
         var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin));
         self.add_plugin_changes(pluginInfo, u.vars, u.topLevel, true, u.force);
     });
@@ -428,4 +421,4 @@ function PlatformMunger_process(plugins_dir) {
     platform_config.prepare_queue.uninstalled = [];
     platform_config.prepare_queue.installed = [];
 }
-/**** END of PlatformMunger ****/
+/** ** END of PlatformMunger ****/
diff --git a/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js b/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js
index 4a58008..ec4a28a 100644
--- a/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js
+++ b/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js
@@ -14,6 +14,8 @@
  *
 */
 
+/* eslint no-control-regex: 0 */
+
 var fs = require('fs');
 var path = require('path');
 
@@ -42,7 +44,7 @@ addProperty(module, 'xml_helpers', '../util/xml-helpers', modules);
 * TODO: Consider moving it out to a separate file and maybe partially with
 * overrides in platform handlers.
 ******************************************************************************/
-function ConfigFile(project_dir, platform, file_tag) {
+function ConfigFile (project_dir, platform, file_tag) {
     this.project_dir = project_dir;
     this.platform = platform;
     this.file_tag = file_tag;
@@ -53,13 +55,13 @@ function ConfigFile(project_dir, platform, file_tag) {
 
 // ConfigFile.load()
 ConfigFile.prototype.load = ConfigFile_load;
-function ConfigFile_load() {
+function ConfigFile_load () {
     var self = this;
 
     // config file may be in a place not exactly specified in the target
     var filepath = self.filepath = resolveConfigFilePath(self.project_dir, self.platform, self.file_tag);
 
-    if ( !filepath || !fs.existsSync(filepath) ) {
+    if (!filepath || !fs.existsSync(filepath)) {
         self.exists = false;
         return;
     }
@@ -69,7 +71,7 @@ function ConfigFile_load() {
     var ext = path.extname(filepath);
     // Windows8 uses an appxmanifest, and wp8 will likely use
     // the same in a future release
-    if (ext == '.xml' || ext == '.appxmanifest') {
+    if (ext === '.xml' || ext === '.appxmanifest') {
         self.type = 'xml';
         self.data = modules.xml_helpers.parseElementtreeSync(filepath);
     } else {
@@ -80,12 +82,12 @@ function ConfigFile_load() {
         //       Do we still need to support binary plist?
         //       If yes, use plist.parseStringSync() and read the file once.
         self.data = isBinaryPlist(filepath) ?
-                modules.bplist.parseBuffer(fs.readFileSync(filepath)) :
-                modules.plist.parse(fs.readFileSync(filepath, 'utf8'));
+            modules.bplist.parseBuffer(fs.readFileSync(filepath)) :
+            modules.plist.parse(fs.readFileSync(filepath, 'utf8'));
     }
 }
 
-ConfigFile.prototype.save = function ConfigFile_save() {
+ConfigFile.prototype.save = function ConfigFile_save () {
     var self = this;
     if (self.type === 'xml') {
         fs.writeFileSync(self.filepath, self.data.write({indent: 4}), 'utf-8');
@@ -97,54 +99,54 @@ ConfigFile.prototype.save = function ConfigFile_save() {
     self.is_changed = false;
 };
 
-ConfigFile.prototype.graft_child = function ConfigFile_graft_child(selector, xml_child) {
+ConfigFile.prototype.graft_child = function ConfigFile_graft_child (selector, xml_child) {
     var self = this;
     var filepath = self.filepath;
     var result;
     if (self.type === 'xml') {
         var xml_to_graft = [modules.et.XML(xml_child.xml)];
         switch (xml_child.mode) {
-            case 'merge':
-                result = modules.xml_helpers.graftXMLMerge(self.data, xml_to_graft, selector, xml_child);
-                break;
-            case 'overwrite':
-                result = modules.xml_helpers.graftXMLOverwrite(self.data, xml_to_graft, selector, xml_child);
-                break;
-            case 'remove':
-                result= true;
-                break;
-            default:
-                result = modules.xml_helpers.graftXML(self.data, xml_to_graft, selector, xml_child.after);
+        case 'merge':
+            result = modules.xml_helpers.graftXMLMerge(self.data, xml_to_graft, selector, xml_child);
+            break;
+        case 'overwrite':
+            result = modules.xml_helpers.graftXMLOverwrite(self.data, xml_to_graft, selector, xml_child);
+            break;
+        case 'remove':
+            result = modules.xml_helpers.pruneXMLRemove(self.data, selector, xml_to_graft);
+            break;
+        default:
+            result = modules.xml_helpers.graftXML(self.data, xml_to_graft, selector, xml_child.after);
         }
-        if ( !result) {
+        if (!result) {
             throw new Error('Unable to graft xml at selector "' + selector + '" from "' + filepath + '" during config install');
         }
     } else {
         // plist file
         result = modules.plist_helpers.graftPLIST(self.data, xml_child.xml, selector);
-        if ( !result ) {
+        if (!result) {
             throw new Error('Unable to graft plist "' + filepath + '" during config install');
         }
     }
     self.is_changed = true;
 };
 
-ConfigFile.prototype.prune_child = function ConfigFile_prune_child(selector, xml_child) {
+ConfigFile.prototype.prune_child = function ConfigFile_prune_child (selector, xml_child) {
     var self = this;
     var filepath = self.filepath;
     var result;
     if (self.type === 'xml') {
         var xml_to_graft = [modules.et.XML(xml_child.xml)];
         switch (xml_child.mode) {
-            case 'merge':
-            case 'overwrite':
-                result = modules.xml_helpers.pruneXMLRestore(self.data, selector, xml_child);
-                break;
-            case 'remove':
-                result = modules.xml_helpers.prunXMLRemove(self.data, selector, xml_to_graft);
-                break;
-            default:
-                result = modules.xml_helpers.pruneXML(self.data, xml_to_graft, selector);
+        case 'merge':
+        case 'overwrite':
+            result = modules.xml_helpers.pruneXMLRestore(self.data, selector, xml_child);
+            break;
+        case 'remove':
+            result = modules.xml_helpers.pruneXMLRemove(self.data, selector, xml_to_graft);
+            break;
+        default:
+            result = modules.xml_helpers.pruneXML(self.data, xml_to_graft, selector);
         }
     } else {
         // plist file
@@ -160,7 +162,7 @@ ConfigFile.prototype.prune_child = function ConfigFile_prune_child(selector, xml
 // Some config-file target attributes are not qualified with a full leading directory, or contain wildcards.
 // Resolve to a real path in this function.
 // TODO: getIOSProjectname is slow because of glob, try to avoid calling it several times per project.
-function resolveConfigFilePath(project_dir, platform, file) {
+function resolveConfigFilePath (project_dir, platform, file) {
     var filepath = path.join(project_dir, file);
     var matches;
 
@@ -170,10 +172,10 @@ function resolveConfigFilePath(project_dir, platform, file) {
         if (matches.length) filepath = matches[0];
 
         // [CB-5989] multiple Info.plist files may exist. default to $PROJECT_NAME-Info.plist
-        if(matches.length > 1 && file.indexOf('-Info.plist')>-1){
-            var plistName =  getIOSProjectname(project_dir)+'-Info.plist';
-            for (var i=0; i < matches.length; i++) {
-                if(matches[i].indexOf(plistName) > -1){
+        if (matches.length > 1 && file.indexOf('-Info.plist') > -1) {
+            var plistName = getIOSProjectname(project_dir) + '-Info.plist';
+            for (var i = 0; i < matches.length; i++) {
+                if (matches[i].indexOf(plistName) > -1) {
                     filepath = matches[i];
                     break;
                 }
@@ -182,16 +184,34 @@ function resolveConfigFilePath(project_dir, platform, file) {
         return filepath;
     }
 
-    // special-case config.xml target that is just "config.xml". This should be resolved to the real location of the file.
-    // TODO: move the logic that contains the locations of config.xml from cordova CLI into plugman.
-    if (file == 'config.xml') {
-        if (platform == 'ubuntu') {
+    // XXX this checks for android studio projects
+    // only if none of the options above are satisfied does this get called
+    // TODO: Move this out of cordova-common and into the platforms somehow
+    if (platform === 'android' && !fs.existsSync(filepath)) {
+        if (file === 'AndroidManifest.xml') {
+            filepath = path.join(project_dir, 'app', 'src', 'main', 'AndroidManifest.xml');
+        } else if (file.endsWith('config.xml')) {
+            filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'xml', 'config.xml');
+        } else if (file.endsWith('strings.xml')) {
+            // Plugins really shouldn't mess with strings.xml, since it's able to be localized
+            filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'values', 'strings.xml');
+        } else if (file.match(/res\/xml/)) {
+            // Catch-all for all other stored XML configuration in legacy plugins
+            var config_file = path.basename(file);
+            filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'xml', config_file);
+        }
+        return filepath;
+    }
+
+    // special-case config.xml target that is just "config.xml" for other platforms. This should
+    // be resolved to the real location of the file.
+    // TODO: Move this out of cordova-common into platforms
+    if (file === 'config.xml') {
+        if (platform === 'ubuntu') {
             filepath = path.join(project_dir, 'config.xml');
-        } else if (platform == 'ios') {
-            var iospath = getIOSProjectname(project_dir);
-            filepath = path.join(project_dir,iospath, 'config.xml');
-        } else if (platform == 'android') {
-            filepath = path.join(project_dir, 'res', 'xml', 'config.xml');
+        } else if (platform === 'ios') {
+            var iospath = module.exports.getIOSProjectname(project_dir);
+            filepath = path.join(project_dir, iospath, 'config.xml');
         } else {
             matches = modules.glob.sync(path.join(project_dir, '**', 'config.xml'));
             if (matches.length) filepath = matches[0];
@@ -199,23 +219,17 @@ function resolveConfigFilePath(project_dir, platform, file) {
         return filepath;
     }
 
-    // XXX this checks for android studio projects
-    // only if none of the options above are satisfied does this get called
-    if(platform === 'android' && !fs.existsSync(filepath)) {
-      filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'xml', 'config.xml');
-    }
-
     // None of the special cases matched, returning project_dir/file.
     return filepath;
 }
 
 // Find out the real name of an iOS project
 // TODO: glob is slow, need a better way or caching, or avoid using more than once.
-function getIOSProjectname(project_dir) {
+function getIOSProjectname (project_dir) {
     var matches = modules.glob.sync(path.join(project_dir, '*.xcodeproj'));
     var iospath;
     if (matches.length === 1) {
-        iospath = path.basename(matches[0],'.xcodeproj');
+        iospath = path.basename(matches[0], '.xcodeproj');
     } else {
         var msg;
         if (matches.length === 0) {
@@ -229,7 +243,7 @@ function getIOSProjectname(project_dir) {
 }
 
 // determine if a plist file is binary
-function isBinaryPlist(filename) {
+function isBinaryPlist (filename) {
     // I wish there was a synchronous way to read only the first 6 bytes of a
     // file. This is wasteful :/
     var buf = '' + fs.readFileSync(filename, 'utf8');
@@ -238,3 +252,6 @@ function isBinaryPlist(filename) {
 }
 
 module.exports = ConfigFile;
+module.exports.isBinaryPlist = isBinaryPlist;
+module.exports.getIOSProjectname = getIOSProjectname;
+module.exports.resolveConfigFilePath = resolveConfigFilePath;
diff --git a/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js b/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js
index 894e922..0ef0435 100644
--- a/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js
+++ b/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js
@@ -28,18 +28,18 @@ var ConfigFile = require('./ConfigFile');
 * project_dir/platform/file
 * where file is the name used for the file in config munges.
 ******************************************************************************/
-function ConfigKeeper(project_dir, plugins_dir) {
+function ConfigKeeper (project_dir, plugins_dir) {
     this.project_dir = project_dir;
     this.plugins_dir = plugins_dir;
     this._cached = {};
 }
 
-ConfigKeeper.prototype.get = function ConfigKeeper_get(project_dir, platform, file) {
+ConfigKeeper.prototype.get = function ConfigKeeper_get (project_dir, platform, file) {
     var self = this;
 
     // This fixes a bug with older plugins - when specifying config xml instead of res/xml/config.xml
     // https://issues.apache.org/jira/browse/CB-6414
-    if(file == 'config.xml' && platform == 'android'){
+    if (file === 'config.xml' && platform === 'android') {
         file = 'res/xml/config.xml';
     }
     var fake_path = path.join(project_dir, platform, file);
@@ -53,8 +53,7 @@ ConfigKeeper.prototype.get = function ConfigKeeper_get(project_dir, platform, fi
     return config_file;
 };
 
-
-ConfigKeeper.prototype.save_all = function ConfigKeeper_save_all() {
+ConfigKeeper.prototype.save_all = function ConfigKeeper_save_all () {
     var self = this;
     Object.keys(self._cached).forEach(function (fake_path) {
         var config_file = self._cached[fake_path];
diff --git a/node_modules/cordova-common/src/ConfigChanges/munge-util.js b/node_modules/cordova-common/src/ConfigChanges/munge-util.js
index 0149bab..62648d8 100644
--- a/node_modules/cordova-common/src/ConfigChanges/munge-util.js
+++ b/node_modules/cordova-common/src/ConfigChanges/munge-util.js
@@ -19,14 +19,14 @@ var _ = require('underscore');
 
 // add the count of [key1][key2]...[keyN] to obj
 // return true if it didn't exist before
-exports.deep_add = function deep_add(obj, keys /* or key1, key2 .... */ ) {
-    if ( !Array.isArray(keys) ) {
+exports.deep_add = function deep_add (obj, keys /* or key1, key2 .... */) {
+    if (!Array.isArray(keys)) {
         keys = Array.prototype.slice.call(arguments, 1);
     }
 
-    return exports.process_munge(obj, true/*createParents*/, function (parentArray, k) {
-        var found = _.find(parentArray, function(element) {
-            return element.xml == k.xml;
+    return exports.process_munge(obj, true/* createParents */, function (parentArray, k) {
+        var found = _.find(parentArray, function (element) {
+            return element.xml === k.xml;
         });
         if (found) {
             found.after = found.after || k.after;
@@ -40,16 +40,16 @@ exports.deep_add = function deep_add(obj, keys /* or key1, key2 .... */ ) {
 
 // decrement the count of [key1][key2]...[keyN] from obj and remove if it reaches 0
 // return true if it was removed or not found
-exports.deep_remove = function deep_remove(obj, keys /* or key1, key2 .... */ ) {
-    if ( !Array.isArray(keys) ) {
+exports.deep_remove = function deep_remove (obj, keys /* or key1, key2 .... */) {
+    if (!Array.isArray(keys)) {
         keys = Array.prototype.slice.call(arguments, 1);
     }
 
-    var result = exports.process_munge(obj, false/*createParents*/, function (parentArray, k) {
+    var result = exports.process_munge(obj, false/* createParents */, function (parentArray, k) {
         var index = -1;
         var found = _.find(parentArray, function (element) {
             index++;
-            return element.xml == k.xml;
+            return element.xml === k.xml;
         });
         if (found) {
             if (parentArray[index].oldAttrib) {
@@ -58,8 +58,7 @@ exports.deep_remove = function deep_remove(obj, keys /* or key1, key2 .... */ )
             found.count -= k.count;
             if (found.count > 0) {
                 return false;
-            }
-            else {
+            } else {
                 parentArray.splice(index, 1);
             }
         }
@@ -71,14 +70,14 @@ exports.deep_remove = function deep_remove(obj, keys /* or key1, key2 .... */ )
 
 // search for [key1][key2]...[keyN]
 // return the object or undefined if not found
-exports.deep_find = function deep_find(obj, keys /* or key1, key2 .... */ ) {
-    if ( !Array.isArray(keys) ) {
+exports.deep_find = function deep_find (obj, keys /* or key1, key2 .... */) {
+    if (!Array.isArray(keys)) {
         keys = Array.prototype.slice.call(arguments, 1);
     }
 
-    return exports.process_munge(obj, false/*createParents?*/, function (parentArray, k) {
+    return exports.process_munge(obj, false/* createParents? */, function (parentArray, k) {
         return _.find(parentArray, function (element) {
-            return element.xml == (k.xml || k);
+            return element.xml === (k.xml || k);
         });
     }, keys);
 };
@@ -87,20 +86,20 @@ exports.deep_find = function deep_find(obj, keys /* or key1, key2 .... */ ) {
 // When createParents is true, add the file and parent items  they are missing
 // When createParents is false, stop and return undefined if the file and/or parent items are missing
 
-exports.process_munge = function process_munge(obj, createParents, func, keys /* or key1, key2 .... */ ) {
-    if ( !Array.isArray(keys) ) {
+exports.process_munge = function process_munge (obj, createParents, func, keys /* or key1, key2 .... */) {
+    if (!Array.isArray(keys)) {
         keys = Array.prototype.slice.call(arguments, 1);
     }
     var k = keys[0];
-    if (keys.length == 1) {
+    if (keys.length === 1) {
         return func(obj, k);
-    } else if (keys.length == 2) {
+    } else if (keys.length === 2) {
         if (!obj.parents[k] && !createParents) {
             return undefined;
         }
         obj.parents[k] = obj.parents[k] || [];
         return exports.process_munge(obj.parents[k], createParents, func, keys.slice(1));
-    } else if (keys.length == 3){
+    } else if (keys.length === 3) {
         if (!obj.files[k] && !createParents) {
             return undefined;
         }
@@ -115,7 +114,7 @@ exports.process_munge = function process_munge(obj, createParents, func, keys /*
 // base[file][selector][child] += munge[file][selector][child]
 // Returns a munge object containing values that exist in munge
 // but not in base.
-exports.increment_munge = function increment_munge(base, munge) {
+exports.increment_munge = function increment_munge (base, munge) {
     var diff = { files: {} };
 
     for (var file in munge.files) {
@@ -138,7 +137,7 @@ exports.increment_munge = function increment_munge(base, munge) {
 // base[file][selector][child] -= munge[file][selector][child]
 // nodes that reached zero value are removed from base and added to the returned munge
 // object.
-exports.decrement_munge = function decrement_munge(base, munge) {
+exports.decrement_munge = function decrement_munge (base, munge) {
     var zeroed = { files: {} };
 
     for (var file in munge.files) {
@@ -158,6 +157,6 @@ exports.decrement_munge = function decrement_munge(base, munge) {
 };
 
 // For better readability where used
-exports.clone_munge = function clone_munge(munge) {
+exports.clone_munge = function clone_munge (munge) {
     return exports.increment_munge({}, munge);
 };
diff --git a/node_modules/cordova-common/src/ConfigParser/ConfigParser.js b/node_modules/cordova-common/src/ConfigParser/ConfigParser.js
index e477a89..095ccf2 100644
--- a/node_modules/cordova-common/src/ConfigParser/ConfigParser.js
+++ b/node_modules/cordova-common/src/ConfigParser/ConfigParser.js
@@ -17,24 +17,21 @@
     under the License.
 */
 
-/* jshint sub:true */
-
-var et = require('elementtree'),
-    xml= require('../util/xml-helpers'),
-    CordovaError = require('../CordovaError/CordovaError'),
-    fs = require('fs'),
-    events = require('../events');
-
+var et = require('elementtree');
+var xml = require('../util/xml-helpers');
+var CordovaError = require('../CordovaError/CordovaError');
+var fs = require('fs');
+var events = require('../events');
 
 /** Wraps a config.xml file */
-function ConfigParser(path) {
+function ConfigParser (path) {
     this.path = path;
     try {
         this.doc = xml.parseElementtreeSync(path);
         this.cdvNamespacePrefix = getCordovaNamespacePrefix(this.doc);
         et.register_namespace(this.cdvNamespacePrefix, 'http://cordova.apache.org/ns/1.0');
     } catch (e) {
-        console.error('Parsing '+path+' failed');
+        events.emit('error', 'Parsing ' + path + ' failed');
         throw e;
     }
     var r = this.doc.getroot();
@@ -43,11 +40,11 @@ function ConfigParser(path) {
     }
 }
 
-function getNodeTextSafe(el) {
+function getNodeTextSafe (el) {
     return el && el.text && el.text.trim();
 }
 
-function findOrCreate(doc, name) {
+function findOrCreate (doc, name) {
     var ret = doc.find(name);
     if (!ret) {
         ret = new et.Element(name);
@@ -56,12 +53,12 @@ function findOrCreate(doc, name) {
     return ret;
 }
 
-function getCordovaNamespacePrefix(doc){
+function getCordovaNamespacePrefix (doc) {
     var rootAtribs = Object.getOwnPropertyNames(doc.getroot().attrib);
     var prefix = 'cdv';
-    for (var j = 0; j < rootAtribs.length; j++ ) {
-        if(rootAtribs[j].indexOf('xmlns:') === 0 &&
-            doc.getroot().attrib[rootAtribs[j]] === 'http://cordova.apache.org/ns/1.0'){
+    for (var j = 0; j < rootAtribs.length; j++) {
+        if (rootAtribs[j].indexOf('xmlns:') === 0 &&
+            doc.getroot().attrib[rootAtribs[j]] === 'http://cordova.apache.org/ns/1.0') {
             var strings = rootAtribs[j].split(':');
             prefix = strings[1];
             break;
@@ -76,7 +73,7 @@ function getCordovaNamespacePrefix(doc){
  * @param  {Array}  elems         An array of ElementTree nodes
  * @return {String}
  */
-function findElementAttributeValue(attributeName, elems) {
+function findElementAttributeValue (attributeName, elems) {
 
     elems = Array.isArray(elems) ? elems : [ elems ];
 
@@ -86,59 +83,69 @@ function findElementAttributeValue(attributeName, elems) {
         return filteredElems.attrib.value;
     }).pop();
 
-    return value ? value : '';
+    return value || '';
 }
 
 ConfigParser.prototype = {
-    getAttribute: function(attr) {
+    getAttribute: function (attr) {
         return this.doc.getroot().attrib[attr];
     },
 
-    packageName: function(id) {
+    packageName: function (id) {
         return this.getAttribute('id');
     },
-    setPackageName: function(id) {
+    setPackageName: function (id) {
         this.doc.getroot().attrib['id'] = id;
     },
-    android_packageName: function() {
+    android_packageName: function () {
         return this.getAttribute('android-packageName');
     },
-    android_activityName: function() {
+    android_activityName: function () {
         return this.getAttribute('android-activityName');
     },
-    ios_CFBundleIdentifier: function() {
+    ios_CFBundleIdentifier: function () {
         return this.getAttribute('ios-CFBundleIdentifier');
     },
-    name: function() {
+    name: function () {
         return getNodeTextSafe(this.doc.find('name'));
     },
-    setName: function(name) {
+    setName: function (name) {
         var el = findOrCreate(this.doc, 'name');
         el.text = name;
     },
-    description: function() {
+    shortName: function () {
+        return this.doc.find('name').attrib['short'] || this.name();
+    },
+    setShortName: function (shortname) {
+        var el = findOrCreate(this.doc, 'name');
+        if (!el.text) {
+            el.text = shortname;
+        }
+        el.attrib['short'] = shortname;
+    },
+    description: function () {
         return getNodeTextSafe(this.doc.find('description'));
     },
-    setDescription: function(text) {
+    setDescription: function (text) {
         var el = findOrCreate(this.doc, 'description');
         el.text = text;
     },
-    version: function() {
+    version: function () {
         return this.getAttribute('version');
     },
-    windows_packageVersion: function() {
+    windows_packageVersion: function () {
         return this.getAttribute('windows-packageVersion');
     },
-    android_versionCode: function() {
+    android_versionCode: function () {
         return this.getAttribute('android-versionCode');
     },
-    ios_CFBundleVersion: function() {
+    ios_CFBundleVersion: function () {
         return this.getAttribute('ios-CFBundleVersion');
     },
-    setVersion: function(value) {
+    setVersion: function (value) {
         this.doc.getroot().attrib['version'] = value;
     },
-    author: function() {
+    author: function () {
         return getNodeTextSafe(this.doc.find('author'));
     },
     getGlobalPreference: function (name) {
@@ -156,7 +163,7 @@ ConfigParser.prototype = {
     getPlatformPreference: function (name, platform) {
         return findElementAttributeValue(name, this.doc.findall('platform[@name=\'' + platform + '\']/preference'));
     },
-    getPreference: function(name, platform) {
+    getPreference: function (name, platform) {
 
         var platformPreference = '';
 
@@ -164,7 +171,7 @@ ConfigParser.prototype = {
             platformPreference = this.getPlatformPreference(name, platform);
         }
 
-        return platformPreference ? platformPreference : this.getGlobalPreference(name);
+        return platformPreference || this.getGlobalPreference(name);
 
     },
     /**
@@ -174,11 +181,11 @@ ConfigParser.prototype = {
      *                               "icon" and "splash" currently supported.
      * @return {Array}               Resources for the platform specified.
      */
-    getStaticResources: function(platform, resourceName) {
-        var ret = [],
-            staticResources = [];
+    getStaticResources: function (platform, resourceName) {
+        var ret = [];
+        var staticResources = [];
         if (platform) { // platform specific icons
-            this.doc.findall('platform[@name=\'' + platform + '\']/' + resourceName).forEach(function(elt){
+            this.doc.findall('platform[@name=\'' + platform + '\']/' + resourceName).forEach(function (elt) {
                 elt.platform = platform; // mark as platform specific resource
                 staticResources.push(elt);
             });
@@ -191,7 +198,7 @@ ConfigParser.prototype = {
             var res = {};
             res.src = elt.attrib.src;
             res.target = elt.attrib.target || undefined;
-            res.density = elt.attrib['density'] || elt.attrib[that.cdvNamespacePrefix+':density'] || elt.attrib['gap:density'];
+            res.density = elt.attrib['density'] || elt.attrib[that.cdvNamespacePrefix + ':density'] || elt.attrib['gap:density'];
             res.platform = elt.platform || null; // null means icon represents default icon (shared between platforms)
             res.width = +elt.attrib.width || undefined;
             res.height = +elt.attrib.height || undefined;
@@ -209,13 +216,13 @@ ConfigParser.prototype = {
          * @param  {number} height Height of resource.
          * @return {Resource} Resource object or null if not found.
          */
-        ret.getBySize = function(width, height) {
-            return ret.filter(function(res) {
+        ret.getBySize = function (width, height) {
+            return ret.filter(function (res) {
                 if (!res.width && !res.height) {
                     return false;
                 }
-                return ((!res.width || (width == res.width)) &&
-                    (!res.height || (height == res.height)));
+                return ((!res.width || (width === res.width)) &&
+                    (!res.height || (height === res.height)));
             })[0] || null;
         };
 
@@ -224,14 +231,14 @@ ConfigParser.prototype = {
          * @param  {string} density Density of resource.
          * @return {Resource}       Resource object or null if not found.
          */
-        ret.getByDensity = function(density) {
-            return ret.filter(function(res) {
-                return res.density == density;
+        ret.getByDensity = function (density) {
+            return ret.filter(function (res) {
+                return res.density === density;
             })[0] || null;
         };
 
         /** Returns default icons */
-        ret.getDefault = function() {
+        ret.getDefault = function () {
             return ret.defaultResource;
         };
 
@@ -243,7 +250,7 @@ ConfigParser.prototype = {
      * @param  {string} platform Platform name
      * @return {Resource[]}      Array of icon objects.
      */
-    getIcons: function(platform) {
+    getIcons: function (platform) {
         return this.getStaticResources(platform, 'icon');
     },
 
@@ -252,20 +259,22 @@ ConfigParser.prototype = {
      * @param  {string} platform Platform name
      * @return {Resource[]}      Array of Splash objects.
      */
-    getSplashScreens: function(platform) {
+    getSplashScreens: function (platform) {
         return this.getStaticResources(platform, 'splash');
     },
 
     /**
      * Returns all resource-files for a specific platform.
      * @param  {string} platform Platform name
+     * @param  {boolean} includeGlobal Whether to return resource-files at the
+     *                                 root level.
      * @return {Resource[]}      Array of resource file objects.
      */
-    getFileResources: function(platform) {
+    getFileResources: function (platform, includeGlobal) {
         var fileResources = [];
 
         if (platform) { // platform specific resources
-            fileResources = this.doc.findall('platform[@name=\'' + platform + '\']/resource-file').map(function(tag) {
+            fileResources = this.doc.findall('platform[@name=\'' + platform + '\']/resource-file').map(function (tag) {
                 return {
                     platform: platform,
                     src: tag.attrib.src,
@@ -277,6 +286,19 @@ ConfigParser.prototype = {
             });
         }
 
+        if (includeGlobal) {
+            this.doc.findall('resource-file').forEach(function (tag) {
+                fileResources.push({
+                    platform: platform || null,
+                    src: tag.attrib.src,
+                    target: tag.attrib.target,
+                    versions: tag.attrib.versions,
+                    deviceTarget: tag.attrib['device-target'],
+                    arch: tag.attrib.arch
+                });
+            });
+        }
+
         return fileResources;
     },
 
@@ -286,23 +308,23 @@ ConfigParser.prototype = {
      * @param {Array}  platforms Platforms to look for scripts into (root scripts will be included as well).
      * @return {Array}               Script elements.
      */
-    getHookScripts: function(hook, platforms) {
+    getHookScripts: function (hook, platforms) {
         var self = this;
         var scriptElements = self.doc.findall('./hook');
 
-        if(platforms) {
+        if (platforms) {
             platforms.forEach(function (platform) {
                 scriptElements = scriptElements.concat(self.doc.findall('./platform[@name="' + platform + '"]/hook'));
             });
         }
 
-        function filterScriptByHookType(el) {
+        function filterScriptByHookType (el) {
             return el.attrib.src && el.attrib.type && el.attrib.type.toLowerCase() === hook;
         }
 
         return scriptElements.filter(filterScriptByHookType);
     },
-   /**
+    /**
     * Returns a list of plugin (IDs).
     *
     * This function also returns any plugin's that
@@ -311,13 +333,13 @@ ConfigParser.prototype = {
     */
     getPluginIdList: function () {
         var plugins = this.doc.findall('plugin');
-        var result = plugins.map(function(plugin){
+        var result = plugins.map(function (plugin) {
             return plugin.attrib.name;
         });
         var features = this.doc.findall('feature');
-        features.forEach(function(element ){
+        features.forEach(function (element) {
             var idTag = element.find('./param[@name="id"]');
-            if(idTag){
+            if (idTag) {
                 result.push(idTag.attrib.value);
             }
         });
@@ -346,9 +368,9 @@ ConfigParser.prototype = {
         // support arbitrary object as variables source
         if (variables && typeof variables === 'object' && !Array.isArray(variables)) {
             variables = Object.keys(variables)
-            .map(function (variableName) {
-                return {name: variableName, value: variables[variableName]};
-            });
+                .map(function (variableName) {
+                    return {name: variableName, value: variables[variableName]};
+                });
         }
 
         if (variables) {
@@ -368,15 +390,15 @@ ConfigParser.prototype = {
      * @param {String} id
      * @returns {object} plugin including any variables
      */
-    getPlugin: function(id){
-        if(!id){
+    getPlugin: function (id) {
+        if (!id) {
             return undefined;
         }
         var pluginElement = this.doc.find('./plugin/[@name="' + id + '"]');
-        if (null === pluginElement) {
-            var legacyFeature =  this.doc.find('./feature/param[@name="id"][@value="' + id + '"]/..');
-            if(legacyFeature){
-                 events.emit('log', 'Found deprecated feature entry for ' + id +' in config.xml.');
+        if (pluginElement === null) {
+            var legacyFeature = this.doc.find('./feature/param[@name="id"][@value="' + id + '"]/..');
+            if (legacyFeature) {
+                events.emit('log', 'Found deprecated feature entry for ' + id + ' in config.xml.');
                 return featureToPlugin(legacyFeature);
             }
             return undefined;
@@ -387,10 +409,10 @@ ConfigParser.prototype = {
         plugin.spec = pluginElement.attrib.spec || pluginElement.attrib.src || pluginElement.attrib.version;
         plugin.variables = {};
         var variableElements = pluginElement.findall('variable');
-        variableElements.forEach(function(varElement){
+        variableElements.forEach(function (varElement) {
             var name = varElement.attrib.name;
             var value = varElement.attrib.value;
-            if(name){
+            if (name) {
                 plugin.variables[name] = value;
             }
         });
@@ -405,8 +427,8 @@ ConfigParser.prototype = {
      * @function
      * @param id name of the plugin
      */
-    removePlugin: function(id){
-        if(id){
+    removePlugin: function (id) {
+        if (id) {
             var plugins = this.doc.findall('./plugin/[@name="' + id + '"]')
                 .concat(this.doc.findall('./feature/param[@name="id"][@value="' + id + '"]/..'));
             var children = this.doc.getroot().getchildren();
@@ -420,7 +442,7 @@ ConfigParser.prototype = {
     },
 
     // Add any element to the root
-    addElement: function(name, attributes) {
+    addElement: function (name, attributes) {
         var el = et.Element(name);
         for (var a in attributes) {
             el.attrib[a] = attributes[a];
@@ -433,11 +455,11 @@ ConfigParser.prototype = {
      * @param  {String} name the engine name
      * @param  {String} spec engine source location or version (optional)
      */
-    addEngine: function(name, spec){
-        if(!name) return;
+    addEngine: function (name, spec) {
+        if (!name) return;
         var el = et.Element('engine');
         el.attrib.name = name;
-        if(spec){
+        if (spec) {
             el.attrib.spec = spec;
         }
         this.doc.getroot().append(el);
@@ -446,52 +468,54 @@ ConfigParser.prototype = {
      * Removes all the engines with given name
      * @param  {String} name the engine name.
      */
-    removeEngine: function(name){
-        var engines = this.doc.findall('./engine/[@name="' +name+'"]');
-        for(var i=0; i < engines.length; i++){
+    removeEngine: function (name) {
+        var engines = this.doc.findall('./engine/[@name="' + name + '"]');
+        for (var i = 0; i < engines.length; i++) {
             var children = this.doc.getroot().getchildren();
             var idx = children.indexOf(engines[i]);
-            if(idx > -1){
-                children.splice(idx,1);
+            if (idx > -1) {
+                children.splice(idx, 1);
             }
         }
     },
-    getEngines: function(){
+    getEngines: function () {
         var engines = this.doc.findall('./engine');
-        return engines.map(function(engine){
+        return engines.map(function (engine) {
             var spec = engine.attrib.spec || engine.attrib.version;
             return {
                 'name': engine.attrib.name,
-                'spec': spec ? spec : null
+                'spec': spec || null
             };
         });
     },
     /* Get all the access tags */
-    getAccesses: function() {
+    getAccesses: function () {
         var accesses = this.doc.findall('./access');
-        return accesses.map(function(access){
+        return accesses.map(function (access) {
             var minimum_tls_version = access.attrib['minimum-tls-version']; /* String */
             var requires_forward_secrecy = access.attrib['requires-forward-secrecy']; /* Boolean */
             var requires_certificate_transparency = access.attrib['requires-certificate-transparency']; /* Boolean */
             var allows_arbitrary_loads_in_web_content = access.attrib['allows-arbitrary-loads-in-web-content']; /* Boolean */
-            var allows_arbitrary_loads_in_media = access.attrib['allows-arbitrary-loads-in-media']; /* Boolean */
+            var allows_arbitrary_loads_in_media = access.attrib['allows-arbitrary-loads-in-media']; /* Boolean (DEPRECATED) */
+            var allows_arbitrary_loads_for_media = access.attrib['allows-arbitrary-loads-for-media']; /* Boolean */
             var allows_local_networking = access.attrib['allows-local-networking']; /* Boolean */
-            
+
             return {
                 'origin': access.attrib.origin,
                 'minimum_tls_version': minimum_tls_version,
-                'requires_forward_secrecy' : requires_forward_secrecy,
-                'requires_certificate_transparency' : requires_certificate_transparency,
-                'allows_arbitrary_loads_in_web_content' : allows_arbitrary_loads_in_web_content,
-                'allows_arbitrary_loads_in_media' : allows_arbitrary_loads_in_media,
-                'allows_local_networking' : allows_local_networking
+                'requires_forward_secrecy': requires_forward_secrecy,
+                'requires_certificate_transparency': requires_certificate_transparency,
+                'allows_arbitrary_loads_in_web_content': allows_arbitrary_loads_in_web_content,
+                'allows_arbitrary_loads_in_media': allows_arbitrary_loads_in_media,
+                'allows_arbitrary_loads_for_media': allows_arbitrary_loads_for_media,
+                'allows_local_networking': allows_local_networking
             };
         });
     },
     /* Get all the allow-navigation tags */
-    getAllowNavigations: function() {
+    getAllowNavigations: function () {
         var allow_navigations = this.doc.findall('./allow-navigation');
-        return allow_navigations.map(function(allow_navigation){
+        return allow_navigations.map(function (allow_navigation) {
             var minimum_tls_version = allow_navigation.attrib['minimum-tls-version']; /* String */
             var requires_forward_secrecy = allow_navigation.attrib['requires-forward-secrecy']; /* Boolean */
             var requires_certificate_transparency = allow_navigation.attrib['requires-certificate-transparency']; /* Boolean */
@@ -499,45 +523,68 @@ ConfigParser.prototype = {
             return {
                 'href': allow_navigation.attrib.href,
                 'minimum_tls_version': minimum_tls_version,
-                'requires_forward_secrecy' : requires_forward_secrecy,
-                'requires_certificate_transparency' : requires_certificate_transparency
+                'requires_forward_secrecy': requires_forward_secrecy,
+                'requires_certificate_transparency': requires_certificate_transparency
             };
         });
     },
     /* Get all the allow-intent tags */
-    getAllowIntents: function() {
+    getAllowIntents: function () {
         var allow_intents = this.doc.findall('./allow-intent');
-        return allow_intents.map(function(allow_intent){
+        return allow_intents.map(function (allow_intent) {
             return {
                 'href': allow_intent.attrib.href
             };
         });
     },
     /* Get all edit-config tags */
-    getEditConfigs: function(platform) {
+    getEditConfigs: function (platform) {
         var platform_tag = this.doc.find('./platform[@name="' + platform + '"]');
         var platform_edit_configs = platform_tag ? platform_tag.findall('edit-config') : [];
 
         var edit_configs = this.doc.findall('edit-config').concat(platform_edit_configs);
 
-        return edit_configs.map(function(tag) {
+        return edit_configs.map(function (tag) {
             var editConfig =
                 {
-                    file : tag.attrib['file'],
-                    target : tag.attrib['target'],
-                    mode : tag.attrib['mode'],
-                    id : 'config.xml',
-                    xmls : tag.getchildren()
+                    file: tag.attrib['file'],
+                    target: tag.attrib['target'],
+                    mode: tag.attrib['mode'],
+                    id: 'config.xml',
+                    xmls: tag.getchildren()
                 };
             return editConfig;
         });
     },
-    write:function() {
+
+    /* Get all config-file tags */
+    getConfigFiles: function (platform) {
+        var platform_tag = this.doc.find('./platform[@name="' + platform + '"]');
+        var platform_config_files = platform_tag ? platform_tag.findall('config-file') : [];
+
+        var config_files = this.doc.findall('config-file').concat(platform_config_files);
+
+        return config_files.map(function (tag) {
+            var configFile =
+                {
+                    target: tag.attrib['target'],
+                    parent: tag.attrib['parent'],
+                    after: tag.attrib['after'],
+                    xmls: tag.getchildren(),
+                    // To support demuxing via versions
+                    versions: tag.attrib['versions'],
+                    deviceTarget: tag.attrib['device-target']
+                };
+            return configFile;
+        });
+    },
+
+    write: function () {
         fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
     }
 };
 
-function featureToPlugin(featureElement) {
+function featureToPlugin (featureElement) {
     var plugin = {};
     plugin.variables = [];
     var pluginVersion,
diff --git a/node_modules/cordova-common/src/CordovaCheck.js b/node_modules/cordova-common/src/CordovaCheck.js
index 46e733f..28f629d 100644
--- a/node_modules/cordova-common/src/CordovaCheck.js
+++ b/node_modules/cordova-common/src/CordovaCheck.js
@@ -17,10 +17,10 @@
     under the License.
 */
 
-var fs = require('fs'),
-    path = require('path');
+var fs = require('fs');
+var path = require('path');
 
-function isRootDir(dir) {
+function isRootDir (dir) {
     if (fs.existsSync(path.join(dir, 'www'))) {
         if (fs.existsSync(path.join(dir, 'config.xml'))) {
             // For sure is.
@@ -41,12 +41,12 @@ function isRootDir(dir) {
 // Runs up the directory chain looking for a .cordova directory.
 // IF it is found we are in a Cordova project.
 // Omit argument to use CWD.
-function isCordova(dir) {
+function isCordova (dir) {
     if (!dir) {
         // Prefer PWD over cwd so that symlinked dirs within your PWD work correctly (CB-5687).
         var pwd = process.env.PWD;
         var cwd = process.cwd();
-        if (pwd && pwd != cwd && pwd != 'undefined') {
+        if (pwd && pwd !== cwd && pwd !== 'undefined') {
             return isCordova(pwd) || isCordova(cwd);
         }
         return isCordova(cwd);
@@ -62,7 +62,7 @@ function isCordova(dir) {
         }
         var parentDir = path.normalize(path.join(dir, '..'));
         // Detect fs root.
-        if (parentDir == dir) {
+        if (parentDir === dir) {
             return bestReturnValueSoFar;
         }
         dir = parentDir;
@@ -72,5 +72,5 @@ function isCordova(dir) {
 }
 
 module.exports = {
-    findProjectRoot : isCordova
+    findProjectRoot: isCordova
 };
diff --git a/node_modules/cordova-common/src/CordovaError/CordovaError.js b/node_modules/cordova-common/src/CordovaError/CordovaError.js
index 7262448..24de6af 100644
--- a/node_modules/cordova-common/src/CordovaError/CordovaError.js
+++ b/node_modules/cordova-common/src/CordovaError/CordovaError.js
@@ -17,7 +17,7 @@
     under the License.
 */
 
-/* jshint proto:true */
+/* eslint no-proto: 0 */
 
 var EOL = require('os').EOL;
 
@@ -30,7 +30,7 @@ var EOL = require('os').EOL;
  * @param {CordovaExternalToolErrorContext} [context] External tool error context object
  * @constructor
  */
-function CordovaError(message, code, context) {
+function CordovaError (message, code, context) {
     Error.captureStackTrace(this, this.constructor);
     this.name = this.constructor.name;
     this.message = message;
@@ -47,10 +47,10 @@ CordovaError.EXTERNAL_TOOL_ERROR = 1;
  * Translates instance's error code number into error code name, e.g. 0 -> UNKNOWN_ERROR
  * @returns {string} Error code string name
  */
-CordovaError.prototype.getErrorCodeName = function() {
-    for(var key in CordovaError) {
-        if(CordovaError.hasOwnProperty(key)) {
-            if(CordovaError[key] === this.code) {
+CordovaError.prototype.getErrorCodeName = function () {
+    for (var key in CordovaError) {
+        if (CordovaError.hasOwnProperty(key)) {
+            if (CordovaError[key] === this.code) {
                 return key;
             }
         }
@@ -63,16 +63,17 @@ CordovaError.prototype.getErrorCodeName = function() {
  *   details including information about error code name and context
  * @return  {String}              Stringified error representation
  */
-CordovaError.prototype.toString = function(isVerbose) {
-    var message = '', codePrefix = '';
+CordovaError.prototype.toString = function (isVerbose) {
+    var message = '';
+    var codePrefix = '';
 
-    if(this.code !== CordovaError.UNKNOWN_ERROR) {
+    if (this.code !== CordovaError.UNKNOWN_ERROR) {
         codePrefix = 'code: ' + this.code + (isVerbose ? (' (' + this.getErrorCodeName() + ')') : '') + ' ';
     }
 
-    if(this.code === CordovaError.EXTERNAL_TOOL_ERROR) {
-        if(typeof this.context !== 'undefined') {
-            if(isVerbose) {
+    if (this.code === CordovaError.EXTERNAL_TOOL_ERROR) {
+        if (typeof this.context !== 'undefined') {
+            if (isVerbose) {
                 message = codePrefix + EOL + this.context.toString(isVerbose) + '\n failed with an error: ' +
                     this.message + EOL + 'Stack trace: ' + this.stack;
             } else {
diff --git a/node_modules/cordova-common/src/CordovaError/CordovaExternalToolErrorContext.js b/node_modules/cordova-common/src/CordovaError/CordovaExternalToolErrorContext.js
index ca9a4aa..30699b4 100644
--- a/node_modules/cordova-common/src/CordovaError/CordovaExternalToolErrorContext.js
+++ b/node_modules/cordova-common/src/CordovaError/CordovaExternalToolErrorContext.js
@@ -27,7 +27,7 @@ var path = require('path');
  * @param {String} [cwd] Command working directory
  * @constructor
  */
-function CordovaExternalToolErrorContext(cmd, args, cwd) {
+function CordovaExternalToolErrorContext (cmd, args, cwd) {
     this.cmd = cmd;
     // Helper field for readability
     this.cmdShortName = path.basename(cmd);
@@ -35,8 +35,8 @@ function CordovaExternalToolErrorContext(cmd, args, cwd) {
     this.cwd = cwd;
 }
 
-CordovaExternalToolErrorContext.prototype.toString = function(isVerbose) {
-    if(isVerbose) {
+CordovaExternalToolErrorContext.prototype.toString = function (isVerbose) {
+    if (isVerbose) {
         return 'External tool \'' + this.cmdShortName + '\'' +
             '\nCommand full path: ' + this.cmd + '\nCommand args: ' + this.args +
             (typeof this.cwd !== 'undefined' ? '\nCommand cwd: ' + this.cwd : '');
diff --git a/node_modules/cordova-common/src/CordovaLogger.js b/node_modules/cordova-common/src/CordovaLogger.js
index 71bc7e8..ea6e9ce 100644
--- a/node_modules/cordova-common/src/CordovaLogger.js
+++ b/node_modules/cordova-common/src/CordovaLogger.js
@@ -41,11 +41,11 @@ function CordovaLogger () {
     this.stderrCursor = ansi(this.stderr);
 
     this.addLevel('verbose', 1000, 'grey');
-    this.addLevel('normal' , 2000);
-    this.addLevel('warn'   , 2000, 'yellow');
-    this.addLevel('info'   , 3000, 'blue');
-    this.addLevel('error'  , 5000, 'red');
-    this.addLevel('results' , 10000);
+    this.addLevel('normal', 2000);
+    this.addLevel('warn', 2000, 'yellow');
+    this.addLevel('info', 3000, 'blue');
+    this.addLevel('error', 5000, 'red');
+    this.addLevel('results', 10000);
 
     this.setLevel('normal');
 }
@@ -82,9 +82,10 @@ CordovaLogger.RESULTS = 'results';
 CordovaLogger.prototype.log = function (logLevel, message) {
     // if there is no such logLevel defined, or provided level has
     // less severity than active level, then just ignore this call and return
-    if (!this.levels[logLevel] || this.levels[logLevel] < this.levels[this.logLevel])
+    if (!this.levels[logLevel] || this.levels[logLevel] < this.levels[this.logLevel]) {
         // return instance to allow to chain calls
         return this;
+    }
 
     var isVerbose = this.logLevel === 'verbose';
     var cursor = this.stdoutCursor;
@@ -179,8 +180,7 @@ CordovaLogger.prototype.adjustLevel = function (opts) {
  */
 CordovaLogger.prototype.subscribe = function (eventEmitter) {
 
-    if (!(eventEmitter instanceof EventEmitter))
-        throw new Error('Subscribe method only accepts an EventEmitter instance as argument');
+    if (!(eventEmitter instanceof EventEmitter)) { throw new Error('Subscribe method only accepts an EventEmitter instance as argument'); }
 
     eventEmitter.on('verbose', this.verbose)
         .on('log', this.normal)
@@ -193,7 +193,7 @@ CordovaLogger.prototype.subscribe = function (eventEmitter) {
     return this;
 };
 
-function formatError(error, isVerbose) {
+function formatError (error, isVerbose) {
     var message = '';
 
     if (error instanceof CordovaError) {
diff --git a/node_modules/cordova-common/src/FileUpdater.js b/node_modules/cordova-common/src/FileUpdater.js
index 8b6876b..c4eeb97 100644
--- a/node_modules/cordova-common/src/FileUpdater.js
+++ b/node_modules/cordova-common/src/FileUpdater.js
@@ -17,12 +17,12 @@
     under the License.
 */
 
-"use strict";
+'use strict';
 
-var fs = require("fs");
-var path = require("path");
-var shell = require("shelljs");
-var minimatch = require("minimatch");
+var fs = require('fs');
+var path = require('path');
+var shell = require('shelljs');
+var minimatch = require('minimatch');
 
 /**
  * Logging callback used in the FileUpdater methods.
@@ -55,27 +55,27 @@ var minimatch = require("minimatch");
  * @return {boolean} true if any changes were made, or false if the force flag is not set
  *     and everything was up to date
  */
-function updatePathWithStats(sourcePath, sourceStats, targetPath, targetStats, options, log) {
+function updatePathWithStats (sourcePath, sourceStats, targetPath, targetStats, options, log) {
     var updated = false;
 
-    var rootDir = (options && options.rootDir) || "";
+    var rootDir = (options && options.rootDir) || '';
     var copyAll = (options && options.all) || false;
 
-    var targetFullPath = path.join(rootDir || "", targetPath);
+    var targetFullPath = path.join(rootDir || '', targetPath);
 
     if (sourceStats) {
-        var sourceFullPath = path.join(rootDir || "", sourcePath);
+        var sourceFullPath = path.join(rootDir || '', sourcePath);
 
         if (targetStats) {
             // The target exists. But if the directory status doesn't match the source, delete it.
             if (targetStats.isDirectory() && !sourceStats.isDirectory()) {
-                log("rmdir  " + targetPath + " (source is a file)");
-                shell.rm("-rf", targetFullPath);
+                log('rmdir  ' + targetPath + ' (source is a file)');
+                shell.rm('-rf', targetFullPath);
                 targetStats = null;
                 updated = true;
             } else if (!targetStats.isDirectory() && sourceStats.isDirectory()) {
-                log("delete " + targetPath + " (source is a directory)");
-                shell.rm("-f", targetFullPath);
+                log('delete ' + targetPath + ' (source is a directory)');
+                shell.rm('-f', targetFullPath);
                 targetStats = null;
                 updated = true;
             }
@@ -84,21 +84,21 @@ function updatePathWithStats(sourcePath, sourceStats, targetPath, targetStats, o
         if (!targetStats) {
             if (sourceStats.isDirectory()) {
                 // The target directory does not exist, so it should be created.
-                log("mkdir " + targetPath);
-                shell.mkdir("-p", targetFullPath);
+                log('mkdir ' + targetPath);
+                shell.mkdir('-p', targetFullPath);
                 updated = true;
             } else if (sourceStats.isFile()) {
                 // The target file does not exist, so it should be copied from the source.
-                log("copy  " + sourcePath + " " + targetPath + (copyAll ? "" : " (new file)"));
-                shell.cp("-f", sourceFullPath, targetFullPath);
+                log('copy  ' + sourcePath + ' ' + targetPath + (copyAll ? '' : ' (new file)'));
+                shell.cp('-f', sourceFullPath, targetFullPath);
                 updated = true;
             }
         } else if (sourceStats.isFile() && targetStats.isFile()) {
             // The source and target paths both exist and are files.
             if (copyAll) {
                 // The caller specified all files should be copied.
-                log("copy  " + sourcePath + " " + targetPath);
-                shell.cp("-f", sourceFullPath, targetFullPath);
+                log('copy  ' + sourcePath + ' ' + targetPath);
+                shell.cp('-f', sourceFullPath, targetFullPath);
                 updated = true;
             } else {
                 // Copy if the source has been modified since it was copied to the target, or if
@@ -107,8 +107,8 @@ function updatePathWithStats(sourcePath, sourceStats, targetPath, targetStats, o
                 // for timestamps lacking sub-second precision in some filesystems.
                 if (sourceStats.mtime.getTime() >= targetStats.mtime.getTime() ||
                         sourceStats.size !== targetStats.size) {
-                    log("copy  " + sourcePath + " " + targetPath + " (updated file)");
-                    shell.cp("-f", sourceFullPath, targetFullPath);
+                    log('copy  ' + sourcePath + ' ' + targetPath + ' (updated file)');
+                    shell.cp('-f', sourceFullPath, targetFullPath);
                     updated = true;
                 }
             }
@@ -116,11 +116,11 @@ function updatePathWithStats(sourcePath, sourceStats, targetPath, targetStats, o
     } else if (targetStats) {
         // The target exists but the source is null, so the target should be deleted.
         if (targetStats.isDirectory()) {
-            log("rmdir  " + targetPath + (copyAll ? "" : " (no source)"));
-            shell.rm("-rf", targetFullPath);
+            log('rmdir  ' + targetPath + (copyAll ? '' : ' (no source)'));
+            shell.rm('-rf', targetFullPath);
         } else {
-            log("delete " + targetPath + (copyAll ? "" : " (no source)"));
-            shell.rm("-f", targetFullPath);
+            log('delete ' + targetPath + (copyAll ? '' : ' (no source)'));
+            shell.rm('-f', targetFullPath);
         }
         updated = true;
     }
@@ -132,8 +132,8 @@ function updatePathWithStats(sourcePath, sourceStats, targetPath, targetStats, o
  * Helper for updatePath and updatePaths functions. Queries stats for source and target
  * and ensures target directory exists before copying a file.
  */
-function updatePathInternal(sourcePath, targetPath, options, log) {
-    var rootDir = (options && options.rootDir) || "";
+function updatePathInternal (sourcePath, targetPath, options, log) {
+    var rootDir = (options && options.rootDir) || '';
     var targetFullPath = path.join(rootDir, targetPath);
     var targetStats = fs.existsSync(targetFullPath) ? fs.statSync(targetFullPath) : null;
     var sourceStats = null;
@@ -142,7 +142,7 @@ function updatePathInternal(sourcePath, targetPath, options, log) {
         // A non-null source path was specified. It should exist.
         var sourceFullPath = path.join(rootDir, sourcePath);
         if (!fs.existsSync(sourceFullPath)) {
-            throw new Error("Source path does not exist: " + sourcePath);
+            throw new Error('Source path does not exist: ' + sourcePath);
         }
 
         sourceStats = fs.statSync(sourceFullPath);
@@ -150,7 +150,7 @@ function updatePathInternal(sourcePath, targetPath, options, log) {
         // Create the target's parent directory if it doesn't exist.
         var parentDir = path.dirname(targetFullPath);
         if (!fs.existsSync(parentDir)) {
-            shell.mkdir("-p", parentDir);
+            shell.mkdir('-p', parentDir);
         }
     }
 
@@ -177,16 +177,16 @@ function updatePathInternal(sourcePath, targetPath, options, log) {
  * @return {boolean} true if any changes were made, or false if the force flag is not set
  *     and everything was up to date
  */
-function updatePath(sourcePath, targetPath, options, log) {
-    if (sourcePath !== null && typeof sourcePath !== "string") {
-        throw new Error("A source path (or null) is required.");
+function updatePath (sourcePath, targetPath, options, log) {
+    if (sourcePath !== null && typeof sourcePath !== 'string') {
+        throw new Error('A source path (or null) is required.');
     }
 
-    if (!targetPath || typeof targetPath !== "string") {
-        throw new Error("A target path is required.");
+    if (!targetPath || typeof targetPath !== 'string') {
+        throw new Error('A target path is required.');
     }
 
-    log = log || function(message) { };
+    log = log || function (message) { };
 
     return updatePathInternal(sourcePath, targetPath, options, log);
 }
@@ -208,12 +208,12 @@ function updatePath(sourcePath, targetPath, options, log) {
  * @return {boolean} true if any changes were made, or false if the force flag is not set
  *     and everything was up to date
  */
-function updatePaths(pathMap, options, log) {
-    if (!pathMap || typeof pathMap !== "object" || Array.isArray(pathMap)) {
-        throw new Error("An object mapping from target paths to source paths is required.");
+function updatePaths (pathMap, options, log) {
+    if (!pathMap || typeof pathMap !== 'object' || Array.isArray(pathMap)) {
+        throw new Error('An object mapping from target paths to source paths is required.');
     }
 
-    log = log || function(message) { };
+    log = log || function (message) { };
 
     var updated = false;
 
@@ -255,44 +255,44 @@ function updatePaths(pathMap, options, log) {
  * @return {boolean} true if any changes were made, or false if the force flag is not set
  *     and everything was up to date
  */
-function mergeAndUpdateDir(sourceDirs, targetDir, options, log) {
-    if (sourceDirs && typeof sourceDirs === "string") {
+function mergeAndUpdateDir (sourceDirs, targetDir, options, log) {
+    if (sourceDirs && typeof sourceDirs === 'string') {
         sourceDirs = [ sourceDirs ];
     } else if (!Array.isArray(sourceDirs)) {
-        throw new Error("A source directory path or array of paths is required.");
+        throw new Error('A source directory path or array of paths is required.');
     }
 
-    if (!targetDir || typeof targetDir !== "string") {
-        throw new Error("A target directory path is required.");
+    if (!targetDir || typeof targetDir !== 'string') {
+        throw new Error('A target directory path is required.');
     }
 
-    log = log || function(message) { };
+    log = log || function (message) { };
 
-    var rootDir = (options && options.rootDir) || "";
+    var rootDir = (options && options.rootDir) || '';
 
-    var include = (options && options.include) || [ "**" ];
-    if (typeof include === "string") {
+    var include = (options && options.include) || [ '**' ];
+    if (typeof include === 'string') {
         include = [ include ];
     } else if (!Array.isArray(include)) {
-        throw new Error("Include parameter must be a glob string or array of glob strings.");
+        throw new Error('Include parameter must be a glob string or array of glob strings.');
     }
 
     var exclude = (options && options.exclude) || [];
-    if (typeof exclude === "string") {
+    if (typeof exclude === 'string') {
         exclude = [ exclude ];
     } else if (!Array.isArray(exclude)) {
-        throw new Error("Exclude parameter must be a glob string or array of glob strings.");
+        throw new Error('Exclude parameter must be a glob string or array of glob strings.');
     }
 
     // Scan the files in each of the source directories.
     var sourceMaps = sourceDirs.map(function (sourceDir) {
-            return path.join(rootDir, sourceDir);
-        }).map(function (sourcePath) {
-            if (!fs.existsSync(sourcePath)) {
-                throw new Error("Source directory does not exist: " + sourcePath);
-            }
-            return mapDirectory(rootDir, path.relative(rootDir, sourcePath), include, exclude);
-        });
+        return path.join(rootDir, sourceDir);
+    }).map(function (sourcePath) {
+        if (!fs.existsSync(sourcePath)) {
+            throw new Error('Source directory does not exist: ' + sourcePath);
+        }
+        return mapDirectory(rootDir, path.relative(rootDir, sourcePath), include, exclude);
+    });
 
     // Scan the files in the target directory, if it exists.
     var targetMap = {};
@@ -323,18 +323,18 @@ function mergeAndUpdateDir(sourceDirs, targetDir, options, log) {
 /**
  * Creates a dictionary map of all files and directories under a path.
  */
-function mapDirectory(rootDir, subDir, include, exclude) {
-    var dirMap = { "": { subDir: subDir, stats: fs.statSync(path.join(rootDir, subDir)) } };
-    mapSubdirectory(rootDir, subDir, "", include, exclude, dirMap);
+function mapDirectory (rootDir, subDir, include, exclude) {
+    var dirMap = { '': { subDir: subDir, stats: fs.statSync(path.join(rootDir, subDir)) } };
+    mapSubdirectory(rootDir, subDir, '', include, exclude, dirMap);
     return dirMap;
 
-    function mapSubdirectory(rootDir, subDir, relativeDir, include, exclude, dirMap) {
+    function mapSubdirectory (rootDir, subDir, relativeDir, include, exclude, dirMap) {
         var itemMapped = false;
         var items = fs.readdirSync(path.join(rootDir, subDir, relativeDir));
 
-        items.forEach(function(item) {
+        items.forEach(function (item) {
             var relativePath = path.join(relativeDir, item);
-            if(!matchGlobArray(relativePath, exclude)) {
+            if (!matchGlobArray(relativePath, exclude)) {
                 // Stats obtained here (required at least to know where to recurse in directories)
                 // are saved for later, where the modified times may also be used. This minimizes
                 // the number of file I/O operations performed.
@@ -361,9 +361,9 @@ function mapDirectory(rootDir, subDir, include, exclude) {
         return itemMapped;
     }
 
-    function matchGlobArray(path, globs) {
-        return globs.some(function(elem) {
-            return minimatch(path, elem, {dot:true});
+    function matchGlobArray (path, globs) {
+        return globs.some(function (elem) {
+            return minimatch(path, elem, {dot: true});
         });
     }
 }
@@ -372,13 +372,13 @@ function mapDirectory(rootDir, subDir, include, exclude) {
  * Merges together multiple source maps and a target map into a single mapping from
  * relative paths to objects with target and source paths and stats.
  */
-function mergePathMaps(sourceMaps, targetMap, targetDir) {
+function mergePathMaps (sourceMaps, targetMap, targetDir) {
     // Merge multiple source maps together, along with target path info.
     // Entries in later source maps override those in earlier source maps.
     // Target stats will be filled in below for targets that exist.
     var pathMap = {};
     sourceMaps.forEach(function (sourceMap) {
-        Object.keys(sourceMap).forEach(function(sourceSubPath){
+        Object.keys(sourceMap).forEach(function (sourceSubPath) {
             var sourceEntry = sourceMap[sourceSubPath];
             pathMap[sourceSubPath] = {
                 targetPath: path.join(targetDir, sourceSubPath),
@@ -391,7 +391,7 @@ function mergePathMaps(sourceMaps, targetMap, targetDir) {
 
     // Fill in target stats for targets that exist, and create entries
     // for targets that don't have any corresponding sources.
-    Object.keys(targetMap).forEach(function(subPath){
+    Object.keys(targetMap).forEach(function (subPath) {
         var entry = pathMap[subPath];
         if (entry) {
             entry.targetStats = targetMap[subPath].stats;
@@ -413,4 +413,3 @@ module.exports = {
     updatePaths: updatePaths,
     mergeAndUpdateDir: mergeAndUpdateDir
 };
-
diff --git a/node_modules/cordova-common/src/PlatformJson.js b/node_modules/cordova-common/src/PlatformJson.js
index ab94b5f..7eaf1a2 100644
--- a/node_modules/cordova-common/src/PlatformJson.js
+++ b/node_modules/cordova-common/src/PlatformJson.js
@@ -13,7 +13,6 @@
  * under the License.
  *
 */
-/* jshint sub:true */
 
 var fs = require('fs');
 var path = require('path');
@@ -22,13 +21,13 @@ var mungeutil = require('./ConfigChanges/munge-util');
 var pluginMappernto = require('cordova-registry-mapper').newToOld;
 var pluginMapperotn = require('cordova-registry-mapper').oldToNew;
 
-function PlatformJson(filePath, platform, root) {
+function PlatformJson (filePath, platform, root) {
     this.filePath = filePath;
     this.platform = platform;
     this.root = fix_munge(root || {});
 }
 
-PlatformJson.load = function(plugins_dir, platform) {
+PlatformJson.load = function (plugins_dir, platform) {
     var filePath = path.join(plugins_dir, platform + '.json');
     var root = null;
     if (fs.existsSync(filePath)) {
@@ -37,9 +36,9 @@ PlatformJson.load = function(plugins_dir, platform) {
     return new PlatformJson(filePath, platform, root);
 };
 
-PlatformJson.prototype.save = function() {
+PlatformJson.prototype.save = function () {
     shelljs.mkdir('-p', path.dirname(this.filePath));
-    fs.writeFileSync(this.filePath, JSON.stringify(this.root, null, 4), 'utf-8');
+    fs.writeFileSync(this.filePath, JSON.stringify(this.root, null, 2), 'utf-8');
 };
 
 /**
@@ -49,7 +48,7 @@ PlatformJson.prototype.save = function() {
  * @param  {String} pluginId A plugin id to check for.
  * @return {Boolean} true if plugin installed as top-level, otherwise false.
  */
-PlatformJson.prototype.isPluginTopLevel = function(pluginId) {
+PlatformJson.prototype.isPluginTopLevel = function (pluginId) {
     var installedPlugins = this.root.installed_plugins;
     return installedPlugins[pluginId] ||
         installedPlugins[pluginMappernto[pluginId]] ||
@@ -63,7 +62,7 @@ PlatformJson.prototype.isPluginTopLevel = function(pluginId) {
  * @param  {String} pluginId A plugin id to check for.
  * @return {Boolean} true if plugin installed as a dependency, otherwise false.
  */
-PlatformJson.prototype.isPluginDependent = function(pluginId) {
+PlatformJson.prototype.isPluginDependent = function (pluginId) {
     var dependentPlugins = this.root.dependent_plugins;
     return dependentPlugins[pluginId] ||
         dependentPlugins[pluginMappernto[pluginId]] ||
@@ -76,12 +75,12 @@ PlatformJson.prototype.isPluginDependent = function(pluginId) {
  * @param  {String} pluginId A plugin id to check for.
  * @return {Boolean} true if plugin installed, otherwise false.
  */
-PlatformJson.prototype.isPluginInstalled = function(pluginId) {
+PlatformJson.prototype.isPluginInstalled = function (pluginId) {
     return this.isPluginTopLevel(pluginId) ||
         this.isPluginDependent(pluginId);
 };
 
-PlatformJson.prototype.addPlugin = function(pluginId, variables, isTopLevel) {
+PlatformJson.prototype.addPlugin = function (pluginId, variables, isTopLevel) {
     var pluginsList = isTopLevel ?
         this.root.installed_plugins :
         this.root.dependent_plugins;
@@ -107,13 +106,13 @@ PlatformJson.prototype.addPluginMetadata = function (pluginInfo) {
     });
 
     var modulesToInstall = pluginInfo.getJsModules(this.platform)
-    .map(function (module) {
-        return new ModuleMetadata(pluginInfo.id, module);
-    })
-    .filter(function (metadata) {
-        // Filter out modules which are already added to metadata
-        return installedPaths.indexOf(metadata.file) === -1;
-    });
+        .map(function (module) {
+            return new ModuleMetadata(pluginInfo.id, module);
+        })
+        .filter(function (metadata) {
+            // Filter out modules which are already added to metadata
+            return installedPaths.indexOf(metadata.file) === -1;
+        });
 
     this.root.modules = installedModules.concat(modulesToInstall);
 
@@ -123,7 +122,7 @@ PlatformJson.prototype.addPluginMetadata = function (pluginInfo) {
     return this;
 };
 
-PlatformJson.prototype.removePlugin = function(pluginId, isTopLevel) {
+PlatformJson.prototype.removePlugin = function (pluginId, isTopLevel) {
     var pluginsList = isTopLevel ?
         this.root.installed_plugins :
         this.root.dependent_plugins;
@@ -144,16 +143,16 @@ PlatformJson.prototype.removePlugin = function(pluginId, isTopLevel) {
  */
 PlatformJson.prototype.removePluginMetadata = function (pluginInfo) {
     var modulesToRemove = pluginInfo.getJsModules(this.platform)
-    .map(function (jsModule) {
-        return  ['plugins', pluginInfo.id, jsModule.src].join('/');
-    });
+        .map(function (jsModule) {
+            return ['plugins', pluginInfo.id, jsModule.src].join('/');
+        });
 
     var installedModules = this.root.modules || [];
     this.root.modules = installedModules
-    .filter(function (installedModule) {
-        // Leave only those metadatas which 'file' is not in removed modules
-        return (modulesToRemove.indexOf(installedModule.file) === -1);
-    });
+        .filter(function (installedModule) {
+            // Leave only those metadatas which 'file' is not in removed modules
+            return (modulesToRemove.indexOf(installedModule.file) === -1);
+        });
 
     if (this.root.plugin_metadata) {
         delete this.root.plugin_metadata[pluginInfo.id];
@@ -162,12 +161,12 @@ PlatformJson.prototype.removePluginMetadata = function (pluginInfo) {
     return this;
 };
 
-PlatformJson.prototype.addInstalledPluginToPrepareQueue = function(pluginDirName, vars, is_top_level, force) {
-    this.root.prepare_queue.installed.push({'plugin':pluginDirName, 'vars':vars, 'topLevel':is_top_level, 'force':force});
+PlatformJson.prototype.addInstalledPluginToPrepareQueue = function (pluginDirName, vars, is_top_level, force) {
+    this.root.prepare_queue.installed.push({'plugin': pluginDirName, 'vars': vars, 'topLevel': is_top_level, 'force': force});
 };
 
-PlatformJson.prototype.addUninstalledPluginToPrepareQueue = function(pluginId, is_top_level) {
-    this.root.prepare_queue.uninstalled.push({'plugin':pluginId, 'id':pluginId, 'topLevel':is_top_level});
+PlatformJson.prototype.addUninstalledPluginToPrepareQueue = function (pluginId, is_top_level) {
+    this.root.prepare_queue.uninstalled.push({'plugin': pluginId, 'id': pluginId, 'topLevel': is_top_level});
 };
 
 /**
@@ -177,7 +176,7 @@ PlatformJson.prototype.addUninstalledPluginToPrepareQueue = function(pluginId, i
  * @param  {String} pluginId A plugin id to make top-level.
  * @return {PlatformJson} PlatformJson instance.
  */
-PlatformJson.prototype.makeTopLevel = function(pluginId) {
+PlatformJson.prototype.makeTopLevel = function (pluginId) {
     var plugin = this.root.dependent_plugins[pluginId];
     if (plugin) {
         delete this.root.dependent_plugins[pluginId];
@@ -195,10 +194,10 @@ PlatformJson.prototype.makeTopLevel = function(pluginId) {
 PlatformJson.prototype.generateMetadata = function () {
     return [
         'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {',
-        'module.exports = ' + JSON.stringify(this.root.modules, null, 4) + ';',
+        'module.exports = ' + JSON.stringify(this.root.modules, null, 2) + ';',
         'module.exports.metadata = ',
         '// TOP OF METADATA',
-        JSON.stringify(this.root.plugin_metadata, null, 4) + ';',
+        JSON.stringify(this.root.plugin_metadata, null, 2) + ';',
         '// BOTTOM OF METADATA',
         '});' // Close cordova.define.
     ].join('\n');
@@ -220,8 +219,8 @@ PlatformJson.prototype.generateAndSaveMetadata = function (destination) {
 };
 
 // convert a munge from the old format ([file][parent][xml] = count) to the current one
-function fix_munge(root) {
-    root.prepare_queue = root.prepare_queue || {installed:[], uninstalled:[]};
+function fix_munge (root) {
+    root.prepare_queue = root.prepare_queue || {installed: [], uninstalled: []};
     root.config_munge = root.config_munge || {files: {}};
     root.installed_plugins = root.installed_plugins || {};
     root.dependent_plugins = root.dependent_plugins || {};
@@ -260,15 +259,15 @@ function ModuleMetadata (pluginId, jsModule) {
     if (!pluginId) throw new TypeError('pluginId argument must be a valid plugin id');
     if (!jsModule.src && !jsModule.name) throw new TypeError('jsModule argument must contain src or/and name properties');
 
-    this.id  = pluginId + '.' + ( jsModule.name || jsModule.src.match(/([^\/]+)\.js/)[1] );
+    this.id = pluginId + '.' + (jsModule.name || jsModule.src.match(/([^\/]+)\.js/)[1]); /* eslint no-useless-escape: 0 */
     this.file = ['plugins', pluginId, jsModule.src].join('/');
     this.pluginId = pluginId;
 
     if (jsModule.clobbers && jsModule.clobbers.length > 0) {
-        this.clobbers = jsModule.clobbers.map(function(o) { return o.target; });
+        this.clobbers = jsModule.clobbers.map(function (o) { return o.target; });
     }
     if (jsModule.merges && jsModule.merges.length > 0) {
-        this.merges = jsModule.merges.map(function(o) { return o.target; });
+        this.merges = jsModule.merges.map(function (o) { return o.target; });
     }
     if (jsModule.runs) {
         this.runs = true;
diff --git a/node_modules/cordova-common/src/PluginInfo/PluginInfo.js b/node_modules/cordova-common/src/PluginInfo/PluginInfo.js
index 44501fa..7e9754d 100644
--- a/node_modules/cordova-common/src/PluginInfo/PluginInfo.js
+++ b/node_modules/cordova-common/src/PluginInfo/PluginInfo.js
@@ -17,8 +17,6 @@
     under the License.
 */
 
-/* jshint sub:true, laxcomma:true, laxbreak:true */
-
 /*
 A class for holidng the information currently stored in plugin.xml
 It should also be able to answer questions like whether the plugin
@@ -27,14 +25,12 @@ is compatible with a given engine version.
 TODO (kamrik): refactor this to not use sync functions and return promises.
 */
 
+var path = require('path');
+var fs = require('fs');
+var xml_helpers = require('../util/xml-helpers');
+var CordovaError = require('../CordovaError/CordovaError');
 
-var path = require('path')
-  , fs = require('fs')
-  , xml_helpers = require('../util/xml-helpers')
-  , CordovaError = require('../CordovaError/CordovaError')
-  ;
-
-function PluginInfo(dirname) {
+function PluginInfo (dirname) {
     var self = this;
 
     // METHODS
@@ -45,15 +41,15 @@ function PluginInfo(dirname) {
     // Used to require a variable to be specified via --variable when installing the plugin.
     // returns { key : default | null}
     self.getPreferences = getPreferences;
-    function getPreferences(platform) {
+    function getPreferences (platform) {
         return _getTags(self._et, 'preference', platform, _parsePreference)
-        .reduce(function (preferences, pref) {
-            preferences[pref.preference] = pref.default;
-            return preferences;
-        }, {});
+            .reduce(function (preferences, pref) {
+                preferences[pref.preference] = pref.default;
+                return preferences;
+            }, {});
     }
 
-    function _parsePreference(prefTag) {
+    function _parsePreference (prefTag) {
         var name = prefTag.attrib.name.toUpperCase();
         var def = prefTag.attrib.default || null;
         return {preference: name, default: def};
@@ -61,16 +57,16 @@ function PluginInfo(dirname) {
 
     // <asset>
     self.getAssets = getAssets;
-    function getAssets(platform) {
+    function getAssets (platform) {
         var assets = _getTags(self._et, 'asset', platform, _parseAsset);
         return assets;
     }
 
-    function _parseAsset(tag) {
+    function _parseAsset (tag) {
         var src = tag.attrib.src;
         var target = tag.attrib.target;
 
-        if ( !src || !target) {
+        if (!src || !target) {
             var msg =
                 'Malformed <asset> tag. Both "src" and "target" attributes'
                 + 'must be specified in\n'
@@ -87,7 +83,6 @@ function PluginInfo(dirname) {
         return asset;
     }
 
-
     // <dependency>
     // Example:
     // <dependency id="com.plugin.id"
@@ -95,27 +90,28 @@ function PluginInfo(dirname) {
     //     commit="428931ada3891801"
     //     subdir="some/path/here" />
     self.getDependencies = getDependencies;
-    function getDependencies(platform) {
+    function getDependencies (platform) {
         var deps = _getTags(
-                self._et,
-                'dependency',
-                platform,
-                _parseDependency
+            self._et,
+            'dependency',
+            platform,
+            _parseDependency
         );
         return deps;
     }
 
-    function _parseDependency(tag) {
+    function _parseDependency (tag) {
         var dep =
-            { id : tag.attrib.id
-            , url : tag.attrib.url || ''
-            , subdir : tag.attrib.subdir || ''
-            , commit : tag.attrib.commit
+            { id: tag.attrib.id,
+                version: tag.attrib.version || '',
+                url: tag.attrib.url || '',
+                subdir: tag.attrib.subdir || '',
+                commit: tag.attrib.commit
             };
 
         dep.git_ref = dep.commit;
 
-        if ( !dep.id ) {
+        if (!dep.id) {
             var msg =
                 '<dependency> tag is missing id attribute in '
                 + self.filepath
@@ -125,52 +121,51 @@ function PluginInfo(dirname) {
         return dep;
     }
 
-
     // <config-file> tag
     self.getConfigFiles = getConfigFiles;
-    function getConfigFiles(platform) {
+    function getConfigFiles (platform) {
         var configFiles = _getTags(self._et, 'config-file', platform, _parseConfigFile);
         return configFiles;
     }
 
-    function _parseConfigFile(tag) {
+    function _parseConfigFile (tag) {
         var configFile =
-            { target : tag.attrib['target']
-            , parent : tag.attrib['parent']
-            , after : tag.attrib['after']
-            , xmls : tag.getchildren()
-            // To support demuxing via versions
-            , versions : tag.attrib['versions']
-            , deviceTarget: tag.attrib['device-target']
+            { target: tag.attrib['target'],
+                parent: tag.attrib['parent'],
+                after: tag.attrib['after'],
+                xmls: tag.getchildren(),
+                // To support demuxing via versions
+                versions: tag.attrib['versions'],
+                deviceTarget: tag.attrib['device-target']
             };
         return configFile;
     }
 
     self.getEditConfigs = getEditConfigs;
-    function getEditConfigs(platform) {
+    function getEditConfigs (platform) {
         var editConfigs = _getTags(self._et, 'edit-config', platform, _parseEditConfigs);
         return editConfigs;
     }
 
-    function _parseEditConfigs(tag) {
+    function _parseEditConfigs (tag) {
         var editConfig =
-        { file : tag.attrib['file']
-        , target : tag.attrib['target']
-        , mode : tag.attrib['mode']
-        , xmls : tag.getchildren()
-        };
+            { file: tag.attrib['file'],
+                target: tag.attrib['target'],
+                mode: tag.attrib['mode'],
+                xmls: tag.getchildren()
+            };
         return editConfig;
     }
 
     // <info> tags, both global and within a <platform>
     // TODO (kamrik): Do we ever use <info> under <platform>? Example wanted.
     self.getInfo = getInfo;
-    function getInfo(platform) {
+    function getInfo (platform) {
         var infos = _getTags(
-                self._et,
-                'info',
-                platform,
-                function(elem) { return elem.text; }
+            self._et,
+            'info',
+            platform,
+            function (elem) { return elem.text; }
         );
         // Filter out any undefined or empty strings.
         infos = infos.filter(Boolean);
@@ -182,12 +177,12 @@ function PluginInfo(dirname) {
     // <source-file src="src/ios/someLib.a" framework="true" />
     // <source-file src="src/ios/someLib.a" compiler-flags="-fno-objc-arc" />
     self.getSourceFiles = getSourceFiles;
-    function getSourceFiles(platform) {
+    function getSourceFiles (platform) {
         var sourceFiles = _getTagsInPlatform(self._et, 'source-file', platform, _parseSourceFile);
         return sourceFiles;
     }
 
-    function _parseSourceFile(tag) {
+    function _parseSourceFile (tag) {
         return {
             itemType: 'source-file',
             src: tag.attrib.src,
@@ -202,8 +197,8 @@ function PluginInfo(dirname) {
     // Example:
     // <header-file src="CDVFoo.h" />
     self.getHeaderFiles = getHeaderFiles;
-    function getHeaderFiles(platform) {
-        var headerFiles = _getTagsInPlatform(self._et, 'header-file', platform, function(tag) {
+    function getHeaderFiles (platform) {
+        var headerFiles = _getTagsInPlatform(self._et, 'header-file', platform, function (tag) {
             return {
                 itemType: 'header-file',
                 src: tag.attrib.src,
@@ -217,8 +212,8 @@ function PluginInfo(dirname) {
     // Example:
     // <resource-file src="FooPluginStrings.xml" target="res/values/FooPluginStrings.xml" device-target="win" arch="x86" versions="&gt;=8.1" />
     self.getResourceFiles = getResourceFiles;
-    function getResourceFiles(platform) {
-        var resourceFiles = _getTagsInPlatform(self._et, 'resource-file', platform, function(tag) {
+    function getResourceFiles (platform) {
+        var resourceFiles = _getTagsInPlatform(self._et, 'resource-file', platform, function (tag) {
             return {
                 itemType: 'resource-file',
                 src: tag.attrib.src,
@@ -236,8 +231,8 @@ function PluginInfo(dirname) {
     // Example:
     // <lib-file src="src/BlackBerry10/native/device/libfoo.so" arch="device" />
     self.getLibFiles = getLibFiles;
-    function getLibFiles(platform) {
-        var libFiles = _getTagsInPlatform(self._et, 'lib-file', platform, function(tag) {
+    function getLibFiles (platform) {
+        var libFiles = _getTagsInPlatform(self._et, 'lib-file', platform, function (tag) {
             return {
                 itemType: 'lib-file',
                 src: tag.attrib.src,
@@ -254,16 +249,16 @@ function PluginInfo(dirname) {
     // Example:
     // <hook type="before_build" src="scripts/beforeBuild.js" />
     self.getHookScripts = getHookScripts;
-    function getHookScripts(hook, platforms) {
-        var scriptElements =  self._et.findall('./hook');
+    function getHookScripts (hook, platforms) {
+        var scriptElements = self._et.findall('./hook');
 
-        if(platforms) {
+        if (platforms) {
             platforms.forEach(function (platform) {
                 scriptElements = scriptElements.concat(self._et.findall('./platform[@name="' + platform + '"]/hook'));
             });
         }
 
-        function filterScriptByHookType(el) {
+        function filterScriptByHookType (el) {
             return el.attrib.src && el.attrib.type && el.attrib.type.toLowerCase() === hook;
         }
 
@@ -271,26 +266,26 @@ function PluginInfo(dirname) {
     }
 
     self.getJsModules = getJsModules;
-    function getJsModules(platform) {
+    function getJsModules (platform) {
         var modules = _getTags(self._et, 'js-module', platform, _parseJsModule);
         return modules;
     }
 
-    function _parseJsModule(tag) {
+    function _parseJsModule (tag) {
         var ret = {
             itemType: 'js-module',
             name: tag.attrib.name,
             src: tag.attrib.src,
-            clobbers: tag.findall('clobbers').map(function(tag) { return { target: tag.attrib.target }; }),
-            merges: tag.findall('merges').map(function(tag) { return { target: tag.attrib.target }; }),
+            clobbers: tag.findall('clobbers').map(function (tag) { return { target: tag.attrib.target }; }),
+            merges: tag.findall('merges').map(function (tag) { return { target: tag.attrib.target }; }),
             runs: tag.findall('runs').length > 0
         };
 
         return ret;
     }
 
-    self.getEngines = function() {
-        return self._et.findall('engines/engine').map(function(n) {
+    self.getEngines = function () {
+        return self._et.findall('engines/engine').map(function (n) {
             return {
                 name: n.attrib.name,
                 version: n.attrib.version,
@@ -300,25 +295,45 @@ function PluginInfo(dirname) {
         });
     };
 
-    self.getPlatforms = function() {
-        return self._et.findall('platform').map(function(n) {
+    self.getPlatforms = function () {
+        return self._et.findall('platform').map(function (n) {
             return { name: n.attrib.name };
         });
     };
 
-    self.getPlatformsArray = function() {
-        return self._et.findall('platform').map(function(n) {
+    self.getPlatformsArray = function () {
+        return self._et.findall('platform').map(function (n) {
             return n.attrib.name;
         });
     };
-    self.getFrameworks = function(platform) {
-        return _getTags(self._et, 'framework', platform, function(el) {
+
+    self.getFrameworks = function (platform, options) {
+        return _getTags(self._et, 'framework', platform, function (el) {
+            var src = el.attrib.src;
+            if (options) {
+                var vars = options.cli_variables || {};
+
+                if (Object.keys(vars).length === 0) {
+                    // get variable defaults from plugin.xml for removal
+                    vars = self.getPreferences(platform);
+                }
+                var regExp;
+                // Iterate over plugin variables.
+                // Replace them in framework src if they exist
+                Object.keys(vars).forEach(function (name) {
+                    if (vars[name]) {
+                        regExp = new RegExp('\\$' + name, 'g');
+                        src = src.replace(regExp, vars[name]);
+                    }
+                });
+            }
             var ret = {
                 itemType: 'framework',
                 type: el.attrib.type,
                 parent: el.attrib.parent,
                 custom: isStrTrue(el.attrib.custom),
-                src: el.attrib.src,
+                embed: isStrTrue(el.attrib.embed),
+                src: src,
                 spec: el.attrib.spec,
                 weak: isStrTrue(el.attrib.weak),
                 versions: el.attrib.versions,
@@ -332,22 +347,21 @@ function PluginInfo(dirname) {
     };
 
     self.getFilesAndFrameworks = getFilesAndFrameworks;
-    function getFilesAndFrameworks(platform) {
+    function getFilesAndFrameworks (platform, options) {
         // Please avoid changing the order of the calls below, files will be
         // installed in this order.
         var items = [].concat(
             self.getSourceFiles(platform),
             self.getHeaderFiles(platform),
             self.getResourceFiles(platform),
-            self.getFrameworks(platform),
+            self.getFrameworks(platform, options),
             self.getLibFiles(platform)
         );
         return items;
     }
-    ///// End of PluginInfo methods /////
-
+    /// // End of PluginInfo methods /////
 
-    ///// PluginInfo Constructor logic  /////
+    /// // PluginInfo Constructor logic  /////
     self.filepath = path.join(dirname, 'plugin.xml');
     if (!fs.existsSync(self.filepath)) {
         throw new CordovaError('Cannot find plugin.xml for plugin "' + path.basename(dirname) + '". Please try adding it again.');
@@ -368,18 +382,18 @@ function PluginInfo(dirname) {
     self.keywords = pelem.findtext('keywords');
     self.info = pelem.findtext('info');
     if (self.keywords) {
-        self.keywords = self.keywords.split(',').map( function(s) { return s.trim(); } );
+        self.keywords = self.keywords.split(',').map(function (s) { return s.trim(); });
     }
     self.getKeywordsAndPlatforms = function () {
         var ret = self.keywords || [];
         return ret.concat('ecosystem:cordova').concat(addCordova(self.getPlatformsArray()));
     };
-}  // End of PluginInfo constructor.
+} // End of PluginInfo constructor.
 
 // Helper function used to prefix every element of an array with cordova-
 // Useful when we want to modify platforms to be cordova-platform
-function addCordova(someArray) {
-    var newArray = someArray.map(function(element) {
+function addCordova (someArray) {
+    var newArray = someArray.map(function (element) {
         return 'cordova-' + element;
     });
     return newArray;
@@ -389,37 +403,37 @@ function addCordova(someArray) {
 // Get all elements of a given name. Both in root and in platform sections
 // for the given platform. If transform is given and is a function, it is
 // applied to each element.
-function _getTags(pelem, tag, platform, transform) {
+function _getTags (pelem, tag, platform, transform) {
     var platformTag = pelem.find('./platform[@name="' + platform + '"]');
     var tagsInRoot = pelem.findall(tag);
     tagsInRoot = tagsInRoot || [];
     var tagsInPlatform = platformTag ? platformTag.findall(tag) : [];
     var tags = tagsInRoot.concat(tagsInPlatform);
-    if ( typeof transform === 'function' ) {
+    if (typeof transform === 'function') {
         tags = tags.map(transform);
     }
     return tags;
 }
 
 // Same as _getTags() but only looks inside a platform section.
-function _getTagsInPlatform(pelem, tag, platform, transform) {
+function _getTagsInPlatform (pelem, tag, platform, transform) {
     var platformTag = pelem.find('./platform[@name="' + platform + '"]');
     var tags = platformTag ? platformTag.findall(tag) : [];
-    if ( typeof transform === 'function' ) {
+    if (typeof transform === 'function') {
         tags = tags.map(transform);
     }
     return tags;
 }
 
 // Check if x is a string 'true'.
-function isStrTrue(x) {
-    return String(x).toLowerCase() == 'true';
+function isStrTrue (x) {
+    return String(x).toLowerCase() === 'true';
 }
 
 module.exports = PluginInfo;
 // Backwards compat:
 PluginInfo.PluginInfo = PluginInfo;
-PluginInfo.loadPluginsDir = function(dir) {
+PluginInfo.loadPluginsDir = function (dir) {
     var PluginInfoProvider = require('./PluginInfoProvider');
     return new PluginInfoProvider().getAllWithinSearchPath(dir);
 };
diff --git a/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js b/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js
index 6240119..5d3f329 100644
--- a/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js
+++ b/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js
@@ -24,12 +24,12 @@ var path = require('path');
 var PluginInfo = require('./PluginInfo');
 var events = require('../events');
 
-function PluginInfoProvider() {
+function PluginInfoProvider () {
     this._cache = {};
     this._getAllCache = {};
 }
 
-PluginInfoProvider.prototype.get = function(dirName) {
+PluginInfoProvider.prototype.get = function (dirName) {
     var absPath = path.resolve(dirName);
     if (!this._cache[absPath]) {
         this._cache[absPath] = new PluginInfo(dirName);
@@ -39,7 +39,7 @@ PluginInfoProvider.prototype.get = function(dirName) {
 
 // Normally you don't need to put() entries, but it's used
 // when copying plugins, and in unit tests.
-PluginInfoProvider.prototype.put = function(pluginInfo) {
+PluginInfoProvider.prototype.put = function (pluginInfo) {
     var absPath = path.resolve(pluginInfo.dir);
     this._cache[absPath] = pluginInfo;
 };
@@ -48,7 +48,7 @@ PluginInfoProvider.prototype.put = function(pluginInfo) {
 // Given a dir containing multiple plugins, create a PluginInfo object for
 // each of them and return as array.
 // Should load them all in parallel and return a promise, but not yet.
-PluginInfoProvider.prototype.getAllWithinSearchPath = function(dirName) {
+PluginInfoProvider.prototype.getAllWithinSearchPath = function (dirName) {
     var absPath = path.resolve(dirName);
     if (!this._getAllCache[absPath]) {
         this._getAllCache[absPath] = getAllHelper(absPath, this);
@@ -56,8 +56,8 @@ PluginInfoProvider.prototype.getAllWithinSearchPath = function(dirName) {
     return this._getAllCache[absPath];
 };
 
-function getAllHelper(absPath, provider) {
-    if (!fs.existsSync(absPath)){
+function getAllHelper (absPath, provider) {
+    if (!fs.existsSync(absPath)) {
         return [];
     }
     // If dir itself is a plugin, return it in an array with one element.
@@ -66,7 +66,7 @@ function getAllHelper(absPath, provider) {
     }
     var subdirs = fs.readdirSync(absPath);
     var plugins = [];
-    subdirs.forEach(function(subdir) {
+    subdirs.forEach(function (subdir) {
         var d = path.join(absPath, subdir);
         if (fs.existsSync(path.join(d, 'plugin.xml'))) {
             try {
diff --git a/node_modules/cordova-common/src/PluginManager.js b/node_modules/cordova-common/src/PluginManager.js
index e8968f1..0097db4 100644
--- a/node_modules/cordova-common/src/PluginManager.js
+++ b/node_modules/cordova-common/src/PluginManager.js
@@ -36,7 +36,7 @@ var PluginInfoProvider = require('./PluginInfo/PluginInfoProvider');
  * @param {Object} locations - Platform files and directories
  * @param {IDEProject} ideProject The IDE project to add/remove plugin changes to/from
  */
-function PluginManager(platform, locations, ideProject) {
+function PluginManager (platform, locations, ideProject) {
     this.platform = platform;
     this.locations = locations;
     this.project = ideProject;
@@ -45,7 +45,6 @@ function PluginManager(platform, locations, ideProject) {
     this.munger = new PlatformMunger(platform, locations.root, platformJson, new PluginInfoProvider());
 }
 
-
 /**
  * @constructs PluginManager
  * A convenience shortcut to new PluginManager(...)
@@ -55,7 +54,7 @@ function PluginManager(platform, locations, ideProject) {
  * @param {IDEProject} ideProject The IDE project to add/remove plugin changes to/from
  * @returns new PluginManager instance
  */
-PluginManager.get = function(platform, locations, ideProject) {
+PluginManager.get = function (platform, locations, ideProject) {
     return new PluginManager(platform, locations, ideProject);
 };
 
@@ -82,11 +81,9 @@ module.exports = PluginManager;
  * @returns {Promise} Returns a Q promise, either resolved in case of success, rejected otherwise.
  */
 PluginManager.prototype.doOperation = function (operation, plugin, options) {
-    if (operation !== PluginManager.INSTALL && operation !== PluginManager.UNINSTALL)
-        return Q.reject(new CordovaError('The parameter is incorrect. The opeation must be either "add" or "remove"'));
+    if (operation !== PluginManager.INSTALL && operation !== PluginManager.UNINSTALL) { return Q.reject(new CordovaError('The parameter is incorrect. The opeation must be either "add" or "remove"')); }
 
-    if (!plugin || plugin.constructor.name !== 'PluginInfo')
-        return Q.reject(new CordovaError('The parameter is incorrect. The first parameter should be a PluginInfo instance'));
+    if (!plugin || plugin.constructor.name !== 'PluginInfo') { return Q.reject(new CordovaError('The parameter is incorrect. The first parameter should be a PluginInfo instance')); }
 
     // Set default to empty object to play safe when accesing properties
     options = options || {};
@@ -95,52 +92,52 @@ PluginManager.prototype.doOperation = function (operation, plugin, options) {
     var actions = new ActionStack();
 
     // gather all files need to be handled during operation ...
-    plugin.getFilesAndFrameworks(this.platform)
+    plugin.getFilesAndFrameworks(this.platform, options)
         .concat(plugin.getAssets(this.platform))
         .concat(plugin.getJsModules(this.platform))
-    // ... put them into stack ...
-    .forEach(function(item) {
-        var installer = self.project.getInstaller(item.itemType);
-        var uninstaller = self.project.getUninstaller(item.itemType);
-        var actionArgs = [item, plugin, self.project, options];
-
-        var action;
-        if (operation === PluginManager.INSTALL) {
-            action = actions.createAction.apply(actions, [installer, actionArgs, uninstaller, actionArgs]);
-        } else /* op === PluginManager.UNINSTALL */{
-            action = actions.createAction.apply(actions, [uninstaller, actionArgs, installer, actionArgs]);
-        }
-        actions.push(action);
-    });
+        // ... put them into stack ...
+        .forEach(function (item) {
+            var installer = self.project.getInstaller(item.itemType);
+            var uninstaller = self.project.getUninstaller(item.itemType);
+            var actionArgs = [item, plugin, self.project, options];
+
+            var action;
+            if (operation === PluginManager.INSTALL) {
+                action = actions.createAction.apply(actions, [installer, actionArgs, uninstaller, actionArgs]); /* eslint no-useless-call: 0 */
+            } else /* op === PluginManager.UNINSTALL */{
+                action = actions.createAction.apply(actions, [uninstaller, actionArgs, installer, actionArgs]); /* eslint no-useless-call: 0 */
+            }
+            actions.push(action);
+        });
 
     // ... and run through the action stack
     return actions.process(this.platform)
-    .then(function () {
-        if (self.project.write) {
-            self.project.write();
-        }
-
-        if (operation === PluginManager.INSTALL) {
-            // Ignore passed `is_top_level` option since platform itself doesn't know
-            // anything about managing dependencies - it's responsibility of caller.
-            self.munger.add_plugin_changes(plugin, options.variables, /*is_top_level=*/true, /*should_increment=*/true, options.force);
-            self.munger.platformJson.addPluginMetadata(plugin);
-        } else {
-            self.munger.remove_plugin_changes(plugin, /*is_top_level=*/true);
-            self.munger.platformJson.removePluginMetadata(plugin);
-        }
-
-        // Save everything (munge and plugin/modules metadata)
-        self.munger.save_all();
-
-        var metadata = self.munger.platformJson.generateMetadata();
-        fs.writeFileSync(path.join(self.locations.www, 'cordova_plugins.js'), metadata, 'utf-8');
-
-        // CB-11022 save plugin metadata to both www and platform_www if options.usePlatformWww is specified
-        if (options.usePlatformWww) {
-            fs.writeFileSync(path.join(self.locations.platformWww, 'cordova_plugins.js'), metadata, 'utf-8');
-        }
-    });
+        .then(function () {
+            if (self.project.write) {
+                self.project.write();
+            }
+
+            if (operation === PluginManager.INSTALL) {
+                // Ignore passed `is_top_level` option since platform itself doesn't know
+                // anything about managing dependencies - it's responsibility of caller.
+                self.munger.add_plugin_changes(plugin, options.variables, /* is_top_level= */true, /* should_increment= */true, options.force);
+                self.munger.platformJson.addPluginMetadata(plugin);
+            } else {
+                self.munger.remove_plugin_changes(plugin, /* is_top_level= */true);
+                self.munger.platformJson.removePluginMetadata(plugin);
+            }
+
+            // Save everything (munge and plugin/modules metadata)
+            self.munger.save_all();
+
+            var metadata = self.munger.platformJson.generateMetadata();
+            fs.writeFileSync(path.join(self.locations.www, 'cordova_plugins.js'), metadata, 'utf-8');
+
+            // CB-11022 save plugin metadata to both www and platform_www if options.usePlatformWww is specified
+            if (options.usePlatformWww) {
+                fs.writeFileSync(path.join(self.locations.platformWww, 'cordova_plugins.js'), metadata, 'utf-8');
+            }
+        });
 };
 
 PluginManager.prototype.addPlugin = function (plugin, installOptions) {
diff --git a/node_modules/cordova-common/src/events.js b/node_modules/cordova-common/src/events.js
index e702bd8..7038643 100644
--- a/node_modules/cordova-common/src/events.js
+++ b/node_modules/cordova-common/src/events.js
@@ -20,6 +20,7 @@
 var EventEmitter = require('events').EventEmitter;
 
 var INSTANCE = new EventEmitter();
+INSTANCE.setMaxListeners(20);
 var EVENTS_RECEIVER;
 
 module.exports = INSTANCE;
@@ -39,8 +40,7 @@ module.exports.forwardEventsTo = function (eventEmitter) {
         return;
     }
 
-    if (!(eventEmitter instanceof EventEmitter))
-        throw new Error('Cordova events can be redirected to another EventEmitter instance only');
+    if (!(eventEmitter instanceof EventEmitter)) { throw new Error('Cordova events can be redirected to another EventEmitter instance only'); }
 
     // CB-10940 Skipping forwarding to self to avoid infinite recursion.
     // This is the case when the modules are npm-linked.
diff --git a/node_modules/cordova-common/src/superspawn.js b/node_modules/cordova-common/src/superspawn.js
index a3f1431..424934e 100644
--- a/node_modules/cordova-common/src/superspawn.js
+++ b/node_modules/cordova-common/src/superspawn.js
@@ -24,12 +24,12 @@ var _ = require('underscore');
 var Q = require('q');
 var shell = require('shelljs');
 var events = require('./events');
-var iswin32 = process.platform == 'win32';
+var iswin32 = process.platform === 'win32';
 
 // On Windows, spawn() for batch files requires absolute path & having the extension.
-function resolveWindowsExe(cmd) {
+function resolveWindowsExe (cmd) {
     var winExtensions = ['.exe', '.bat', '.cmd', '.js', '.vbs'];
-    function isValidExe(c) {
+    function isValidExe (c) {
         return winExtensions.indexOf(path.extname(c)) !== -1 && fs.existsSync(c);
     }
     if (isValidExe(cmd)) {
@@ -37,7 +37,7 @@ function resolveWindowsExe(cmd) {
     }
     cmd = shell.which(cmd) || cmd;
     if (!isValidExe(cmd)) {
-        winExtensions.some(function(ext) {
+        winExtensions.some(function (ext) {
             if (fs.existsSync(cmd + ext)) {
                 cmd = cmd + ext;
                 return true;
@@ -47,7 +47,7 @@ function resolveWindowsExe(cmd) {
     return cmd;
 }
 
-function maybeQuote(a) {
+function maybeQuote (a) {
     if (/^[^"].*[ &].*[^"]/.test(a)) return '"' + a + '"';
     return a;
 }
@@ -85,7 +85,7 @@ function maybeQuote(a) {
  *       'stderr': ...
  *   }
  */
-exports.spawn = function(cmd, args, opts) {
+exports.spawn = function (cmd, args, opts) {
     args = args || [];
     opts = opts || {};
     var spawnOpts = {};
@@ -95,7 +95,7 @@ exports.spawn = function(cmd, args, opts) {
         cmd = resolveWindowsExe(cmd);
         // If we couldn't find the file, likely we'll end up failing,
         // but for things like "del", cmd will do the trick.
-        if (path.extname(cmd) != '.exe') {
+        if (path.extname(cmd) !== '.exe') {
             var cmdArgs = '"' + [cmd].concat(args).map(maybeQuote).join(' ') + '"';
             // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
             args = [['/s', '/c', cmdArgs].join(' ')];
@@ -137,7 +137,7 @@ exports.spawn = function(cmd, args, opts) {
 
     if (child.stdout) {
         child.stdout.setEncoding('utf8');
-        child.stdout.on('data', function(data) {
+        child.stdout.on('data', function (data) {
             capturedOut += data;
             d.notify({'stdout': data});
         });
@@ -145,7 +145,7 @@ exports.spawn = function(cmd, args, opts) {
 
     if (child.stderr) {
         child.stderr.setEncoding('utf8');
-        child.stderr.on('data', function(data) {
+        child.stderr.on('data', function (data) {
             capturedErr += data;
             d.notify({'stderr': data});
         });
@@ -153,10 +153,10 @@ exports.spawn = function(cmd, args, opts) {
 
     child.on('close', whenDone);
     child.on('error', whenDone);
-    function whenDone(arg) {
+    function whenDone (arg) {
         child.removeListener('close', whenDone);
         child.removeListener('error', whenDone);
-        var code = typeof arg == 'number' ? arg : arg && arg.code;
+        var code = typeof arg === 'number' ? arg : arg && arg.code;
 
         events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args);
         if (code === 0) {
@@ -167,6 +167,12 @@ exports.spawn = function(cmd, args, opts) {
                 errMsg += ' Error output:\n' + capturedErr.trim();
             }
             var err = new Error(errMsg);
+            if (capturedErr) {
+                err.stderr = capturedErr;
+            }
+            if (capturedOut) {
+                err.stdout = capturedOut;
+            }
             err.code = code;
             d.reject(err);
         }
@@ -175,10 +181,9 @@ exports.spawn = function(cmd, args, opts) {
     return d.promise;
 };
 
-exports.maybeSpawn = function(cmd, args, opts) {
+exports.maybeSpawn = function (cmd, args, opts) {
     if (fs.existsSync(cmd)) {
         return exports.spawn(cmd, args, opts);
     }
     return Q(null);
 };
-
diff --git a/node_modules/cordova-common/src/util/addProperty.js b/node_modules/cordova-common/src/util/addProperty.js
index 7dc4dc1..3e48174 100644
--- a/node_modules/cordova-common/src/util/addProperty.js
+++ b/node_modules/cordova-common/src/util/addProperty.js
@@ -17,8 +17,8 @@
        under the License.
 */
 
-module.exports = function addProperty(module, property, modulePath, obj) {
-    
+module.exports = function addProperty (module, property, modulePath, obj) {
+
     obj = obj || module.exports;
     // Add properties as getter to delay load the modules on first invocation
     Object.defineProperty(obj, property, {
diff --git a/node_modules/cordova-common/src/util/plist-helpers.js b/node_modules/cordova-common/src/util/plist-helpers.js
index 38eb31b..5ec4c1d 100644
--- a/node_modules/cordova-common/src/util/plist-helpers.js
+++ b/node_modules/cordova-common/src/util/plist-helpers.js
@@ -15,32 +15,32 @@
     KIND, either express or implied.  See the License for the
     specific language governing permissions and limitations
     under the License.
-*/ 
+*/
+/* eslint no-useless-escape: 0 */
 
 // contains PLIST utility functions
-var __     = require('underscore');
+var __ = require('underscore');
 var plist = require('plist');
 
 // adds node to doc at selector
 module.exports.graftPLIST = graftPLIST;
-function graftPLIST(doc, xml, selector) {
-    var obj = plist.parse('<plist>'+xml+'</plist>');
+function graftPLIST (doc, xml, selector) {
+    var obj = plist.parse('<plist>' + xml + '</plist>');
 
     var node = doc[selector];
-    if (node && Array.isArray(node) && Array.isArray(obj)){
+    if (node && Array.isArray(node) && Array.isArray(obj)) {
         node = node.concat(obj);
-        for (var i =0;i<node.length; i++){
-            for (var j=i+1; j<node.length; ++j) {
-              if (nodeEqual(node[i], node[j]))
-                    node.splice(j--,1);
+        for (var i = 0; i < node.length; i++) {
+            for (var j = i + 1; j < node.length; ++j) {
+                if (nodeEqual(node[i], node[j])) { node.splice(j--, 1); }
             }
         }
         doc[selector] = node;
     } else {
-        //plist uses objects for <dict>. If we have two dicts we merge them instead of
+        // plist uses objects for <dict>. If we have two dicts we merge them instead of
         // overriding the old one. See CB-6472
-        if (node && __.isObject(node) && __.isObject(obj) && !__.isDate(node) && !__.isDate(obj)){//arrays checked above
-            __.extend(obj,node);
+        if (node && __.isObject(node) && __.isObject(obj) && !__.isDate(node) && !__.isDate(obj)) { // arrays checked above
+            __.extend(obj, node);
         }
         doc[selector] = obj;
     }
@@ -50,15 +50,15 @@ function graftPLIST(doc, xml, selector) {
 
 // removes node from doc at selector
 module.exports.prunePLIST = prunePLIST;
-function prunePLIST(doc, xml, selector) {
-    var obj = plist.parse('<plist>'+xml+'</plist>');
+function prunePLIST (doc, xml, selector) {
+    var obj = plist.parse('<plist>' + xml + '</plist>');
 
     pruneOBJECT(doc, selector, obj);
 
     return true;
 }
 
-function pruneOBJECT(doc, selector, fragment) {
+function pruneOBJECT (doc, selector, fragment) {
     if (Array.isArray(fragment) && Array.isArray(doc[selector])) {
         var empty = true;
         for (var i in fragment) {
@@ -66,13 +66,11 @@ function pruneOBJECT(doc, selector, fragment) {
                 empty = pruneOBJECT(doc[selector], j, fragment[i]) && empty;
             }
         }
-        if (empty)
-        {
+        if (empty) {
             delete doc[selector];
             return true;
         }
-    }
-    else if (nodeEqual(doc[selector], fragment)) {
+    } else if (nodeEqual(doc[selector], fragment)) {
         delete doc[selector];
         return true;
     }
@@ -80,14 +78,11 @@ function pruneOBJECT(doc, selector, fragment) {
     return false;
 }
 
-function nodeEqual(node1, node2) {
-    if (typeof node1 != typeof node2)
-        return false;
-    else if (typeof node1 == 'string') {
-        node2 = escapeRE(node2).replace(new RegExp('\\$[a-zA-Z0-9-_]+','gm'),'(.*?)');
+function nodeEqual (node1, node2) {
+    if (typeof node1 !== typeof node2) { return false; } else if (typeof node1 === 'string') {
+        node2 = escapeRE(node2).replace(/\\\$\S+/gm, '(.*?)');
         return new RegExp('^' + node2 + '$').test(node1);
-    }
-    else {
+    } else {
         for (var key in node2) {
             if (!nodeEqual(node1[key], node2[key])) return false;
         }
@@ -96,6 +91,6 @@ function nodeEqual(node1, node2) {
 }
 
 // escape string for use in regex
-function escapeRE(str) {
-    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '$&');
+function escapeRE (str) {
+    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
 }
diff --git a/node_modules/cordova-common/src/util/xml-helpers.js b/node_modules/cordova-common/src/util/xml-helpers.js
index b4b0490..e2c8fd3 100644
--- a/node_modules/cordova-common/src/util/xml-helpers.js
+++ b/node_modules/cordova-common/src/util/xml-helpers.js
@@ -15,32 +15,31 @@
     KIND, either express or implied.  See the License for the
     specific language governing permissions and limitations
     under the License.
-*/ 
-
-/* jshint sub:true, laxcomma:true */
+*/
 
 /**
  * contains XML utility functions, some of which are specific to elementtree
  */
 
-var fs = require('fs')
-  , path = require('path')
-  , _ = require('underscore')
-  , et = require('elementtree')
-  ;
+var fs = require('fs');
+var path = require('path');
+var _ = require('underscore');
+var et = require('elementtree');
 
-  var ROOT = /^\/([^\/]*)/,
-      ABSOLUTE = /^\/([^\/]*)\/(.*)/;
+/* eslint-disable no-useless-escape */
+var ROOT = /^\/([^\/]*)/;
+var ABSOLUTE = /^\/([^\/]*)\/(.*)/;
+/* eslint-enable no-useless-escape */
 
 module.exports = {
     // compare two et.XML nodes, see if they match
     // compares tagName, text, attributes and children (recursively)
-    equalNodes: function(one, two) {
-        if (one.tag != two.tag) {
+    equalNodes: function (one, two) {
+        if (one.tag !== two.tag) {
             return false;
-        } else if (one.text.trim() != two.text.trim()) {
+        } else if (one.text.trim() !== two.text.trim()) {
             return false;
-        } else if (one._children.length != two._children.length) {
+        } else if (one._children.length !== two._children.length) {
             return false;
         }
 
@@ -56,13 +55,13 @@ module.exports = {
     },
 
     // adds node to doc at selector, creating parent if it doesn't exist
-    graftXML: function(doc, nodes, selector, after) {
+    graftXML: function (doc, nodes, selector, after) {
         var parent = module.exports.resolveParent(doc, selector);
         if (!parent) {
-            //Try to create the parent recursively if necessary
+            // Try to create the parent recursively if necessary
             try {
-                var parentToCreate = et.XML('<' + path.basename(selector) + '>'),
-                    parentSelector = path.dirname(selector);
+                var parentToCreate = et.XML('<' + path.basename(selector) + '>');
+                var parentSelector = path.dirname(selector);
 
                 this.graftXML(doc, [parentToCreate], parentSelector);
             } catch (e) {
@@ -78,7 +77,7 @@ module.exports = {
                 var children = parent.getchildren();
                 var insertIdx = after ? findInsertIdx(children, after) : children.length;
 
-                //TODO: replace with parent.insert after the bug in ElementTree is fixed
+                // TODO: replace with parent.insert after the bug in ElementTree is fixed
                 parent.getchildren().splice(insertIdx, 0, node);
             }
         });
@@ -88,7 +87,7 @@ module.exports = {
 
     // adds new attributes to doc at selector
     // Will only merge if attribute has not been modified already or --force is used
-    graftXMLMerge: function(doc, nodes, selector, xml) {
+    graftXMLMerge: function (doc, nodes, selector, xml) {
         var target = module.exports.resolveParent(doc, selector);
         if (!target) return false;
 
@@ -107,7 +106,7 @@ module.exports = {
 
     // overwrite all attributes to doc at selector with new attributes
     // Will only overwrite if attribute has not been modified already or --force is used
-    graftXMLOverwrite: function(doc, nodes, selector, xml) {
+    graftXMLOverwrite: function (doc, nodes, selector, xml) {
         var target = module.exports.resolveParent(doc, selector);
         if (!target) return false;
 
@@ -132,7 +131,7 @@ module.exports = {
     },
 
     // removes node from doc at selector
-    pruneXML: function(doc, nodes, selector) {
+    pruneXML: function (doc, nodes, selector) {
         var parent = module.exports.resolveParent(doc, selector);
         if (!parent) return false;
 
@@ -149,7 +148,7 @@ module.exports = {
     },
 
     // restores attributes from doc at selector
-    pruneXMLRestore: function(doc, selector, xml) {
+    pruneXMLRestore: function (doc, selector, xml) {
         var target = module.exports.resolveParent(doc, selector);
         if (!target) return false;
 
@@ -160,7 +159,7 @@ module.exports = {
         return true;
     },
 
-    prunXMLRemove: function(doc, selector, nodes) {
+    pruneXMLRemove: function (doc, selector, nodes) {
         var target = module.exports.resolveParent(doc, selector);
         if (!target) return false;
 
@@ -177,11 +176,10 @@ module.exports = {
 
     },
 
-
     parseElementtreeSync: function (filename) {
         var contents = fs.readFileSync(filename, 'utf-8');
-        if(contents) {
-            //Windows is the BOM. Skip the Byte Order Mark.
+        if (contents) {
+            // Windows is the BOM. Skip the Byte Order Mark.
             contents = contents.substring(contents.indexOf('<'));
         }
         return new et.ElementTree(et.XML(contents));
@@ -194,7 +192,7 @@ module.exports = {
         if (ROOT.test(selector)) {
             tagName = selector.match(ROOT)[1];
             // test for wildcard "any-tag" root selector
-            if (tagName == '*' || tagName === doc._root.tag) {
+            if (tagName === '*' || tagName === doc._root.tag) {
                 parent = doc._root;
 
                 // could be an absolute path, but not selecting the root
@@ -212,11 +210,12 @@ module.exports = {
     }
 };
 
-function findChild(node, parent) {
-    var matchingKids = parent.findall(node.tag)
-      , i, j;
+function findChild (node, parent) {
+    var matchingKids = parent.findall(node.tag);
+    var i;
+    var j;
 
-    for (i = 0, j = matchingKids.length ; i < j ; i++) {
+    for (i = 0, j = matchingKids.length; i < j; i++) {
         if (module.exports.equalNodes(node, matchingKids[i])) {
             return matchingKids[i];
         }
@@ -224,13 +223,13 @@ function findChild(node, parent) {
     return null;
 }
 
-function uniqueChild(node, parent) {
-    var matchingKids = parent.findall(node.tag)
-      , i = 0;
+function uniqueChild (node, parent) {
+    var matchingKids = parent.findall(node.tag);
+    var i = 0;
 
     if (matchingKids.length === 0) {
         return true;
-    } else  {
+    } else {
         for (i; i < matchingKids.length; i++) {
             if (module.exports.equalNodes(node, matchingKids[i])) {
                 return false;
@@ -244,51 +243,51 @@ function uniqueChild(node, parent) {
 // of tags after which the insertion should be made. E.g. If we need to
 // insert an element C, and the rule is that the order of children has to be
 // As, Bs, Cs. After will be equal to "C;B;A".
-function findInsertIdx(children, after) {
-    var childrenTags = children.map(function(child) { return child.tag; });
+function findInsertIdx (children, after) {
+    var childrenTags = children.map(function (child) { return child.tag; });
     var afters = after.split(';');
-    var afterIndexes = afters.map(function(current) { return childrenTags.lastIndexOf(current); });
-    var foundIndex = _.find(afterIndexes, function(index) { return index != -1; });
+    var afterIndexes = afters.map(function (current) { return childrenTags.lastIndexOf(current); });
+    var foundIndex = _.find(afterIndexes, function (index) { return index !== -1; });
 
-    //add to the beginning if no matching nodes are found
-    return typeof foundIndex === 'undefined' ? 0 : foundIndex+1;
+    // add to the beginning if no matching nodes are found
+    return typeof foundIndex === 'undefined' ? 0 : foundIndex + 1;
 }
 
-var BLACKLIST = ['platform', 'feature','plugin','engine'];
+var BLACKLIST = ['platform', 'feature', 'plugin', 'engine'];
 var SINGLETONS = ['content', 'author', 'name'];
-function mergeXml(src, dest, platform, clobber) {
+function mergeXml (src, dest, platform, clobber) {
     // Do nothing for blacklisted tags.
-    if (BLACKLIST.indexOf(src.tag) != -1) return;
+    if (BLACKLIST.indexOf(src.tag) !== -1) return;
 
-    //Handle attributes
+    // Handle attributes
     Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
         if (clobber || !dest.attrib[attribute]) {
             dest.attrib[attribute] = src.attrib[attribute];
         }
     });
-    //Handle text
+    // Handle text
     if (src.text && (clobber || !dest.text)) {
         dest.text = src.text;
     }
-    //Handle children
+    // Handle children
     src.getchildren().forEach(mergeChild);
 
-    //Handle platform
+    // Handle platform
     if (platform) {
         src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
             platformElement.getchildren().forEach(mergeChild);
         });
     }
 
-    //Handle duplicate preference tags (by name attribute)
+    // Handle duplicate preference tags (by name attribute)
     removeDuplicatePreferences(dest);
 
     function mergeChild (srcChild) {
-        var srcTag = srcChild.tag,
-            destChild = new et.Element(srcTag),
-            foundChild,
-            query = srcTag + '',
-            shouldMerge = true;
+        var srcTag = srcChild.tag;
+        var destChild = new et.Element(srcTag);
+        var foundChild;
+        var query = srcTag + '';
+        var shouldMerge = true;
 
         if (BLACKLIST.indexOf(srcTag) !== -1) return;
 
@@ -299,11 +298,11 @@ function mergeXml(src, dest, platform, clobber) {
                 dest.remove(destChild);
             }
         } else {
-            //Check for an exact match and if you find one don't add
+            // Check for an exact match and if you find one don't add
             var mergeCandidates = dest.findall(query)
-            .filter(function (foundChild) {
-                return foundChild && textMatch(srcChild, foundChild) && attribMatch(srcChild, foundChild);
-            });
+                .filter(function (foundChild) {
+                    return foundChild && textMatch(srcChild, foundChild) && attribMatch(srcChild, foundChild);
+                });
 
             if (mergeCandidates.length > 0) {
                 destChild = mergeCandidates[0];
@@ -316,20 +315,20 @@ function mergeXml(src, dest, platform, clobber) {
         dest.append(destChild);
     }
 
-    function removeDuplicatePreferences(xml) {
+    function removeDuplicatePreferences (xml) {
         // reduce preference tags to a hashtable to remove dupes
-        var prefHash = xml.findall('preference[@name][@value]').reduce(function(previousValue, currentValue) {
+        var prefHash = xml.findall('preference[@name][@value]').reduce(function (previousValue, currentValue) {
             previousValue[ currentValue.attrib.name ] = currentValue.attrib.value;
             return previousValue;
         }, {});
 
         // remove all preferences
-        xml.findall('preference[@name][@value]').forEach(function(pref) {
+        xml.findall('preference[@name][@value]').forEach(function (pref) {
             xml.remove(pref);
         });
 
         // write new preferences
-        Object.keys(prefHash).forEach(function(key, index) {
+        Object.keys(prefHash).forEach(function (key, index) {
             var element = et.SubElement(xml, 'preference');
             element.set('name', key);
             element.set('value', this[key]);
@@ -340,24 +339,24 @@ function mergeXml(src, dest, platform, clobber) {
 // Expose for testing.
 module.exports.mergeXml = mergeXml;
 
-function textMatch(elm1, elm2) {
-    var text1 = elm1.text ? elm1.text.replace(/\s+/, '') : '',
-        text2 = elm2.text ? elm2.text.replace(/\s+/, '') : '';
+function textMatch (elm1, elm2) {
+    var text1 = elm1.text ? elm1.text.replace(/\s+/, '') : '';
+    var text2 = elm2.text ? elm2.text.replace(/\s+/, '') : '';
     return (text1 === '' || text1 === text2);
 }
 
-function attribMatch(one, two) {
+function attribMatch (one, two) {
     var oneAttribKeys = Object.keys(one.attrib);
     var twoAttribKeys = Object.keys(two.attrib);
 
-    if (oneAttribKeys.length != twoAttribKeys.length) {
+    if (oneAttribKeys.length !== twoAttribKeys.length) {
         return false;
     }
 
     for (var i = 0; i < oneAttribKeys.length; i++) {
         var attribName = oneAttribKeys[i];
 
-        if (one.attrib[attribName] != two.attrib[attribName]) {
+        if (one.attrib[attribName] !== two.attrib[attribName]) {
             return false;
         }
     }
diff --git a/package.json b/package.json
index 3aab4b8..49a6b13 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
     "eslint": "eslint bin && eslint template && eslint spec"
   },
   "dependencies": {
-    "cordova-common": "^2.0.0",
+    "cordova-common": "^2.2.1",
     "elementtree": "^0.1.6",
     "node-uuid": "^1.4.3",
     "nopt": "^3.0.4",
diff --git a/spec/unit/ConfigChanges.spec.js b/spec/unit/ConfigChanges.spec.js
index ef4591a..71ca461 100644
--- a/spec/unit/ConfigChanges.spec.js
+++ b/spec/unit/ConfigChanges.spec.js
@@ -27,10 +27,8 @@ var AppxManifest = require('../../template/cordova/lib/AppxManifest');
 var os = require('os');
 var path = require('path');
 var shell = require('shelljs');
-var rewire = require('rewire');
 
 var configChanges = require('../../template/cordova/lib/ConfigChanges');
-var pluginInfo = rewire('../../template/cordova/lib/PluginInfo.js');
 var tempDir = path.join(os.tmpdir(), 'windows');
 var WINDOWS_MANIFEST = 'package.windows.appxmanifest';
 var WINDOWS10_MANIFEST = 'package.windows10.appxmanifest';
@@ -246,7 +244,6 @@ describe('generate_plugin_config_munge for windows project', function () {
     });
 
     it('should not process change w/o target package.appxmanifest', function () {
-        var processChanges = pluginInfo.__get__('processChanges');
         var testChanges = [
             {
                 target: 'package.windows.appxmanifest'
@@ -256,20 +253,18 @@ describe('generate_plugin_config_munge for windows project', function () {
             }
         ];
 
-        var changes = processChanges(testChanges);
+        var changes = AppxManifest.processChanges(testChanges);
         expect(changes.length).toBe(4);
         expect(changes[0].target).toBe(testChanges[0].target);
     });
 
     it('should apply changes to all manifests in case of incorrect "deviceTarget" attribute', function () {
-        var processChanges = pluginInfo.__get__('processChanges');
-
         var testChanges = [{
             deviceTarget: 'wrong_device_target',
             target: 'package.appxmanifest'
         }];
 
-        var changes = processChanges(testChanges);
+        var changes = AppxManifest.processChanges(testChanges);
         expect(changes.length).toBe(3);
         expect(changes[0].target).toBe('package.windows.appxmanifest');
         expect(changes[1].target).toBe('package.phone.appxmanifest');
diff --git a/spec/unit/WindowsConfigParser.spec.js b/spec/unit/WindowsConfigParser.spec.js
index 5565b1e..926e03a 100644
--- a/spec/unit/WindowsConfigParser.spec.js
+++ b/spec/unit/WindowsConfigParser.spec.js
@@ -22,6 +22,7 @@ var et = require('elementtree');
 var xml = require('cordova-common').xmlHelpers;
 var ConfigParser = require('../../template/cordova/lib/ConfigParser');
 var ConfigParserOrig = require('cordova-common').ConfigParser;
+var AppxManifest = require('../../template/cordova/lib/AppxManifest');
 
 var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?><widget/>';
 
@@ -101,3 +102,17 @@ describe('getAllMinMaxUAPVersions method', function () {
         }
     });
 });
+
+describe('getConfigFiles method', function () {
+    var mockConfig;
+    beforeEach(function () {
+        spyOn(xml, 'parseElementtreeSync').and.returnValue(new et.ElementTree(et.XML(TEST_XML)));
+        mockConfig = new ConfigParser('/some/file');
+    });
+
+    it('should call AppxManifest.processChanges to distribute changes across manifests', function () {
+        spyOn(AppxManifest, 'processChanges').and.callThrough();
+        mockConfig.getConfigFiles('windows');
+        expect(AppxManifest.processChanges).toHaveBeenCalled();
+    });
+});
diff --git a/template/cordova/Api.js b/template/cordova/Api.js
index f086d47..b8103ca 100644
--- a/template/cordova/Api.js
+++ b/template/cordova/Api.js
@@ -25,6 +25,7 @@ var CordovaLogger = require('cordova-common').CordovaLogger;
 var PlatformMunger = require('./lib/ConfigChanges.js').PlatformMunger;
 var PlatformJson = require('cordova-common').PlatformJson;
 var PluginInfo = require('./lib/PluginInfo').PluginInfo;
+var ConfigParser = require('./lib/ConfigParser');
 var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
 
 var PLATFORM = 'windows';
@@ -172,6 +173,8 @@ Api.prototype.getPlatformInfo = function () {
  *   CordovaError instance.
  */
 Api.prototype.prepare = function (cordovaProject, prepareOptions) {
+    var configPath = cordovaProject.projectConfig.path;
+    cordovaProject.projectConfig = new ConfigParser(configPath);
     return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
 };
 
diff --git a/template/cordova/lib/AppxManifest.js b/template/cordova/lib/AppxManifest.js
index dcd9d25..acaeefd 100644
--- a/template/cordova/lib/AppxManifest.js
+++ b/template/cordova/lib/AppxManifest.js
@@ -22,6 +22,7 @@ var util = require('util');
 var et = require('elementtree');
 var path = require('path');
 var xml = require('cordova-common').xmlHelpers;
+var semver = require('semver');
 
 var UAP_RESTRICTED_CAPS = ['enterpriseAuthentication', 'sharedUserCertificates',
     'documentsLibrary', 'musicLibrary', 'picturesLibrary',
@@ -40,6 +41,24 @@ var KNOWN_ORIENTATIONS = {
     'landscape': ['landscape', 'landscapeFlipped']
 };
 
+var MANIFESTS = {
+    'windows': {
+        '8.1.0': 'package.windows.appxmanifest',
+        '10.0.0': 'package.windows10.appxmanifest'
+    },
+    'phone': {
+        '8.1.0': 'package.phone.appxmanifest',
+        '10.0.0': 'package.windows10.appxmanifest'
+    },
+    'all': {
+        '8.1.0': ['package.windows.appxmanifest', 'package.phone.appxmanifest'],
+        '10.0.0': 'package.windows10.appxmanifest'
+    }
+};
+
+var SUBSTS = ['package.phone.appxmanifest', 'package.windows.appxmanifest', 'package.windows10.appxmanifest'];
+var TARGETS = ['windows', 'phone', 'all'];
+
 /**
  * Store to cache appxmanifest files based on file location
  * @type  {Object}
@@ -120,6 +139,35 @@ AppxManifest.get = function (fileName, ignoreCache) {
     return result;
 };
 
+AppxManifest.processChanges = function (changes) {
+    var hasManifestChanges = changes.some(function (change) {
+        return change.target === 'package.appxmanifest';
+    });
+
+    if (!hasManifestChanges) {
+        return changes;
+    }
+
+    // Demux 'package.appxmanifest' into relevant platform-specific appx manifests.
+    // Only spend the cycles if there are version-specific plugin settings
+    var oldChanges = changes;
+    changes = [];
+
+    oldChanges.forEach(function (change) {
+        // Only support semver/device-target demux for package.appxmanifest
+        // Pass through in case something downstream wants to use it
+        if (change.target !== 'package.appxmanifest') {
+            changes.push(change);
+            return;
+        }
+
+        var manifestsForChange = getManifestsForChange(change);
+        changes = changes.concat(demuxChangeWithSubsts(change, manifestsForChange));
+    });
+
+    return changes;
+};
+
 /**
  * Removes manifests from cache to prevent using stale entries
  *
@@ -457,6 +505,51 @@ AppxManifest.prototype.getCapabilities = function () {
         });
 };
 
+function demuxChangeWithSubsts (change, manifestFiles) {
+    return manifestFiles.map(function (file) {
+        return createReplacement(file, change);
+    });
+}
+
+function getManifestsForChange (change) {
+    var hasTarget = (typeof change.deviceTarget !== 'undefined');
+    var hasVersion = (typeof change.versions !== 'undefined');
+
+    var targetDeviceSet = hasTarget ? change.deviceTarget : 'all';
+
+    if (TARGETS.indexOf(targetDeviceSet) === -1) {
+        // target-device couldn't be resolved, fix it up here to a valid value
+        targetDeviceSet = 'all';
+    }
+
+    // No semver/device-target for this config-file, pass it through
+    if (!(hasTarget || hasVersion)) {
+        return SUBSTS;
+    }
+
+    var knownWindowsVersionsForTargetDeviceSet = Object.keys(MANIFESTS[targetDeviceSet]);
+    return knownWindowsVersionsForTargetDeviceSet.reduce(function (manifestFiles, winver) {
+        if (hasVersion && !semver.satisfies(winver, change.versions)) {
+            return manifestFiles;
+        }
+        return manifestFiles.concat(MANIFESTS[targetDeviceSet][winver]);
+    }, []);
+}
+
+// This is a local function that creates the new replacement representing the
+// mutation.  Used to save code further down.
+function createReplacement (manifestFile, originalChange) {
+    var replacement = {
+        target: manifestFile,
+        parent: originalChange.parent,
+        after: originalChange.after,
+        xmls: originalChange.xmls,
+        versions: originalChange.versions,
+        deviceTarget: originalChange.deviceTarget
+    };
+    return replacement;
+}
+
 function isCSSColorName (color) {
     return color.indexOf('0x') === -1 && color.indexOf('#') === -1;
 }
diff --git a/template/cordova/lib/ConfigParser.js b/template/cordova/lib/ConfigParser.js
index 4a50bfb..bd2cb7f 100644
--- a/template/cordova/lib/ConfigParser.js
+++ b/template/cordova/lib/ConfigParser.js
@@ -20,6 +20,7 @@
 var util = require('util');
 var Version = require('./Version');
 var ConfigParser = require('cordova-common').ConfigParser;
+var AppxManifest = require('./AppxManifest');
 
 var BASE_UAP_VERSION = new Version(10, 0, 10240, 0);
 
@@ -50,6 +51,11 @@ WindowsConfigParser.prototype.windows_packageVersion = function () {
     return this.doc.getroot().attrib['windows-packageVersion'];
 };
 
+WindowsConfigParser.prototype.getConfigFiles = function (platform) {
+    var configFiles = ConfigParser.prototype.getConfigFiles.call(this, platform);
+    return AppxManifest.processChanges(configFiles);
+};
+
 WindowsConfigParser.prototype.getMatchingPreferences = function (regexp) {
     var preferences = this.doc.findall('preference');
     var result = [];
diff --git a/template/cordova/lib/PluginInfo.js b/template/cordova/lib/PluginInfo.js
index 723fa26..fc9900a 100644
--- a/template/cordova/lib/PluginInfo.js
+++ b/template/cordova/lib/PluginInfo.js
@@ -16,101 +16,8 @@
        specific language governing permissions and limitations
        under the License.
 */
-
-var semver = require('semver');
 var CommonPluginInfo = require('cordova-common').PluginInfo;
-
-var MANIFESTS = {
-    'windows': {
-        '8.1.0': 'package.windows.appxmanifest',
-        '10.0.0': 'package.windows10.appxmanifest'
-    },
-    'phone': {
-        '8.1.0': 'package.phone.appxmanifest',
-        '10.0.0': 'package.windows10.appxmanifest'
-    },
-    'all': {
-        '8.1.0': ['package.windows.appxmanifest', 'package.phone.appxmanifest'],
-        '10.0.0': 'package.windows10.appxmanifest'
-    }
-};
-
-var SUBSTS = ['package.phone.appxmanifest', 'package.windows.appxmanifest', 'package.windows10.appxmanifest'];
-var TARGETS = ['windows', 'phone', 'all'];
-
-function processChanges (changes) {
-    var hasManifestChanges = changes.some(function (change) {
-        return change.target === 'package.appxmanifest';
-    });
-
-    if (!hasManifestChanges) {
-        return changes;
-    }
-
-    // Demux 'package.appxmanifest' into relevant platform-specific appx manifests.
-    // Only spend the cycles if there are version-specific plugin settings
-    var oldChanges = changes;
-    changes = [];
-
-    oldChanges.forEach(function (change) {
-        // Only support semver/device-target demux for package.appxmanifest
-        // Pass through in case something downstream wants to use it
-        if (change.target !== 'package.appxmanifest') {
-            changes.push(change);
-            return;
-        }
-
-        var manifestsForChange = getManifestsForChange(change);
-        changes = changes.concat(demuxChangeWithSubsts(change, manifestsForChange));
-    });
-
-    return changes;
-}
-
-function demuxChangeWithSubsts (change, manifestFiles) {
-    return manifestFiles.map(function (file) {
-        return createReplacement(file, change);
-    });
-}
-
-function getManifestsForChange (change) {
-    var hasTarget = (typeof change.deviceTarget !== 'undefined');
-    var hasVersion = (typeof change.versions !== 'undefined');
-
-    var targetDeviceSet = hasTarget ? change.deviceTarget : 'all';
-
-    if (TARGETS.indexOf(targetDeviceSet) === -1) {
-        // target-device couldn't be resolved, fix it up here to a valid value
-        targetDeviceSet = 'all';
-    }
-
-    // No semver/device-target for this config-file, pass it through
-    if (!(hasTarget || hasVersion)) {
-        return SUBSTS;
-    }
-
-    var knownWindowsVersionsForTargetDeviceSet = Object.keys(MANIFESTS[targetDeviceSet]);
-    return knownWindowsVersionsForTargetDeviceSet.reduce(function (manifestFiles, winver) {
-        if (hasVersion && !semver.satisfies(winver, change.versions)) {
-            return manifestFiles;
-        }
-        return manifestFiles.concat(MANIFESTS[targetDeviceSet][winver]);
-    }, []);
-}
-
-// This is a local function that creates the new replacement representing the
-// mutation.  Used to save code further down.
-function createReplacement (manifestFile, originalChange) {
-    var replacement = {
-        target: manifestFile,
-        parent: originalChange.parent,
-        after: originalChange.after,
-        xmls: originalChange.xmls,
-        versions: originalChange.versions,
-        deviceTarget: originalChange.deviceTarget
-    };
-    return replacement;
-}
+var AppxManifest = require('./AppxManifest');
 
 /*
 A class for holidng the information currently stored in plugin.xml
@@ -126,12 +33,12 @@ function PluginInfo (dirname) {
 
     this.getEditConfigs = function (platform) {
         var editConfigs = parentGetEditConfigs(platform);
-        return processChanges(editConfigs);
+        return AppxManifest.processChanges(editConfigs);
     };
 
     this.getConfigFiles = function (platform) {
         var configFiles = parentGetConfigFiles(platform);
-        return processChanges(configFiles);
+        return AppxManifest.processChanges(configFiles);
     };
 }
 

-- 
To stop receiving notification emails like this one, please contact
janpio@apache.org.

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org