You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ka...@apache.org on 2014/05/02 20:33:20 UTC

[01/24] Split out cordova-lib: move cordova-cli files

Repository: cordova-cli
Updated Branches:
  refs/heads/cordova-lib [created] 1b3b1f03a


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/wp8_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/wp8_parser.js b/src/metadata/wp8_parser.js
deleted file mode 100644
index b5f0326..0000000
--- a/src/metadata/wp8_parser.js
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    child_process = require('child_process'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    xml           = require('../xml-helpers'),
-    config        = require('../config'),
-    hooker        = require('../hooker');
-
-module.exports = function wp8_parser(project) {
-    try {
-        // TODO : Check that it's not a wp8 project?
-        var csproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
-        if (!csproj_file) throw new CordovaError('No .csproj file in "'+project+'"');
-        this.wp8_proj_dir = project;
-        this.csproj_path  = path.join(this.wp8_proj_dir, csproj_file);
-        this.sln_path     = path.join(this.wp8_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
-    } catch(e) {
-        throw new CordovaError('The provided path "' + project + '" is not a Windows Phone 8 project. ' + e);
-    }
-    this.manifest_path  = path.join(this.wp8_proj_dir, 'Properties', 'WMAppManifest.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking wp8 requirements...');
-    var lib_path = path.join(util.libDirectory, 'wp', 'cordova', require('../../platforms').wp8.version, 'wp8');
-    var custom_path = config.has_custom_path(project_root, 'wp8');
-    if (custom_path) {
-        lib_path = path.join(custom_path, 'wp8');
-    }
-    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output);
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-    update_from_config:function(config) {
-        //check config parser
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        //Get manifest file
-        var manifest = xml.parseElementtreeSync(this.manifest_path);
-
-        //Update app version
-        var version = config.version();
-        manifest.find('.//App').attrib.Version = version;
-
-        // Update app name by editing app title in Properties\WMAppManifest.xml
-        var name = config.name();
-        var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
-        if(prev_name != name) {
-            //console.log("Updating app name from " + prev_name + " to " + name);
-            manifest.find('.//App').attrib.Title = name;
-            manifest.find('.//App').attrib.Publisher = name + " Publisher";
-            manifest.find('.//App').attrib.Author = name + " Author";
-            manifest.find('.//PrimaryToken').attrib.TokenID = name;
-            //update name of sln and csproj.
-            name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
-            prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
-            // TODO: might return .sln.user? (generated file)
-            var sln_name = fs.readdirSync(this.wp8_proj_dir).filter(function(e) { return e.match(/\.sln$/i); })[0];
-            var sln_path = path.join(this.wp8_proj_dir, sln_name);
-            var sln_file = fs.readFileSync(sln_path, 'utf-8');
-            var name_regex = new RegExp(prev_name, "g");
-            fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
-            shell.mv('-f', this.csproj_path, path.join(this.wp8_proj_dir, name + '.csproj'));
-            this.csproj_path = path.join(this.wp8_proj_dir, name + '.csproj');
-            shell.mv('-f', sln_path, path.join(this.wp8_proj_dir, name + '.sln'));
-            this.sln_path    = path.join(this.wp8_proj_dir, name + '.sln');
-        }
-
-        // Update package name by changing:
-        /*  - CordovaAppProj.csproj
-         *  - MainPage.xaml
-         *  - MainPage.xaml.cs
-         *  - App.xaml
-         *  - App.xaml.cs
-         */
-         var pkg = config.packageName();
-         var csproj = xml.parseElementtreeSync(this.csproj_path);
-         prev_name = csproj.find('.//RootNamespace').text;
-         if(prev_name != pkg) {
-            //console.log("Updating package name from " + prev_name + " to " + pkg);
-            //CordovaAppProj.csproj
-            csproj.find('.//RootNamespace').text = pkg;
-            csproj.find('.//AssemblyName').text = pkg;
-            csproj.find('.//XapFilename').text = pkg + '.xap';
-            csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
-            fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
-            //MainPage.xaml
-            var mainPageXAML = xml.parseElementtreeSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'));
-            mainPageXAML.getroot().attrib['x:Class'] = pkg + '.MainPage';
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
-            //MainPage.xaml.cs
-            var mainPageCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
-            var namespaceRegEx = new RegExp('namespace ' + prev_name);
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-            //App.xaml
-            var appXAML = xml.parseElementtreeSync(path.join(this.wp8_proj_dir, 'App.xaml'));
-            appXAML.getroot().attrib['x:Class'] = pkg + '.App';
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
-            //App.xaml.cs
-            var appCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), 'utf-8');
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-         }
-
-         //Write out manifest
-         fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
-
-        // Update icons
-        var icons = config.getIcons('wp8');
-        var platformRoot = this.wp8_proj_dir;
-        var appRoot = util.isCordova(platformRoot);
-
-        // icons, that should be added to platform
-        // @param dest {string} Path to copy icon to, relative to platform root
-        var platformIcons = [
-            {dest: "ApplicationIcon.png", width: 99, height: 99},
-            {dest: "Background.png", width: 159, height: 159},
-        ];
-
-        platformIcons.forEach(function (item) {
-            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
-            if (icon){
-                var src = path.join(appRoot, icon.src),
-                    dest = path.join(platformRoot, item.dest);
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        });
-
-    },
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.wp8_proj_dir, 'www');
-    },
-    config_xml:function() {
-        return path.join(this.wp8_proj_dir, 'config.xml');
-    },
-    // copy files from merges directory to actual www dir
-    copy_merges:function(merges_sub_path) {
-        var merges_path = path.join(util.appDir(util.isCordova(this.wp8_proj_dir)), 'merges', merges_sub_path);
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, '..', 'common', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.wp8_proj_dir);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.wp8_proj_dir, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-
-        // Copy all files from merges directories - wp generic first, then wp8 specific.
-        this.copy_merges('wp');
-        this.copy_merges('wp8');
-
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // updates the csproj file to explicitly list all www content.
-    update_csproj:function() {
-        var csproj_xml = xml.parseElementtreeSync(this.csproj_path);
-        // remove any previous references to the www files
-        var item_groups = csproj_xml.findall('ItemGroup');
-        for (var i = 0, l = item_groups.length; i < l; i++) {
-            var group = item_groups[i];
-            var files = group.findall('Content');
-            for (var j = 0, k = files.length; j < k; j++) {
-                var file = files[j];
-                if (file.attrib.Include.substr(0, 3) == 'www') {
-                    // remove file reference
-                    group.remove(0, file);
-                    // remove ItemGroup if empty
-                    var new_group = group.findall('Content');
-                    if(new_group.length < 1) {
-                        csproj_xml.getroot().remove(0, group);
-                    }
-                }
-            }
-        }
-
-        // now add all www references back in from the root www folder
-        var www_files = this.folder_contents('www', this.www_dir());
-        for(file in www_files) {
-            var item = new et.Element('ItemGroup');
-            var content = new et.Element('Content');
-            content.attrib.Include = www_files[file];
-            item.append(content);
-            csproj_xml.getroot().append(item);
-        }
-        // save file
-        fs.writeFileSync(this.csproj_path, csproj_xml.write({indent:4}), 'utf-8');
-    },
-    // Returns an array of all the files in the given directory with relative paths
-    // - name     : the name of the top level directory (i.e all files will start with this in their path)
-    // - dir     : the directory whos contents will be listed under 'name' directory
-    folder_contents:function(name, dir) {
-        var results = [];
-        var folder_dir = fs.readdirSync(dir);
-        for(item in folder_dir) {
-            var stat = fs.statSync(path.join(dir, folder_dir[item]));
-
-            if(stat.isDirectory()) {
-                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
-                //Add all subfolder item paths
-                for(sub_item in sub_dir) {
-                    results.push(sub_dir[sub_item]);
-                }
-            }
-            else if(stat.isFile()) {
-                results.push(path.join(name, folder_dir[item]));
-            }
-            // else { it is a FIFO, or a Socket or something ... }
-        }
-        return results;
-    },
-
-    // calls the nessesary functions to update the wp8 project
-    // Returns a promise.
-    update_project:function(cfg) {
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-
-        // trigger an event in case anyone needs to modify the contents of the www folder before we package it.
-        var that = this;
-        var projectRoot = util.isCordova(process.cwd());
-
-        var hooks = new hooker(projectRoot);
-        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['wp8']  })
-        .then(function() {
-            that.update_csproj();
-            util.deleteSvnFolders(that.www_dir());
-        });
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/platform.js
----------------------------------------------------------------------
diff --git a/src/platform.js b/src/platform.js
deleted file mode 100644
index bd20780..0000000
--- a/src/platform.js
+++ /dev/null
@@ -1,399 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var config            = require('./config'),
-    cordova           = require('../cordova'),
-    cordova_util      = require('./util'),
-    ConfigParser     = require('./ConfigParser'),
-    util              = require('util'),
-    fs                = require('fs'),
-    os                = require('os'),
-    path              = require('path'),
-    hooker            = require('./hooker'),
-    events            = require('./events'),
-    lazy_load         = require('./lazy_load'),
-    CordovaError      = require('./CordovaError'),
-    Q                 = require('q'),
-    platforms         = require('../platforms'),
-    superspawn        = require('./superspawn'),
-    semver            = require('semver'),
-    shell             = require('shelljs');
-
-function getVersionFromScript(script, defaultValue) {
-    var versionPromise = Q(defaultValue);
-    if (fs.existsSync(script)) {
-        versionPromise = superspawn.spawn(script);
-    } else {
-        /* if you are here, it's probably because you're in Jasmine: fix your existsSync stub */
-        versionPromise = Q(defaultValue);
-    }
-    return versionPromise;
-}
-
-function add(hooks, projectRoot, targets, opts) {
-    var xml = cordova_util.projectConfig(projectRoot);
-    var cfg = new ConfigParser(xml);
-    if (!targets || !targets.length) {
-        return Q.reject(new CordovaError('No platform specified. Please specify a platform to add. See "platform list".'));
-    }
-    var config_json = config.read(projectRoot);
-    var platformsDir = path.join(projectRoot, 'platforms');
-
-    // The "platforms" dir is safe to delete, it's almost equivalent to
-    // cordova platfrom rm <list of all platforms>
-    if ( !fs.existsSync(platformsDir)) {
-        shell.mkdir('-p', platformsDir);
-    }
-
-    return hooks.fire('before_platform_add', opts)
-    .then(function() {
-        return targets.reduce(function(soFar, t) {
-            return soFar.then(function() {
-                return lazy_load.based_on_config(projectRoot, t)
-                .then(function(libDir) {
-                    var template = config_json.lib && config_json.lib[t] && config_json.lib[t].template || null;
-                    var copts = null;
-                    if ('spawnoutput' in opts) {
-                        copts = opts.spawnoutput;
-                    }
-                    return call_into_create(t, projectRoot, cfg, libDir, template, copts);
-                }, function(err) {
-                    throw new CordovaError('Unable to fetch platform ' + t + ': ' + err);
-                });
-            });
-        }, Q());
-    })
-    .then(function() {
-        return hooks.fire('after_platform_add', opts);
-    });
-};
-
-function remove(hooks, projectRoot, targets, opts) {
-    if (!targets || !targets.length) {
-        return Q.reject(new CordovaError('No platform[s] specified. Please specify platform[s] to remove. See "platform list".'));
-    }
-    return hooks.fire('before_platform_rm', opts)
-    .then(function() {
-        targets.forEach(function(target) {
-            shell.rm('-rf', path.join(projectRoot, 'platforms', target));
-            var plugins_json = path.join(projectRoot, 'plugins', target + '.json');
-            if (fs.existsSync(plugins_json)) shell.rm(plugins_json);
-        });
-    }).then(function() {
-        return hooks.fire('after_platform_rm', opts);
-    });
-}
-
-function update(hooks, projectRoot, targets, opts) {
-    // Shell out to the update script provided by the named platform.
-    if (!targets || !targets.length) {
-        return Q.reject(new CordovaError('No platform specified. Please specify a platform to update. See "platform list".'));
-    } else if (targets.length > 1) {
-        return Q.reject(new CordovaError('Platform update can only be executed on one platform at a time.'));
-    } else {
-        var plat = targets[0];
-        var platformPath = path.join(projectRoot, 'platforms', plat);
-        var installed_platforms = cordova_util.listPlatforms(projectRoot);
-        if (installed_platforms.indexOf(plat) < 0) {
-            return Q.reject(new CordovaError('Platform "' + plat + '" is not installed. See "platform list".'));
-        }
-
-        function copyCordovaJs() {
-            var parser = new platforms[plat].parser(platformPath);
-            var platform_www = path.join(platformPath, 'platform_www');
-            shell.mkdir('-p', platform_www);
-            shell.cp('-f', path.join(parser.www_dir(), 'cordova.js'), path.join(platform_www, 'cordova.js'));
-        }
-
-        // First, lazy_load the latest version.
-        return hooks.fire('before_platform_update', opts)
-        .then(function() {
-            return lazy_load.based_on_config(projectRoot, plat);
-        }).then(function(libDir) {
-            // Call the platform's update script.
-            var script = path.join(libDir, 'bin', 'update');
-            return superspawn.spawn(script, [platformPath], { stdio: 'inherit' })
-            .then(function() {
-                // Copy the new cordova.js from www -> platform_www.
-                copyCordovaJs();
-                // Leave it to the update script to log out "updated to v FOO".
-            });
-        });
-    }
-}
-
-function check(hooks, projectRoot) {
-    var platformsText = [],
-        platforms_on_fs = cordova_util.listPlatforms(projectRoot),
-        scratch = path.join(os.tmpdir(), "cordova-platform-check-"+Date.now()),
-        listeners = events._events;
-        events._events = {};
-    var result = Q.defer();
-    cordova.raw.create(scratch)
-    .then(function () {
-        var h = new hooker(scratch);
-        // Acquire the version number of each platform we have installed, and output that too.
-        Q.all(platforms_on_fs.map(function(p) {
-            var d = Q.defer();
-            add(h, scratch, [p], {spawnoutput: {stdio: 'ignore'}})
-            .then(function() {
-                var d_avail = Q.defer(),
-                    d_cur = Q.defer();
-                getVersionFromScript(path.join(scratch, 'platforms', p, 'cordova', 'version'), null)
-                .then(function(avail) {
-                    if (!avail) {
-                        /* Platform version script was silent, we can't work with this */
-                        d_avail.resolve('');
-                    } else {
-                        d_avail.resolve(avail);
-                    }
-                })
-                .catch(function () {
-                    /* Platform version script failed, we can't work with this */
-                    d_avail.resolve('');
-                });
-                getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
-                .catch(function () {
-                    d_cur.resolve('broken');
-                }).then(function(v) {
-                    d_cur.resolve(v || '');
-                });
-                Q.all([d_avail.promise, d_cur.promise]).spread(function (avail, v) {
-                    var m;
-                    if (avail && (!v || v == 'broken' || semver.gt(avail, v))) {
-                        m = p + ' @ ' + (v || 'unknown') + ' could be updated to: ' + avail;
-                        platformsText.push(m);
-                    }
-                    d.resolve(m);
-                })
-                .catch(function () {
-                    return '?';
-                })
-                .done();
-            })
-            .catch(function () {
-                /* If a platform doesn't install, then we can't realistically suggest updating */
-                d.resolve();
-            });
-            return d.promise;
-        })).then(function() {
-            var results = '';
-            events._events = listeners;
-            shell.rm('-rf', scratch);
-            if (platformsText) {
-                results = platformsText.filter(function (p) {return !!p}).sort().join('\n');
-            }
-            if (!results) {
-                results = 'All platforms are up-to-date.';
-            }
-            events.emit('results', results);
-            result.resolve();
-        })
-        .done();
-    }).catch(function (){
-        events._events = listeners;
-        shell.rm('-rf', scratch);
-    })
-    .done();
-    return result.promise;
-}
-
-function list(hooks, projectRoot) {
-    var platforms_on_fs = cordova_util.listPlatforms(projectRoot);
-    return hooks.fire('before_platform_ls')
-    .then(function() {
-        // Acquire the version number of each platform we have installed, and output that too.
-        return Q.all(platforms_on_fs.map(function(p) {
-            return getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
-            .then(function(v) {
-                if (!v) return p;
-                return p + ' ' + v;
-            }, function(v) {
-                return p + ' broken';
-            });
-        }));
-    }).then(function(platformsText) {
-        var results = 'Installed platforms: ' + platformsText.sort().join(', ') + '\n';
-        var available = Object.getOwnPropertyNames(platforms).filter(function(p) {
-            var platform = platforms[p] || {},
-                hostos = platform.hostos || null;
-            if (!hostos)
-                return true;
-            if (hostos.indexOf('*') >= 0)
-                return true;
-            if (hostos.indexOf(process.platform) >= 0)
-                return true;
-            return false;
-        });
-
-        available = available.filter(function(p) {
-            return platforms_on_fs.indexOf(p) < 0; // Only those not already installed.
-        });
-        results += 'Available platforms: ' + available.sort().join(', ');
-
-        events.emit('results', results);
-    }).then(function() {
-        return hooks.fire('after_platform_ls');
-    });
-}
-
-// Returns a promise.
-module.exports = function platform(command, targets) {
-    var projectRoot = cordova_util.cdProjectRoot();
-
-    var hooks = new hooker(projectRoot);
-
-    if (arguments.length === 0) command = 'ls';
-    if (targets) {
-        if (!(targets instanceof Array)) targets = [targets];
-        var err;
-        targets.forEach(function(t) {
-            if (!(t in platforms)) {
-                err = new CordovaError('Platform "' + t + '" not recognized as a core cordova platform. See "platform list".');
-            }
-        });
-        if (err) return Q.reject(err);
-    } else {
-        if (command == 'add' || command == 'rm') {
-            return Q.reject(new CordovaError('You need to qualify `add` or `remove` with one or more platforms!'));
-        }
-    }
-
-    var opts = {
-        platforms:targets
-    };
-    switch(command) {
-        case 'add':
-            return add(hooks, projectRoot, targets, opts);
-        case 'rm':
-        case 'remove':
-            return remove(hooks, projectRoot, targets, opts);
-        case 'update':
-        case 'up':
-            return update(hooks, projectRoot, targets, opts);
-        case 'check':
-            return check(hooks, projectRoot);
-        case 'ls':
-        case 'list':
-        default:
-            return list(hooks, projectRoot);
-    }
-};
-
-/**
- * Check Platform Support.
- *
- *   - {String} `name` of the platform to test.
- *   - Returns a promise, which shows any errors.
- *
- */
-
-function supports(project_root, name) {
-    // required parameters
-    if (!name) return Q.reject(new CordovaError('requires a platform name parameter'));
-
-    // check if platform exists
-    var platform = platforms[name];
-    if (!platform) {
-        return Q.reject(new CordovaError(util.format('"%s" platform does not exist', name)));
-    }
-
-    // look up platform meta-data parser
-    var platformParser = platforms[name].parser;
-    if (!platformParser) {
-        return Q.reject(new Error(util.format('"%s" platform parser does not exist', name)));
-    }
-
-    // check for platform support
-    return platformParser.check_requirements(project_root);
-};
-
-// Expose the platform parsers on top of this command
-for (var p in platforms) {
-    module.exports[p] = platforms[p];
-}
-function createOverrides(projectRoot, target) {
-    shell.mkdir('-p', path.join(cordova_util.appDir(projectRoot), 'merges', target));
-};
-
-// Returns a promise.
-function call_into_create(target, projectRoot, cfg, libDir, template_dir, opts) {
-    var output = path.join(projectRoot, 'platforms', target);
-
-    // Check if output directory already exists.
-    if (fs.existsSync(output)) {
-        return Q.reject(new CordovaError('Platform ' + target + ' already added'));
-    } else {
-        // Make sure we have minimum requirements to work with specified platform
-        events.emit('verbose', 'Checking if platform "' + target + '" passes minimum requirements...');
-        /* XXX this is calling the public symbol so that Jasmine Spy can attack it */
-        return module.exports.supports(projectRoot, target)
-        .then(function() {
-            events.emit('log', 'Creating ' + target + ' project...');
-            var bin = path.join(libDir, 'bin', 'create');
-            var args = [];
-            if (target == 'android') {
-                var platformVersion = fs.readFileSync(path.join(libDir, 'VERSION'), 'UTF-8').trim();
-                if (semver.gt(platformVersion, '3.3.0')) {
-                    args.push('--cli');
-                }
-            } else if (target == 'ios') {
-                var platformVersion = fs.readFileSync(path.join(libDir, 'CordovaLib', 'VERSION'), 'UTF-8').trim();
-                args.push('--arc');
-                if (semver.gt(platformVersion, '3.3.0')) {
-                    args.push('--cli');
-                }
-            }
-
-            var pkg = cfg.packageName().replace(/[^\w.]/g,'_');
-            var name = cfg.name();
-            args.push(output, pkg, name);
-            if (template_dir) {
-                args.push(template_dir);
-            }
-            return superspawn.spawn(bin, args, opts || { stdio: 'inherit' })
-            .then(function() {
-                return require('../cordova').raw.prepare(target);
-            })
-            .then(function() {
-                createOverrides(projectRoot, target);
-                // Install all currently installed plugins into this new platform.
-                var plugins_dir = path.join(projectRoot, 'plugins');
-                var plugins = cordova_util.findPlugins(plugins_dir);
-                var parser = new platforms[target].parser(output);
-                if (!plugins) return Q();
-
-                var plugman = require('plugman');
-                // Install them serially.
-                return plugins.reduce(function(soFar, plugin) {
-                    return soFar.then(function() {
-                        events.emit('verbose', 'Installing plugin "' + plugin + '" following successful platform add of ' + target);
-                        return plugman.raw.install(target, output, path.basename(plugin), plugins_dir);
-                    });
-                }, Q());
-            });
-        });
-    }
-}
-
-module.exports.add = add;
-module.exports.remove = remove;
-module.exports.update = update;
-module.exports.check = check;
-module.exports.list = list;
-module.exports.supports = supports;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/plugin.js
----------------------------------------------------------------------
diff --git a/src/plugin.js b/src/plugin.js
deleted file mode 100644
index f0e01f7..0000000
--- a/src/plugin.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-// Returns a promise.
-module.exports = function plugin(command, targets, opts) {
-    var cordova_util  = require('./util'),
-        path          = require('path'),
-        hooker        = require('./hooker'),
-        config        = require('./config'),
-        Q             = require('q'),
-        CordovaError  = require('./CordovaError'),
-        events        = require('./events');
-
-    var projectRoot = cordova_util.cdProjectRoot(),
-        err;
-
-    // Dance with all the possible call signatures we've come up over the time. They can be:
-    // 1. plugin() -> list the plugins
-    // 2. plugin(command, Array of targets, maybe opts object)
-    // 3. plugin(command, target1, target2, target3 ... )
-    // The targets are not really targets, they can be a mixture of plugins and options to be passed to plugman.
-
-    command = command || 'ls';
-    targets = targets || [];
-    opts = opts || {};
-    if ( opts.length ) {
-        // This is the case with multiple targes as separate arguments and opts is not opts but another target.
-        targets = Array.prototype.slice.call(arguments, 1);
-        opts = {};
-    }
-    if ( !Array.isArray(targets) ) {
-        // This means we had a single target given as string.
-        targets = [targets];
-    }
-    opts.options = [];
-    opts.plugins = [];
-
-    var hooks = new hooker(projectRoot);
-    var platformList = cordova_util.listPlatforms(projectRoot);
-
-    // Massage plugin name(s) / path(s)
-    var pluginPath, plugins;
-    pluginPath = path.join(projectRoot, 'plugins');
-    plugins = cordova_util.findPlugins(pluginPath);
-    if (!targets || !targets.length) {
-        if (command == 'add' || command == 'rm') {
-            return Q.reject(new CordovaError('You need to qualify `add` or `remove` with one or more plugins!'));
-        } else {
-            targets = [];
-        }
-    }
-
-    //Split targets between plugins and options
-    //Assume everything after a token with a '-' is an option
-    var i;
-    for (i = 0; i < targets.length; i++) {
-        if (targets[i].match(/^-/)) {
-            opts.options = targets.slice(i);
-            break;
-        } else {
-            opts.plugins.push(targets[i]);
-        }
-    }
-
-    switch(command) {
-        case 'add':
-            if (!targets || !targets.length) {
-                return Q.reject(new CordovaError('No plugin specified. Please specify a plugin to add. See "plugin search".'));
-            }
-
-            var config_json = config(projectRoot, {});
-            var searchPath = config_json.plugin_search_path || [];
-            if (typeof opts.searchpath == 'string') {
-                searchPath = opts.searchpath.split(path.delimiter).concat(searchPath);
-            } else if (opts.searchpath) {
-                searchPath = opts.searchpath.concat(searchPath);
-            }
-            // Blank it out to appease unit tests.
-            if (searchPath.length === 0) {
-                searchPath = undefined;
-            }
-
-            return hooks.fire('before_plugin_add', opts)
-            .then(function() {
-                return opts.plugins.reduce(function(soFar, target) {
-                    var pluginsDir = path.join(projectRoot, 'plugins');
-                    return soFar.then(function() {
-                        if (target[target.length - 1] == path.sep) {
-                            target = target.substring(0, target.length - 1);
-                        }
-
-                        // Fetch the plugin first.
-                        events.emit('verbose', 'Calling plugman.fetch on plugin "' + target + '"');
-                        var plugman = require('plugman');
-                        return plugman.raw.fetch(target, pluginsDir, { searchpath: searchPath});
-                    })
-                    .then(function(dir) {
-                        // Iterate (in serial!) over all platforms in the project and install the plugin.
-                        return platformList.reduce(function(soFar, platform) {
-                            return soFar.then(function() {
-                                var platforms = require('../platforms');
-                                var platformRoot = path.join(projectRoot, 'platforms', platform),
-                                    parser = new platforms[platform].parser(platformRoot),
-                                    options = {
-                                        cli_variables: {},
-                                        searchpath: searchPath
-                                    },
-                                    tokens,
-                                    key,
-                                    i;
-                                //parse variables into cli_variables
-                                for (i=0; i< opts.options.length; i++) {
-                                    if (opts.options[i] === "--variable" && typeof opts.options[++i] === "string") {
-                                        tokens = opts.options[i].split('=');
-                                        key = tokens.shift().toUpperCase();
-                                        if (/^[\w-_]+$/.test(key)) {
-                                            options.cli_variables[key] = tokens.join('=');
-                                        }
-                                    }
-                                }
-
-                                events.emit('verbose', 'Calling plugman.install on plugin "' + dir + '" for platform "' + platform + '" with options "' + JSON.stringify(options)  + '"');
-                                return plugman.raw.install(platform, platformRoot, path.basename(dir), pluginsDir, options);
-                            });
-                        }, Q());
-                    });
-                }, Q()); // end Q.all
-            }).then(function() {
-                return hooks.fire('after_plugin_add', opts);
-            });
-            break;
-        case 'rm':
-        case 'remove':
-            if (!targets || !targets.length) {
-                return Q.reject(new CordovaError('No plugin specified. Please specify a plugin to remove. See "plugin list".'));
-            }
-            return hooks.fire('before_plugin_rm', opts)
-            .then(function() {
-                return opts.plugins.reduce(function(soFar, target) {
-                    // Check if we have the plugin.
-                    if (plugins.indexOf(target) < 0) {
-                        return Q.reject(new CordovaError('Plugin "' + target + '" is not present in the project. See "plugin list".'));
-                    }
-
-                    var targetPath = path.join(pluginPath, target);
-                    // Iterate over all installed platforms and uninstall.
-                    // If this is a web-only or dependency-only plugin, then
-                    // there may be nothing to do here except remove the
-                    // reference from the platform's plugin config JSON.
-                    var plugman = require('plugman');
-                    return platformList.reduce(function(soFar, platform) {
-                        return soFar.then(function() {
-                            var platformRoot = path.join(projectRoot, 'platforms', platform);
-                            var platforms = require('../platforms');
-                            var parser = new platforms[platform].parser(platformRoot);
-                            events.emit('verbose', 'Calling plugman.uninstall on plugin "' + target + '" for platform "' + platform + '"');
-                            return plugman.raw.uninstall.uninstallPlatform(platform, platformRoot, target, path.join(projectRoot, 'plugins'));
-                        });
-                    }, Q())
-                    .then(function() {
-                        return plugman.raw.uninstall.uninstallPlugin(target, path.join(projectRoot, 'plugins'));
-                    });
-                }, Q());
-            }).then(function() {
-                return hooks.fire('after_plugin_rm', opts);
-            });
-            break;
-        case 'search':
-            return hooks.fire('before_plugin_search')
-            .then(function() {
-                var plugman = require('plugman');
-                return plugman.raw.search(opts.plugins);
-            }).then(function(plugins) {
-                for(var plugin in plugins) {
-                    events.emit('results', plugins[plugin].name, '-', plugins[plugin].description || 'no description provided');
-                }
-            }).then(function() {
-                return hooks.fire('after_plugin_search');
-            });
-            break;
-        case 'ls':
-        case 'list':
-        default:
-            return hooks.fire('before_plugin_ls')
-            .then(function() {
-                events.emit('results', (plugins.length ? plugins : 'No plugins added. Use `cordova plugin add <plugin>`.'));
-                return hooks.fire('after_plugin_ls')
-                .then(function() {
-                    return plugins;
-                });
-            });
-            break;
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/plugin_parser.js
----------------------------------------------------------------------
diff --git a/src/plugin_parser.js b/src/plugin_parser.js
deleted file mode 100644
index d3099c0..0000000
--- a/src/plugin_parser.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var xml = require('./xml-helpers'),
-    fs  = require('fs');
-
-function plugin_parser(xmlPath) {
-    this.path = xmlPath;
-    this.doc = xml.parseElementtreeSync(xmlPath);
-    this.platforms = this.doc.findall('platform').map(function(p) {
-        return p.attrib.name;
-    });
-}
-
-module.exports = plugin_parser;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/prepare.js
----------------------------------------------------------------------
diff --git a/src/prepare.js b/src/prepare.js
deleted file mode 100644
index eef0123..0000000
--- a/src/prepare.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_util      = require('./util'),
-    ConfigParser = require('./ConfigParser'),
-    path              = require('path'),
-    platforms         = require('../platforms'),
-    platform          = require('./platform'),
-    fs                = require('fs'),
-    shell             = require('shelljs'),
-    et                = require('elementtree'),
-    hooker            = require('./hooker'),
-    lazy_load         = require('./lazy_load'),
-    events            = require('./events'),
-    Q                 = require('q'),
-    plugman           = require('plugman'),
-    util              = require('util');
-
-// Returns a promise.
-exports = module.exports = function prepare(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-
-    if (!options) {
-        options = {
-            verbose: false,
-            platforms: [],
-            options: []
-        };
-    }
-
-    options = cordova_util.preProcessOptions(options);
-
-    var xml = cordova_util.projectConfig(projectRoot);
-    var paths = options.platforms.map(function(p) {
-        var platform_path = path.join(projectRoot, 'platforms', p);
-        var parser = (new platforms[p].parser(platform_path));
-        return parser.www_dir();
-    });
-    options.paths = paths;
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_prepare', options)
-    .then(function() {
-        var cfg = new ConfigParser(xml);
-
-        // Iterate over each added platform
-        return Q.all(options.platforms.map(function(platform) {
-            var platformPath = path.join(projectRoot, 'platforms', platform);
-            return lazy_load.based_on_config(projectRoot, platform)
-            .then(function(libDir) {
-                var parser = new platforms[platform].parser(platformPath),
-                    defaults_xml_path = path.join(platformPath, "cordova", "defaults.xml");
-                //If defaults.xml is present, overwrite platform config.xml with it
-                //Otherwise save whatever is there as defaults so it can be restored
-                //or copy project config into platform if none exists
-                if (fs.existsSync(defaults_xml_path)) {
-                    shell.cp("-f", defaults_xml_path, parser.config_xml());
-                    events.emit('verbose', 'Generating config.xml from defaults for platform "' + platform + '"');
-                } else {
-                    if(fs.existsSync(parser.config_xml())){
-                        shell.cp("-f", parser.config_xml(), defaults_xml_path);
-                    }else{
-                        shell.cp("-f",xml,parser.config_xml());
-                    }
-                }
-
-                var stagingPath = path.join(platformPath, '.staging');
-                if (fs.existsSync(stagingPath)) {
-                    events.emit('log', 'Deleting now-obsolete intermediate directory: ' + stagingPath);
-                    shell.rm('-rf', stagingPath);
-                }
-
-                var platform_www = path.join(platformPath, 'platform_www');
-                // Create platfom_www if project was created with older version.
-                if (!fs.existsSync(platform_www)) {
-                    shell.mkdir(platform_www);
-                    shell.cp(parser.cordovajs_path(libDir), path.join(platform_www, 'cordova.js'));
-                }
-
-                // Replace the existing web assets with the app master versions
-                parser.update_www();
-
-                // Call plugman --prepare for this platform. sets up js-modules appropriately.
-                var plugins_dir = path.join(projectRoot, 'plugins');
-                events.emit('verbose', 'Calling plugman.prepare for platform "' + platform + '"');
-                plugman.prepare(platformPath, platform, plugins_dir);
-
-                // Make sure that config changes for each existing plugin is in place
-                var munger = new plugman.config_changes.PlatformMunger(platform, platformPath, plugins_dir);
-                munger.reapply_global_munge();
-                munger.save_all();
-
-                // Update platform config.xml based on top level config.xml
-                var platform_cfg = new ConfigParser(parser.config_xml());
-                exports._mergeXml(cfg.doc.getroot(), platform_cfg.doc.getroot(), platform, true);
-                platform_cfg.write();
-
-                return parser.update_project(cfg);
-            });
-        })).then(function() {
-            return hooks.fire('after_prepare', options);
-        });
-    });
-};
-
-var BLACKLIST = ["platform"];
-var SINGLETONS = ["content", "author"];
-function mergeXml(src, dest, platform, clobber) {
-    if (BLACKLIST.indexOf(src.tag) === -1) {
-        //Handle attributes
-        Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
-            if (clobber || !dest.attrib[attribute]) {
-                dest.attrib[attribute] = src.attrib[attribute];
-            }
-        });
-        //Handle text
-        if (src.text && (clobber || !dest.text)) {
-            dest.text = src.text;
-        }
-        //Handle platform
-        if (platform) {
-            src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
-                platformElement.getchildren().forEach(mergeChild);
-            });
-        }
-
-        //Handle children
-        src.getchildren().forEach(mergeChild);
-
-        function mergeChild (srcChild) {
-            var srcTag = srcChild.tag,
-                destChild = new et.Element(srcTag),
-                foundChild,
-                query = srcTag + "",
-                shouldMerge = true;
-
-            if (BLACKLIST.indexOf(srcTag) === -1) {
-                if (SINGLETONS.indexOf(srcTag) !== -1) {
-                    foundChild = dest.find(query);
-                    if (foundChild) {
-                        destChild = foundChild;
-                        dest.remove(0, destChild);
-                    }
-                } else {
-                    //Check for an exact match and if you find one don't add
-                    Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
-                        query += "[@" + attribute + '="' + srcChild.attrib[attribute] + '"]';
-                    });
-                    foundChild = dest.find(query);
-                    if (foundChild && textMatch(srcChild, foundChild)) {
-                        destChild = foundChild;
-                        dest.remove(0, destChild);
-                        shouldMerge = false;
-                    }
-                }
-
-                mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
-                dest.append(destChild);
-            }
-        }
-
-        function textMatch(elm1, elm2) {
-            var text1 = elm1.text ? elm1.text.replace(/\s+/, "") : "",
-                text2 = elm2.text ? elm2.text.replace(/\s+/, "") : "";
-            return (text1 === "" || text1 === text2);
-        }
-    }
-}
-
-// Expose for testing.
-exports._mergeXml = mergeXml;
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/run.js
----------------------------------------------------------------------
diff --git a/src/run.js b/src/run.js
deleted file mode 100644
index 5de3031..0000000
--- a/src/run.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-/*global require: true, module: true, process: true*/
-/*jslint sloppy: true, white: true, newcap: true */
-
-var cordova_util      = require('./util'),
-    path              = require('path'),
-    hooker            = require('./hooker'),
-    superspawn        = require('./superspawn'),
-    Q                 = require('q');
-
-// Returns a promise.
-module.exports = function run(options) {
-    var projectRoot = cordova_util.cdProjectRoot(),
-    options = cordova_util.preProcessOptions(options);
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_run', options)
-    .then(function() {
-        // Run a prepare first, then shell out to run
-        return require('../cordova').raw.prepare(options.platforms)
-    }).then(function() {
-        // Deploy in parallel (output gets intermixed though...)
-        return Q.all(options.platforms.map(function(platform) {
-            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'run');
-            return superspawn.spawn(cmd, options.options, { printCommand: true, stdio: 'inherit' });
-        }));
-    }).then(function() {
-        return hooks.fire('after_run', options);
-    });
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/serve.js
----------------------------------------------------------------------
diff --git a/src/serve.js b/src/serve.js
deleted file mode 100644
index bd17fa3..0000000
--- a/src/serve.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_util = require('./util'),
-    crypto = require('crypto'),
-    path = require('path'),
-    shell = require('shelljs'),
-    platforms     = require('../platforms'),
-    ConfigParser = require('./ConfigParser'),
-    hooker        = require('./hooker'),
-    fs = require('fs'),
-    http = require("http"),
-    url = require("url"),
-    mime = require("mime"),
-    zlib = require("zlib");
-
-function launchServer(projectRoot, port) {
-    var server = http.createServer(function(request, response) {
-        function do404() {
-            console.log('404 ' + request.url);
-            response.writeHead(404, {"Content-Type": "text/plain"});
-            response.write("404 Not Found\n");
-            response.end();
-        }
-        function do302(where) {
-            console.log('302 ' + request.url);
-            response.setHeader("Location", where);
-            response.writeHead(302, {"Content-Type": "text/plain"});
-            response.end();
-        }
-        function doRoot() {
-            response.writeHead(200, {"Content-Type": "text/html"});
-            var config = new ConfigParser(cordova_util.projectConfig(projectRoot));
-            response.write("<html><head><title>"+config.name()+"</title></head><body>");
-            response.write("<table border cellspacing=0><thead><caption><h3>Package Metadata</h3></caption></thead><tbody>");
-            for (var c in {"name": true, "packageName": true, "version": true}) {
-                response.write("<tr><th>"+c+"</th><td>"+config[c]()+"</td></tr>");
-            }
-            response.write("</tbody></table>");
-            response.write("<h3>Platforms</h3><ul>");
-            var installed_platforms = cordova_util.listPlatforms(projectRoot);
-            for (var p in platforms) {
-                if (installed_platforms.indexOf(p) >= 0) {
-                    response.write("<li><a href='"+p+"/'>"+p+"</a></li>\n");
-                } else {
-                    response.write("<li><em>"+p+"</em></li>\n");
-                }
-            }
-            response.write("</ul>");
-            response.write("<h3>Plugins</h3><ul>");
-            var pluginPath = path.join(projectRoot, 'plugins');
-            var plugins = cordova_util.findPlugins(pluginPath);
-            for (var p in plugins) {
-                response.write("<li>"+plugins[p]+"</li>\n");
-            }
-            response.write("</ul>");
-            response.write("</body></html>");
-            response.end();
-        }
-        var urlPath = url.parse(request.url).pathname;
-        var firstSegment = /\/(.*?)\//.exec(urlPath);
-        if (!firstSegment) {
-            return doRoot();
-        }
-        var platformId = firstSegment[1];
-        if (!platforms[platformId]) {
-            return do404();
-        }
-        // Strip the platform out of the path.
-        urlPath = urlPath.slice(platformId.length + 1);
-
-        try {
-            var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
-        } catch (e) {
-            return do404();
-        }
-        var filePath = null;
-
-        if (urlPath == '/config.xml') {
-            filePath = parser.config_xml();
-        } else if (urlPath == '/project.json') {
-            processAddRequest(request, response, platformId, projectRoot);
-            return;
-        } else if (/^\/www\//.test(urlPath)) {
-            filePath = path.join(parser.www_dir(), urlPath.slice(5));
-        } else if (/^\/+[^\/]*$/.test(urlPath)) {
-            return do302("/" + platformId + "/www/");
-        } else {
-            return do404();
-        }
-
-        fs.exists(filePath, function(exists) {
-            if (exists) {
-                if (fs.statSync(filePath).isDirectory()) {
-                    index = path.join(filePath, "index.html");
-                    try {
-                        if (fs.statSync(index)) {
-                            filePath = index;
-                        }
-                    } catch (e) {}
-                }
-                if (fs.statSync(filePath).isDirectory()) {
-                    if (!/\/$/.test(urlPath)) {
-                        return do302("/" + platformId + urlPath + "/");
-                    }
-                    console.log('200 ' + request.url);
-                    response.writeHead(200, {"Content-Type": "text/html"});
-                    response.write("<html><head><title>Directory listing of "+ urlPath + "</title></head>");
-                    response.write("<h3>Items in this directory</h3>");
-                    var items = fs.readdirSync(filePath);
-                    response.write("<ul>");
-                    for (var i in items) {
-                        var file = items[i];
-                        if (file) {
-                            response.write('<li><a href="'+file+'">'+file+'</a></li>\n');
-                        }
-                    }
-                    response.write("</ul>");
-                    response.end();
-                } else {
-                    var mimeType = mime.lookup(filePath);
-                    var respHeaders = {
-                      'Content-Type': mimeType
-                    };
-                    var readStream = fs.createReadStream(filePath);
-
-                    var acceptEncoding = request.headers['accept-encoding'] || '';
-                    if (acceptEncoding.match(/\bgzip\b/)) {
-                        respHeaders['content-encoding'] = 'gzip';
-                        readStream = readStream.pipe(zlib.createGzip());
-                    } else if (acceptEncoding.match(/\bdeflate\b/)) {
-                        respHeaders['content-encoding'] = 'deflate';
-                        readStream = readStream.pipe(zlib.createDeflate());
-                    }
-                    console.log('200 ' + request.url);
-                    response.writeHead(200, respHeaders);
-                    readStream.pipe(response);
-                }
-            } else {
-                return do404();
-            }
-        });
-    }).on('listening', function () {
-        console.log("Static file server running on port " + port + " (i.e. http://localhost:" + port + ")\nCTRL + C to shut down");
-    }).on('error', function (e) {
-        if (e && e.toString().indexOf('EADDRINUSE') !== -1) {
-            port++;
-            server.listen(port);
-        } else {
-            console.log("An error occured starting static file server: " + e);
-        }
-    }).listen(port);
-    return server;
-}
-
-function calculateMd5(fileName) {
-    var BUF_LENGTH = 64*1024,
-        buf = new Buffer(BUF_LENGTH),
-        bytesRead = BUF_LENGTH,
-        pos = 0,
-        fdr = fs.openSync(fileName, 'r');
-
-    try {
-        var md5sum = crypto.createHash('md5');
-        while (bytesRead === BUF_LENGTH) {
-            bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
-            pos += bytesRead;
-            md5sum.update(buf.slice(0, bytesRead));
-        }
-    } finally {
-        fs.closeSync(fdr);
-    }
-    return md5sum.digest('hex');
-}
-
-function processAddRequest(request, response, platformId, projectRoot) {
-    var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
-    var wwwDir = parser.www_dir();
-    var payload = {
-        'configPath': '/' + platformId + '/config.xml',
-        'wwwPath': '/' + platformId + '/www',
-        'wwwFileList': shell.find(wwwDir)
-            .filter(function(a) { return !fs.statSync(a).isDirectory() && !/(^\.)|(\/\.)/.test(a) })
-            .map(function(a) { return {'path': a.slice(wwwDir.length), 'etag': '' + calculateMd5(a)}; })
-    };
-    console.log('200 ' + request.url);
-    response.writeHead(200, {
-        'Content-Type': 'application/json',
-        'Cache-Control': 'no-cache'
-    });
-    response.write(JSON.stringify(payload));
-    response.end();
-}
-
-module.exports = function server(port) {
-    var projectRoot = cordova_util.cdProjectRoot();
-    port = +port || 8000;
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_serve')
-    .then(function() {
-        // Run a prepare first!
-        return require('../cordova').raw.prepare([]);
-    }).then(function() {
-        launchServer(projectRoot, port);
-        return hooks.fire('after_serve');
-    });
-};
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/superspawn.js
----------------------------------------------------------------------
diff --git a/src/superspawn.js b/src/superspawn.js
deleted file mode 100644
index 60c9fdc..0000000
--- a/src/superspawn.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var child_process = require('child_process');
-var fs = require('fs');
-var path = require('path');
-var _ = require('underscore');
-var Q = require('q');
-var shell = require('shelljs');
-var events = require('./events');
-var iswin32 = process.platform == 'win32';
-
-// On Windows, spawn() for batch files requires absolute path & having the extension.
-function resolveWindowsExe(cmd) {
-    var winExtensions = ['.exe', '.cmd', '.bat', '.js', '.vbs'];
-    function isValidExe(c) {
-        return winExtensions.indexOf(path.extname(c)) !== -1 && fs.existsSync(c);
-    }
-    if (isValidExe(cmd)) {
-        return cmd;
-    }
-    cmd = shell.which(cmd) || cmd;
-    if (!isValidExe(cmd)) {
-        winExtensions.some(function(ext) {
-            if (fs.existsSync(cmd + ext)) {
-                cmd = cmd + ext;
-                return true;
-            }
-        });
-    }
-    return cmd;
-}
-
-function maybeQuote(a) {
-    if (a.indexOf(' ') != -1) {
-        a = '"' + a + '"';
-    }
-    return a;
-}
-
-// opts:
-//   printCommand: Whether to log the command (default: false)
-//   stdio: 'default' is to capture output and returning it as a string to success (same as exec)
-//          'ignore' means don't bother capturing it
-//          'inherit' means pipe the input & output. This is required for anything that prompts.
-//   env: Map of extra environment variables.
-//   cwd: Working directory for the command.
-// Returns a promise that succeeds only for return code = 0.
-exports.spawn = function(cmd, args, opts) {
-    args = args || [];
-    opts = opts || {};
-    var spawnOpts = {};
-    var d = Q.defer();
-
-    if (iswin32) {
-        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' && cmd.indexOf(' ') != -1) {
-            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
-            args = [['/s', '/c', '"'+[cmd].concat(args).map(function(a){if (/^[^"].* .*[^"]/.test(a)) return '"'+a+'"'; return a;}).join(" ")+'"'].join(" ")];
-            cmd = 'cmd';
-            spawnOpts.windowsVerbatimArguments = true;
-        } else if (!fs.existsSync(cmd)) {
-            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
-            args = ['/s', '/c', cmd].concat(args);
-        }
-    }
-
-    if (opts.stdio == 'ignore') {
-        spawnOpts.stdio = 'ignore';
-    } else if (opts.stdio == 'inherit') {
-        spawnOpts.stdio = 'inherit';
-    }
-    if (opts.cwd) {
-        spawnOpts.cwd = opts.cwd;
-    }
-    if (opts.env) {
-        spawnOpts.env = _.extend(_.extend({}, process.env), opts.env);
-    }
-
-    events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' '));
-
-    var child = child_process.spawn(cmd, args, spawnOpts);
-    var capturedOut = '';
-    var capturedErr = '';
-
-    if (child.stdout) {
-        child.stdout.setEncoding('utf8');
-        child.stdout.on('data', function(data) {
-            capturedOut += data;
-        });
-
-        child.stderr.setEncoding('utf8');
-        child.stderr.on('data', function(data) {
-            capturedErr += data;
-        });
-    }
-
-    child.on('close', whenDone);
-    child.on('error', whenDone);
-    function whenDone(arg) {
-        child.removeListener('close', whenDone);
-        child.removeListener('error', whenDone);
-        var code = typeof arg == 'number' ? arg : arg && arg.code;
-
-        events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args);
-        if (code === 0) {
-            d.resolve(capturedOut.trim());
-        } else {
-            var errMsg = cmd + ': Command failed with exit code ' + code;
-            if (capturedErr) {
-                errMsg += ' Error output:\n' + capturedErr.trim();
-            }
-            var err = new Error(errMsg);
-            err.code = code;
-            d.reject(err);
-        }
-    }
-
-    return d.promise;
-};
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/util.js
----------------------------------------------------------------------
diff --git a/src/util.js b/src/util.js
deleted file mode 100644
index 2d3b12a..0000000
--- a/src/util.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    CordovaError  = require('./CordovaError'),
-    shell         = require('shelljs');
-
-// Global configuration paths
-var HOME = process.env[(process.platform.slice(0, 3) == 'win') ? 'USERPROFILE' : 'HOME'];
-var global_config_path = path.join(HOME, '.cordova');
-var lib_path = path.join(global_config_path, 'lib');
-shell.mkdir('-p', lib_path);
-
-function isRootDir(dir) {
-    if (fs.existsSync(path.join(dir, 'www'))) {
-        if (fs.existsSync(path.join(dir, 'config.xml'))) {
-            // For sure is.
-            if (fs.existsSync(path.join(dir, 'platforms'))) {
-                return 2;
-            } else {
-                return 1;
-            }
-        }
-        // Might be (or may be under platforms/).
-        if (fs.existsSync(path.join(dir, 'www', 'config.xml'))) {
-            return 1;
-        }
-    }
-    return 0;
-}
-
-exports = module.exports = {
-    globalConfig:global_config_path,
-    libDirectory:lib_path,
-    // 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.
-    isCordova: 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) {
-                return this.isCordova(pwd) || this.isCordova(cwd);
-            }
-            return this.isCordova(cwd);
-        }
-        var bestReturnValueSoFar = false;
-        for (var i = 0; i < 1000; ++i) {
-            var result = isRootDir(dir);
-            if (result === 2) {
-                return dir;
-            }
-            if (result === 1) {
-                bestReturnValueSoFar = dir;
-            }
-            var parentDir = path.normalize(path.join(dir, '..'));
-            // Detect fs root.
-            if (parentDir == dir) {
-                return bestReturnValueSoFar;
-            }
-            dir = parentDir;
-        }
-        console.error('Hit an unhandled case in util.isCordova');
-        return false;
-    },
-    // Cd to project root dir and return its path. Throw CordovaError if not in a Corodva project.
-    cdProjectRoot: function() {
-        var projectRoot = this.isCordova();
-        if (!projectRoot) {
-            throw new CordovaError('Current working directory is not a Cordova-based project.');
-        }
-        process.chdir(projectRoot);
-        return projectRoot;
-    },
-    // Recursively deletes .svn folders from a target path
-    deleteSvnFolders:function(dir) {
-        var contents = fs.readdirSync(dir);
-        contents.forEach(function(entry) {
-            var fullpath = path.join(dir, entry);
-            if (fs.statSync(fullpath).isDirectory()) {
-                if (entry == '.svn') {
-                    shell.rm('-rf', fullpath);
-                } else module.exports.deleteSvnFolders(fullpath);
-            }
-        });
-    },
-    listPlatforms:function(project_dir) {
-        var core_platforms = require('../platforms');
-        var platforms_dir = path.join(project_dir, 'platforms');
-        if ( !fs.existsSync(platforms_dir)) {
-            return [];
-        }
-        var subdirs = fs.readdirSync(platforms_dir);
-        return subdirs.filter(function(p) {
-            return Object.keys(core_platforms).indexOf(p) > -1;
-        });
-    },
-    // list the directories in the path, ignoring any files
-    findPlugins:function(pluginPath) {
-        var plugins = [],
-            stats;
-
-        if (fs.existsSync(pluginPath)) {
-            plugins = fs.readdirSync(pluginPath).filter(function (fileName) {
-               stats = fs.statSync(path.join(pluginPath, fileName));
-               return fileName != '.svn' && fileName != 'CVS' && stats.isDirectory();
-            });
-        }
-
-        return plugins;
-    },
-    appDir: function(projectDir) {
-        return projectDir;
-    },
-    projectWww: function(projectDir) {
-        return path.join(projectDir, 'www');
-    },
-    projectConfig: function(projectDir) {
-        var rootPath = path.join(projectDir, 'config.xml');
-        var wwwPath = path.join(projectDir, 'www', 'config.xml');
-        if (fs.existsSync(rootPath)) {
-            return rootPath;
-        } else if (fs.existsSync(wwwPath)) {
-            return wwwPath;
-        }
-        return rootPath;
-    },
-    preProcessOptions: function (inputOptions) {
-        /**
-         * Current Desired Arguments
-         * options: {verbose: boolean, platforms: [String], options: [String]}
-         * Accepted Arguments
-         * platformList: [String] -- assume just a list of platforms
-         * platform: String -- assume this is a platform
-         */
-        var result = inputOptions || {};
-        if (Array.isArray(inputOptions)) {
-            result = { platforms: inputOptions };
-        } else if (typeof inputOptions === 'string') {
-            result = { platforms: [inputOptions] };
-        }
-        result.verbose = result.verbose || false;
-        result.platforms = result.platforms || [];
-        result.options = result.options || [];
-
-        var projectRoot = this.isCordova();
-
-        if (!projectRoot) {
-            throw new CordovaError('Current working directory is not a Cordova-based project.');
-        }
-        var projectPlatforms = this.listPlatforms(projectRoot);
-        if (projectPlatforms.length === 0) {
-            throw new CordovaError('No platforms added to this project. Please use `cordova platform add <platform>`.');
-        }
-        if (result.platforms.length === 0) {
-            result.platforms = projectPlatforms;
-        }
-
-        return result;
-    }
-};
-
-// opt_wrap is a boolean: True means that a callback-based wrapper for the promise-based function
-// should be created.
-function addModuleProperty(module, symbol, modulePath, opt_wrap, opt_obj) {
-    var val = null;
-    if (opt_wrap) {
-        module.exports[symbol] = function() {
-            val = val || module.require(modulePath);
-            if (arguments.length && typeof arguments[arguments.length - 1] === 'function') {
-                // If args exist and the last one is a function, it's the callback.
-                var args = Array.prototype.slice.call(arguments);
-                var cb = args.pop();
-                val.apply(module.exports, args).done(function(result) {cb(undefined, result)}, cb);
-            } else {
-                val.apply(module.exports, arguments).done(null, function(err) { throw err; });
-            }
-        };
-    } else {
-        Object.defineProperty(opt_obj || module.exports, symbol, {
-            get : function() { return val = val || module.require(modulePath); },
-            set : function(v) { val = v; }
-        });
-    }
-
-    // Add the module.raw.foo as well.
-    if(module.exports.raw) {
-        Object.defineProperty(module.exports.raw, symbol, {
-            get : function() { return val = val || module.require(modulePath); },
-            set : function(v) { val = v; }
-        });
-    }
-}
-
-addModuleProperty(module, 'plugin_parser', './plugin_parser');
-
-exports.addModuleProperty = addModuleProperty;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/xml-helpers.js
----------------------------------------------------------------------
diff --git a/src/xml-helpers.js b/src/xml-helpers.js
deleted file mode 100644
index 70ec96b..0000000
--- a/src/xml-helpers.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- *
- * Copyright 2013 Anis Kadri
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/**
- * contains XML utility functions, some of which are specific to elementtree
- */
-
-var fs = require('fs')
-  , path = require('path')
-  , et = require('elementtree');
-
-module.exports = {
-    // Returns a promise.
-    moveProjFile: function(origFile, projPath) {
-        var src = path.resolve(projPath, origFile)
-          , dest = src.replace('.orig', '');
-
-        var d = Q.defer();
-        fs.createReadStream(src)
-            .pipe(fs.createWriteStream(dest))
-            .on('close', d.resolve)
-            .on('error', d.reject);
-        return d.promise;
-    },
-
-    // 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) {
-            return false;
-        } else if (one.text.trim() != two.text.trim()) {
-            return false;
-        } else if (one._children.length != two._children.length) {
-            return false;
-        }
-
-        var oneAttribKeys = Object.keys(one.attrib),
-            twoAttribKeys = Object.keys(two.attrib),
-            i = 0, attribName;
-
-        if (oneAttribKeys.length != twoAttribKeys.length) {
-            return false;
-        }
-
-        for (i; i < oneAttribKeys.length; i++) {
-            attribName = oneAttribKeys[i];
-
-            if (one.attrib[attribName] != two.attrib[attribName]) {
-                return false;
-            }
-        }
-
-        for (i; i < one._children.length; i++) {
-            if (!module.exports.equalNodes(one._children[i], two._children[i])) {
-                return false;
-            }
-        }
-
-        return true;
-    },
-
-    // adds node to doc at selector
-    graftXML: function(doc, nodes, selector) {
-        var parent = resolveParent(doc, selector);
-        if (!parent) return false;
-
-        nodes.forEach(function (node) {
-            // check if child is unique first
-            if (uniqueChild(node, parent)) {
-                parent.append(node);
-            }
-        });
-
-        return true;
-    },
-
-    // removes node from doc at selector
-    pruneXML: function(doc, nodes, selector) {
-        var parent = resolveParent(doc, selector);
-        if (!parent) return false;
-
-        nodes.forEach(function (node) {
-            var matchingKid = null;
-            if ((matchingKid = findChild(node, parent)) != null) {
-                // stupid elementtree takes an index argument it doesn't use
-                // and does not conform to the python lib
-                parent.remove(0, matchingKid);
-            }
-        });
-
-        return true;
-    },
-
-    parseElementtreeSync: function (filename) {
-        var contents = fs.readFileSync(filename, 'utf-8');
-        if(contents) {
-            contents = contents.substring(contents.indexOf("<")); //Windows is the BOM
-        }
-        return new et.ElementTree(et.XML(contents));
-    }
-};
-
-function findChild(node, parent) {
-    var matchingKids = parent.findall(node.tag)
-      , i, j;
-
-    for (i = 0, j = matchingKids.length ; i < j ; i++) {
-        if (module.exports.equalNodes(node, matchingKids[i])) {
-            return matchingKids[i];
-        }
-    }
-    return null;
-}
-
-function uniqueChild(node, parent) {
-    var matchingKids = parent.findall(node.tag)
-      , i = 0;
-
-    if (matchingKids.length == 0) {
-        return true;
-    } else  {
-        for (i; i < matchingKids.length; i++) {
-            if (module.exports.equalNodes(node, matchingKids[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
-
-var ROOT = /^\/([^\/]*)/,
-    ABSOLUTE = /^\/([^\/]*)\/(.*)/;
-function resolveParent(doc, selector) {
-    var parent, tagName, subSelector;
-
-    // handle absolute selector (which elementtree doesn't like)
-    if (ROOT.test(selector)) {
-        tagName = selector.match(ROOT)[1];
-        // test for wildcard "any-tag" root selector
-        if (tagName == '*' || tagName === doc._root.tag) {
-            parent = doc._root;
-
-            // could be an absolute path, but not selecting the root
-            if (ABSOLUTE.test(selector)) {
-                subSelector = selector.match(ABSOLUTE)[2];
-                parent = parent.find(subSelector)
-            }
-        } else {
-            return false;
-        }
-    } else {
-        parent = doc.find(selector)
-    }
-    return parent;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/templates/config.xml
----------------------------------------------------------------------
diff --git a/templates/config.xml b/templates/config.xml
deleted file mode 100644
index 4a9a4d8..0000000
--- a/templates/config.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
-        id        = "io.cordova.hellocordova"
-        version   = "0.0.1">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <content src="index.html" />
-
-    <access origin="*" />
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/templates/hooks-README.md
----------------------------------------------------------------------
diff --git a/templates/hooks-README.md b/templates/hooks-README.md
deleted file mode 100644
index d2563ea..0000000
--- a/templates/hooks-README.md
+++ /dev/null
@@ -1,83 +0,0 @@
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
--->
-# Cordova Hooks
-
-This directory may contain scripts used to customize cordova commands. This
-directory used to exist at `.cordova/hooks`, but has now been moved to the
-project root. Any scripts you add to these directories will be executed before
-and after the commands corresponding to the directory name. Useful for
-integrating your own build systems or integrating with version control systems.
-
-__Remember__: Make your scripts executable.
-
-## Hook Directories
-The following subdirectories will be used for hooks:
-
-    after_build/
-    after_compile/
-    after_docs/
-    after_emulate/
-    after_platform_add/
-    after_platform_rm/
-    after_platform_ls/
-    after_plugin_add/
-    after_plugin_ls/
-    after_plugin_rm/
-    after_plugin_search/
-    after_prepare/
-    after_run/
-    after_serve/
-    before_build/
-    before_compile/
-    before_docs/
-    before_emulate/
-    before_platform_add/
-    before_platform_rm/
-    before_platform_ls/
-    before_plugin_add/
-    before_plugin_ls/
-    before_plugin_rm/
-    before_plugin_search/
-    before_prepare/
-    before_run/
-    before_serve/
-    pre_package/ <-- Windows 8 and Windows Phone only.
-
-## Script Interface
-
-All scripts are run from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables:
-
-* CORDOVA_VERSION - The version of the Cordova-CLI.
-* CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios).
-* CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer)
-* CORDOVA_HOOK - Path to the hook that is being executed.
-* CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate)
-
-If a script returns a non-zero exit code, then the parent cordova command will be aborted.
-
-
-## Writing hooks
-
-We highly recommend writting your hooks using Node.js so that they are
-cross-platform. Some good examples are shown here:
-
-[http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/)
-


[14/24] git commit: Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
Split out cordova-lib: move cordova-cli files

HISTORY:
git log <file> will show no history from before this commit for files that
moved. To see full history use either
git log --follow <file>
or
git log cli_pre_lib <old file name>

'cli_pre_lib' is a tag for the last commit in cordova-cli repo made before
cordova-lib was split out.


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

Branch: refs/heads/cordova-lib
Commit: b51e1c12ae384838ea6c1399dba6c0b49d3c2bca
Parents: 450468a
Author: Mark Koudritsky <ka...@gmail.com>
Authored: Wed Apr 30 18:11:57 2014 -0400
Committer: Mark Koudritsky <ka...@gmail.com>
Committed: Wed Apr 30 18:11:57 2014 -0400

----------------------------------------------------------------------
 cordova-lib/spec-cordova/ConfigParser.spec.js   |   84 +
 cordova-lib/spec-cordova/build.spec.js          |  129 ++
 cordova-lib/spec-cordova/compile.spec.js        |  113 ++
 cordova-lib/spec-cordova/create.spec.js         |  138 ++
 cordova-lib/spec-cordova/emulate.spec.js        |  115 ++
 .../fixtures/base/.cordova/config.json          |   22 +
 .../spec-cordova/fixtures/base/merges/.svn      |    0
 .../spec-cordova/fixtures/base/plugins/.svn     |    0
 .../spec-cordova/fixtures/base/www/config.xml   |   14 +
 .../fixtures/base/www/css/index.css             |  115 ++
 .../spec-cordova/fixtures/base/www/img/logo.png |  Bin 0 -> 21814 bytes
 .../spec-cordova/fixtures/base/www/index.html   |   43 +
 .../spec-cordova/fixtures/base/www/js/index.js  |   49 +
 .../spec-cordova/fixtures/base/www/spec.html    |   68 +
 .../fixtures/hooks_bat/fail/fail.bat            |    2 +
 .../fixtures/hooks_bat/test/.dotted.bat         |    2 +
 .../spec-cordova/fixtures/hooks_bat/test/07.bat |    3 +
 .../spec-cordova/fixtures/hooks_bat/test/1.bat  |    5 +
 .../spec-cordova/fixtures/hooks_sh/fail/fail.sh |    1 +
 .../fixtures/hooks_sh/test/.dotted.sh           |    1 +
 .../spec-cordova/fixtures/hooks_sh/test/07.sh   |    2 +
 .../spec-cordova/fixtures/hooks_sh/test/1.sh    |    4 +
 .../fixtures/platforms/android-lib/VERSION      |    1 +
 .../android-lib/framework/assets/www/cordova.js |    1 +
 .../platforms/android/AndroidManifest.xml       |   14 +
 .../platforms/android/assets/www/config.xml     |   14 +
 .../platforms/android/assets/www/cordova.js     | 1712 ++++++++++++++++++
 .../android/assets/www/cordova_plugins.js       |    3 +
 .../platforms/android/assets/www/css/index.css  |  115 ++
 .../platforms/android/assets/www/img/logo.png   |  Bin 0 -> 21814 bytes
 .../platforms/android/assets/www/index.html     |   43 +
 .../platforms/android/assets/www/js/index.js    |   49 +
 .../platforms/android/assets/www/spec.html      |   68 +
 .../fixtures/platforms/android/build.xml        |   92 +
 .../fixtures/platforms/android/cordova/build    |   35 +
 .../platforms/android/cordova/check_reqs        |   27 +
 .../fixtures/platforms/android/cordova/clean    |   34 +
 .../platforms/android/cordova/defaults.xml      |   50 +
 .../platforms/android/cordova/lib/appinfo.js    |   41 +
 .../platforms/android/cordova/lib/build.js      |   89 +
 .../platforms/android/cordova/lib/check_reqs.js |   78 +
 .../platforms/android/cordova/lib/clean.js      |   43 +
 .../platforms/android/cordova/lib/device.js     |   95 +
 .../platforms/android/cordova/lib/emulator.js   |  337 ++++
 .../android/cordova/lib/install-device          |   38 +
 .../android/cordova/lib/install-emulator        |   38 +
 .../platforms/android/cordova/lib/list-devices  |   28 +
 .../android/cordova/lib/list-emulator-images    |   29 +
 .../android/cordova/lib/list-started-emulators  |   29 +
 .../platforms/android/cordova/lib/log.js        |   43 +
 .../platforms/android/cordova/lib/run.js        |  124 ++
 .../android/cordova/lib/start-emulator          |   38 +
 .../fixtures/platforms/android/cordova/log      |   33 +
 .../fixtures/platforms/android/cordova/run      |   35 +
 .../fixtures/platforms/android/cordova/version  |   25 +
 .../fixtures/platforms/android/local.properties |   10 +
 .../platforms/android/proguard-project.txt      |   20 +
 .../platforms/android/project.properties        |   14 +
 .../android/res/drawable-hdpi/icon.png          |  Bin 0 -> 6080 bytes
 .../android/res/drawable-ldpi/icon.png          |  Bin 0 -> 3096 bytes
 .../android/res/drawable-mdpi/icon.png          |  Bin 0 -> 4090 bytes
 .../android/res/drawable-xhdpi/icon.png         |  Bin 0 -> 7685 bytes
 .../platforms/android/res/drawable/icon.png     |  Bin 0 -> 7685 bytes
 .../platforms/android/res/values/strings.xml    |    4 +
 .../platforms/android/res/xml/config.xml        |   18 +
 .../android/src/org/testing/TestBase.java       |   37 +
 .../fixtures/plugins/ChildBrowser/plugin.xml    |  142 ++
 .../ChildBrowser/src/android/ChildBrowser.java  |   19 +
 .../plugins/ChildBrowser/www/childbrowser.js    |   19 +
 .../ChildBrowser/www/childbrowser/image.jpg     |    1 +
 .../ChildBrowser/www/childbrowser_file.html     |    1 +
 .../fixtures/plugins/android/plugin.xml         |   14 +
 .../plugins/android/src/android/Android.java    |    0
 .../android/src/android/SomethingWithR.java     |    6 +
 .../fixtures/plugins/android/www/android.js     |    0
 .../fixtures/plugins/fake1/plugin.xml           |   10 +
 .../fixtures/plugins/test/plugin.xml            |   14 +
 .../fixtures/plugins/test/www/test.js           |    0
 .../projects/android/AndroidManifest.xml        |   69 +
 .../projects/android/assets/www/.gitkeep        |    0
 .../projects/android/res/xml/config.xml         |   54 +
 .../fixtures/projects/android/src/.gitkeep      |    0
 .../fixtures/projects/windows/bom_test.xml      |   24 +
 .../fixtures/templates/no_content_config.xml    |   19 +
 cordova-lib/spec-cordova/helper.js              |   19 +
 cordova-lib/spec-cordova/helpers.js             |   46 +
 cordova-lib/spec-cordova/hooker.spec.js         |  261 +++
 cordova-lib/spec-cordova/lazy_load.spec.js      |  200 ++
 .../metadata/android_parser.spec.js             |  211 +++
 .../metadata/blackberry_parser.spec.js          |  225 +++
 .../metadata/firefoxos_parser.spec.js           |   74 +
 .../spec-cordova/metadata/ios_parser.spec.js    |  199 ++
 .../metadata/windows8_parser.spec.js            |  189 ++
 .../spec-cordova/metadata/wp7_parser.spec.js    |  208 +++
 .../spec-cordova/metadata/wp8_parser.spec.js    |  208 +++
 cordova-lib/spec-cordova/platform.spec.js       |  108 ++
 cordova-lib/spec-cordova/plugin.spec.js         |   68 +
 cordova-lib/spec-cordova/plugin_parser.spec.js  |   48 +
 cordova-lib/spec-cordova/prepare.spec.js        |  290 +++
 cordova-lib/spec-cordova/run.spec.js            |  114 ++
 cordova-lib/spec-cordova/serve.spec.js          |  132 ++
 cordova-lib/spec-cordova/test-config.xml        |   26 +
 cordova-lib/spec-cordova/util.spec.js           |  186 ++
 cordova-lib/spec-cordova/wrappers.spec.js       |   40 +
 cordova-lib/spec-cordova/xml-helpers.spec.js    |  137 ++
 cordova-lib/src/cordova/ConfigParser.js         |  163 ++
 cordova-lib/src/cordova/CordovaError.js         |   31 +
 cordova-lib/src/cordova/build.js                |   47 +
 cordova-lib/src/cordova/compile.js              |   45 +
 cordova-lib/src/cordova/config.js               |   82 +
 cordova-lib/src/cordova/cordova.js              |   68 +
 cordova-lib/src/cordova/create.js               |  220 +++
 cordova-lib/src/cordova/emulate.js              |   50 +
 cordova-lib/src/cordova/events.js               |   23 +
 cordova-lib/src/cordova/hooker.js               |  161 ++
 cordova-lib/src/cordova/info.js                 |  111 ++
 cordova-lib/src/cordova/lazy_load.js            |  151 ++
 .../cordova/metadata/amazon_fireos_parser.js    |  183 ++
 .../src/cordova/metadata/android_parser.js      |  303 ++++
 .../src/cordova/metadata/blackberry10_parser.js |  145 ++
 .../src/cordova/metadata/firefoxos_parser.js    |  151 ++
 cordova-lib/src/cordova/metadata/ios_parser.js  |  202 +++
 .../src/cordova/metadata/ubuntu_parser.js       |  162 ++
 .../src/cordova/metadata/windows8_parser.js     |  339 ++++
 cordova-lib/src/cordova/metadata/wp7_parser.js  |  262 +++
 cordova-lib/src/cordova/metadata/wp8_parser.js  |  287 +++
 cordova-lib/src/cordova/platform.js             |  399 ++++
 cordova-lib/src/cordova/platforms.js            |   88 +
 cordova-lib/src/cordova/plugin.js               |  210 +++
 cordova-lib/src/cordova/plugin_parser.js        |   30 +
 cordova-lib/src/cordova/prepare.js              |  187 ++
 cordova-lib/src/cordova/run.js                  |   48 +
 cordova-lib/src/cordova/serve.js                |  224 +++
 cordova-lib/src/cordova/superspawn.js           |  139 ++
 cordova-lib/src/cordova/util.js                 |  214 +++
 cordova-lib/src/cordova/xml-helpers.js          |  171 ++
 cordova-lib/templates/config.xml                |   19 +
 cordova-lib/templates/hooks-README.md           |   83 +
 cordova.js                                      |   68 -
 platforms.js                                    |   88 -
 spec/ConfigParser.spec.js                       |   84 -
 spec/build.spec.js                              |  129 --
 spec/compile.spec.js                            |  113 --
 spec/create.spec.js                             |  138 --
 spec/emulate.spec.js                            |  115 --
 spec/fixtures/base/.cordova/config.json         |   22 -
 spec/fixtures/base/merges/.svn                  |    0
 spec/fixtures/base/plugins/.svn                 |    0
 spec/fixtures/base/www/config.xml               |   14 -
 spec/fixtures/base/www/css/index.css            |  115 --
 spec/fixtures/base/www/img/logo.png             |  Bin 21814 -> 0 bytes
 spec/fixtures/base/www/index.html               |   43 -
 spec/fixtures/base/www/js/index.js              |   49 -
 spec/fixtures/base/www/spec.html                |   68 -
 spec/fixtures/hooks_bat/fail/fail.bat           |    2 -
 spec/fixtures/hooks_bat/test/.dotted.bat        |    2 -
 spec/fixtures/hooks_bat/test/07.bat             |    3 -
 spec/fixtures/hooks_bat/test/1.bat              |    5 -
 spec/fixtures/hooks_sh/fail/fail.sh             |    1 -
 spec/fixtures/hooks_sh/test/.dotted.sh          |    1 -
 spec/fixtures/hooks_sh/test/07.sh               |    2 -
 spec/fixtures/hooks_sh/test/1.sh                |    4 -
 spec/fixtures/platforms/android-lib/VERSION     |    1 -
 .../android-lib/framework/assets/www/cordova.js |    1 -
 .../platforms/android/AndroidManifest.xml       |   14 -
 .../platforms/android/assets/www/config.xml     |   14 -
 .../platforms/android/assets/www/cordova.js     | 1712 ------------------
 .../android/assets/www/cordova_plugins.js       |    3 -
 .../platforms/android/assets/www/css/index.css  |  115 --
 .../platforms/android/assets/www/img/logo.png   |  Bin 21814 -> 0 bytes
 .../platforms/android/assets/www/index.html     |   43 -
 .../platforms/android/assets/www/js/index.js    |   49 -
 .../platforms/android/assets/www/spec.html      |   68 -
 spec/fixtures/platforms/android/build.xml       |   92 -
 spec/fixtures/platforms/android/cordova/build   |   35 -
 .../platforms/android/cordova/check_reqs        |   27 -
 spec/fixtures/platforms/android/cordova/clean   |   34 -
 .../platforms/android/cordova/defaults.xml      |   50 -
 .../platforms/android/cordova/lib/appinfo.js    |   41 -
 .../platforms/android/cordova/lib/build.js      |   89 -
 .../platforms/android/cordova/lib/check_reqs.js |   78 -
 .../platforms/android/cordova/lib/clean.js      |   43 -
 .../platforms/android/cordova/lib/device.js     |   95 -
 .../platforms/android/cordova/lib/emulator.js   |  337 ----
 .../android/cordova/lib/install-device          |   38 -
 .../android/cordova/lib/install-emulator        |   38 -
 .../platforms/android/cordova/lib/list-devices  |   28 -
 .../android/cordova/lib/list-emulator-images    |   29 -
 .../android/cordova/lib/list-started-emulators  |   29 -
 .../platforms/android/cordova/lib/log.js        |   43 -
 .../platforms/android/cordova/lib/run.js        |  124 --
 .../android/cordova/lib/start-emulator          |   38 -
 spec/fixtures/platforms/android/cordova/log     |   33 -
 spec/fixtures/platforms/android/cordova/run     |   35 -
 spec/fixtures/platforms/android/cordova/version |   25 -
 .../fixtures/platforms/android/local.properties |   10 -
 .../platforms/android/proguard-project.txt      |   20 -
 .../platforms/android/project.properties        |   14 -
 .../android/res/drawable-hdpi/icon.png          |  Bin 6080 -> 0 bytes
 .../android/res/drawable-ldpi/icon.png          |  Bin 3096 -> 0 bytes
 .../android/res/drawable-mdpi/icon.png          |  Bin 4090 -> 0 bytes
 .../android/res/drawable-xhdpi/icon.png         |  Bin 7685 -> 0 bytes
 .../platforms/android/res/drawable/icon.png     |  Bin 7685 -> 0 bytes
 .../platforms/android/res/values/strings.xml    |    4 -
 .../platforms/android/res/xml/config.xml        |   18 -
 .../android/src/org/testing/TestBase.java       |   37 -
 spec/fixtures/plugins/ChildBrowser/plugin.xml   |  142 --
 .../ChildBrowser/src/android/ChildBrowser.java  |   19 -
 .../plugins/ChildBrowser/www/childbrowser.js    |   19 -
 .../ChildBrowser/www/childbrowser/image.jpg     |    1 -
 .../ChildBrowser/www/childbrowser_file.html     |    1 -
 spec/fixtures/plugins/android/plugin.xml        |   14 -
 .../plugins/android/src/android/Android.java    |    0
 .../android/src/android/SomethingWithR.java     |    6 -
 spec/fixtures/plugins/android/www/android.js    |    0
 spec/fixtures/plugins/fake1/plugin.xml          |   10 -
 spec/fixtures/plugins/test/plugin.xml           |   14 -
 spec/fixtures/plugins/test/www/test.js          |    0
 .../projects/android/AndroidManifest.xml        |   69 -
 .../projects/android/assets/www/.gitkeep        |    0
 .../projects/android/res/xml/config.xml         |   54 -
 spec/fixtures/projects/android/src/.gitkeep     |    0
 spec/fixtures/projects/windows/bom_test.xml     |   24 -
 spec/fixtures/templates/no_content_config.xml   |   19 -
 spec/helper.js                                  |   19 -
 spec/helpers.js                                 |   46 -
 spec/hooker.spec.js                             |  261 ---
 spec/lazy_load.spec.js                          |  200 --
 spec/metadata/android_parser.spec.js            |  211 ---
 spec/metadata/blackberry_parser.spec.js         |  225 ---
 spec/metadata/firefoxos_parser.spec.js          |   74 -
 spec/metadata/ios_parser.spec.js                |  199 --
 spec/metadata/windows8_parser.spec.js           |  189 --
 spec/metadata/wp7_parser.spec.js                |  208 ---
 spec/metadata/wp8_parser.spec.js                |  208 ---
 spec/platform.spec.js                           |  108 --
 spec/plugin.spec.js                             |   68 -
 spec/plugin_parser.spec.js                      |   48 -
 spec/prepare.spec.js                            |  290 ---
 spec/run.spec.js                                |  114 --
 spec/serve.spec.js                              |  132 --
 spec/test-config.xml                            |   26 -
 spec/util.spec.js                               |  186 --
 spec/wrappers.spec.js                           |   40 -
 spec/xml-helpers.spec.js                        |  137 --
 src/ConfigParser.js                             |  163 --
 src/CordovaError.js                             |   31 -
 src/build.js                                    |   47 -
 src/compile.js                                  |   45 -
 src/config.js                                   |   82 -
 src/create.js                                   |  220 ---
 src/emulate.js                                  |   50 -
 src/events.js                                   |   23 -
 src/hooker.js                                   |  161 --
 src/info.js                                     |  111 --
 src/lazy_load.js                                |  151 --
 src/metadata/amazon_fireos_parser.js            |  183 --
 src/metadata/android_parser.js                  |  303 ----
 src/metadata/blackberry10_parser.js             |  145 --
 src/metadata/firefoxos_parser.js                |  151 --
 src/metadata/ios_parser.js                      |  202 ---
 src/metadata/ubuntu_parser.js                   |  162 --
 src/metadata/windows8_parser.js                 |  339 ----
 src/metadata/wp7_parser.js                      |  262 ---
 src/metadata/wp8_parser.js                      |  287 ---
 src/platform.js                                 |  399 ----
 src/plugin.js                                   |  210 ---
 src/plugin_parser.js                            |   30 -
 src/prepare.js                                  |  187 --
 src/run.js                                      |   48 -
 src/serve.js                                    |  224 ---
 src/superspawn.js                               |  139 --
 src/util.js                                     |  214 ---
 src/xml-helpers.js                              |  171 --
 templates/config.xml                            |   19 -
 templates/hooks-README.md                       |   83 -
 276 files changed, 12793 insertions(+), 12793 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/ConfigParser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/ConfigParser.spec.js b/cordova-lib/spec-cordova/ConfigParser.spec.js
new file mode 100644
index 0000000..1faec88
--- /dev/null
+++ b/cordova-lib/spec-cordova/ConfigParser.spec.js
@@ -0,0 +1,84 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var path = require('path'),
+    fs = require('fs'),
+    ConfigParser = require('../src/ConfigParser'),
+    xml = path.join(__dirname, 'test-config.xml'),
+    xml_contents = fs.readFileSync(xml, 'utf-8');
+
+describe('config.xml parser', function () {
+    var readFile;
+    beforeEach(function() {
+        readFile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
+    });
+
+    it('should create an instance based on an xml file', function() {
+        var cfg;
+        expect(function () {
+            cfg = new ConfigParser(xml);
+        }).not.toThrow();
+        expect(cfg).toBeDefined();
+        expect(cfg.doc).toBeDefined();
+    });
+
+    describe('methods', function() {
+        var cfg;
+        beforeEach(function() {
+            cfg = new ConfigParser(xml);
+        });
+
+        describe('package name / id', function() {
+            it('should get the (default) packagename', function() {
+                expect(cfg.packageName()).toEqual('io.cordova.hellocordova');
+            });
+            it('should allow setting the packagename', function() {
+                cfg.setPackageName('this.is.bat.country');
+                expect(cfg.packageName()).toEqual('this.is.bat.country');
+            });
+        });
+
+        describe('version', function() {
+            it('should get the version', function() {
+                expect(cfg.version()).toEqual('0.0.1');
+            });
+            it('should allow setting the version', function() {
+                cfg.setVersion('2.0.1');
+                expect(cfg.version()).toEqual('2.0.1');
+            });
+        });
+
+        describe('app name', function() {
+            it('should get the (default) app name', function() {
+                expect(cfg.name()).toEqual('Hello Cordova');
+            });
+            it('should allow setting the app name', function() {
+                cfg.setName('this.is.bat.country');
+                expect(cfg.name()).toEqual('this.is.bat.country');
+            });
+        });
+        describe('preference', function() {
+            it('should get value of existing preference', function() {
+                expect(cfg.getPreference('fullscreen')).toEqual('true');
+            });
+            it('should get undefined as non existing preference', function() {
+                expect(cfg.getPreference('zimzooo!')).toEqual(undefined);
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/build.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/build.spec.js b/cordova-lib/spec-cordova/build.spec.js
new file mode 100644
index 0000000..259c3d4
--- /dev/null
+++ b/cordova-lib/spec-cordova/build.spec.js
@@ -0,0 +1,129 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    platforms = require('../platforms'),
+    shell = require('shelljs'),
+    path = require('path'),
+    fs = require('fs'),
+    hooker = require('../src/hooker'),
+    Q = require('q'),
+    util = require('../src/util');
+
+var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
+
+describe('build command', function() {
+    var is_cordova, cd_project_root, list_platforms, fire;
+    var project_dir = '/some/path';
+    var prepare_spy, compile_spy;
+    var result;
+
+    function buildPromise(f) {
+        f.then(function() { result = true; }, function(err) { result = err; });
+    }
+
+    function wrapper(f, post) {
+        runs(function() {
+            buildPromise(f);
+        });
+        waitsFor(function() { return result; }, 'promise never resolved', 500);
+        runs(post);
+    }
+
+    beforeEach(function() {
+        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
+        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
+        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
+        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
+        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
+        compile_spy = spyOn(cordova.raw, 'compile').andReturn(Q());
+    });
+    describe('failure', function() {
+        it('should not run inside a project with no platforms', function(done) {
+            list_platforms.andReturn([]);
+            Q().then(cordova.raw.build).then(function() {
+                expect('this call').toBe('fail');
+            }, function(err) {
+                expect(err.message).toEqual(
+                    'No platforms added to this project. Please use `cordova platform add <platform>`.'
+                )
+            }).fin(done);
+        });
+
+        it('should not run outside of a Cordova-based project', function(done) {
+            is_cordova.andReturn(false);
+
+            Q().then(cordova.raw.build).then(function() {
+                expect('this call').toBe('fail');
+            }, function(err) {
+                expect(err.message).toEqual(
+                    'Current working directory is not a Cordova-based project.'
+                )
+            }).fin(done);
+        });
+    });
+
+    describe('success', function() {
+        it('should run inside a Cordova-based project with at least one added platform and call both prepare and compile', function(done) {
+            cordova.raw.build(['android','ios']).then(function() {
+                var opts = {verbose: false, platforms: ['android', 'ios'], options: []};
+                expect(prepare_spy).toHaveBeenCalledWith(opts);
+                expect(compile_spy).toHaveBeenCalledWith(opts);
+                done();
+            });
+        });
+        it('should pass down options', function(done) {
+            cordova.raw.build({platforms: ['android'], options: ['--release']}).then(function() {
+                var opts = {platforms: ['android'], options: ["--release"], verbose: false};
+                expect(prepare_spy).toHaveBeenCalledWith(opts);
+                expect(compile_spy).toHaveBeenCalledWith(opts);
+                done();
+            });
+        });
+    });
+
+    describe('hooks', function() {
+        describe('when platforms are added', function() {
+            it('should fire before hooks through the hooker module', function(done) {
+                cordova.raw.build(['android', 'ios']).then(function() {
+                    expect(fire).toHaveBeenCalledWith('before_build', {verbose: false, platforms:['android', 'ios'], options: []});
+                    done();
+                });
+            });
+            it('should fire after hooks through the hooker module', function(done) {
+                cordova.raw.build('android').then(function() {
+                     expect(fire).toHaveBeenCalledWith('after_build', {verbose: false, platforms:['android'], options: []});
+                     done();
+                });
+            });
+        });
+
+        describe('with no platforms added', function() {
+            it('should not fire the hooker', function(done) {
+                list_platforms.andReturn([]);
+                Q().then(cordova.raw.build).then(function() {
+                    expect('this call').toBe('fail');
+                }, function(err) {
+                    expect(err.message).toEqual(
+                        'No platforms added to this project. Please use `cordova platform add <platform>`.'
+                    )
+                }).fin(done);
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/compile.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/compile.spec.js b/cordova-lib/spec-cordova/compile.spec.js
new file mode 100644
index 0000000..c1fc8b9
--- /dev/null
+++ b/cordova-lib/spec-cordova/compile.spec.js
@@ -0,0 +1,113 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    platforms = require('../platforms'),
+    path = require('path'),
+    fs = require('fs'),
+    hooker = require('../src/hooker'),
+    superspawn = require('../src/superspawn'),
+    util = require('../src/util'),
+    Q = require('q'),
+    os = require('os');
+
+
+var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
+
+
+describe('compile command', function() {
+    var is_cordova, list_platforms, fire, result, cd_project_root;
+    var project_dir = '/some/path';
+
+    function wrapper(f, post) {
+        runs(function() {
+            Q().then(f).then(function() { result = true; }, function(err) { result = err; });
+        });
+        waitsFor(function() { return result; }, 'promise never resolved', 500);
+        runs(post);
+    }
+    beforeEach(function() {
+        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
+        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
+        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
+        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
+        spyOn(superspawn, 'spawn').andCallFake(function() { return Q() });
+    });
+    describe('failure', function() {
+        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() {
+            list_platforms.andReturn([]);
+            wrapper(cordova.raw.compile, function() {
+                expect('' + result).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
+            });
+        });
+        it('should not run outside of a Cordova-based project', function() {
+            is_cordova.andReturn(false);
+            wrapper(cordova.raw.compile, function() {
+                expect(result instanceof Error).toBe(true);
+            });
+        });
+    });
+
+    describe('success', function() {
+        it('should run inside a Cordova-based project with at least one added platform and shell out to build', function(done) {
+            cordova.raw.compile(['android','ios']).then(function() {
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'build'), [], jasmine.any(Object));
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'build'), [], jasmine.any(Object));
+                done();
+            });
+        });
+
+        it('should pass down optional parameters', function (done) {
+            cordova.raw.compile({platforms:["blackberry10"], options:["--release"]}).then(function () {
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'build'), ['--release'], jasmine.any(Object));
+                done();
+            });
+        });
+    });
+
+    describe('hooks', function() {
+        describe('when platforms are added', function() {
+            it('should fire before hooks through the hooker module', function(done) {
+                cordova.raw.compile(['android', 'ios']).then(function() {
+                    expect(fire).toHaveBeenCalledWith('before_compile', {verbose: false, platforms:['android', 'ios'], options: []});
+                    done();
+                });
+            });
+            it('should fire after hooks through the hooker module', function(done) {
+                cordova.raw.compile('android').then(function() {
+                     expect(fire).toHaveBeenCalledWith('after_compile', {verbose: false, platforms:['android'], options: []});
+                     done();
+                });
+            });
+        });
+
+        describe('with no platforms added', function() {
+            it('should not fire the hooker', function(done) {
+                list_platforms.andReturn([]);
+                Q().then(cordova.raw.compile).then(function() {
+                    expect('this call').toBe('fail');
+                }, function(err) {
+                    expect(fire).not.toHaveBeenCalled();
+                    expect(err.message).toContain(
+                        'No platforms added to this project. Please use `cordova platform add <platform>`.'
+                    )
+                }).fin(done);
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/create.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/create.spec.js b/cordova-lib/spec-cordova/create.spec.js
new file mode 100644
index 0000000..ebdfab5
--- /dev/null
+++ b/cordova-lib/spec-cordova/create.spec.js
@@ -0,0 +1,138 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var helpers = require('./helpers'),
+    path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    Q = require('q'),
+    config = require('../src/config'),
+    events = require('../src/events'),
+    util = require('../src/util'),
+    ConfigParser = require('../src/ConfigParser'),
+    cordova = require('../cordova');
+
+// A utility function to generate all combinations of elements from 2 arrays.
+// crossConcat(['x', 'y'], ['1', '2', '3'])
+// -> [ 'x1', 'x2', 'x3', 'y1', 'y2', 'y3']
+var crossConcat = function(a, b, delimiter){
+    var result = [];
+    delimiter = delimiter || '';
+    for (var i = 0; i < a.length; i++) {
+        for (var j = 0; j < b.length; j++) {
+            result.push(a[i] + delimiter + b[j]);
+        }
+    }
+    return result;
+};
+
+var tmpDir = helpers.tmpDir('create_test');
+var appName = 'TestBase';
+var appId = 'org.testing';
+var project = path.join(tmpDir, appName);
+var cordovaDir = path.join(project, '.cordova');
+var configNormal = {
+      lib: {
+        www: {
+          uri: path.join(__dirname, 'fixtures', 'base', 'www'),
+          version: "testCordovaCreate",
+          id: appName
+        }
+      }
+    };
+var configSymlink = {
+      lib: {
+        www: {
+          uri: path.join(__dirname, 'fixtures', 'base'), // "create" should copy or link the www child of this dir and not the dir itself.
+          link: true
+        }
+      }
+    };
+
+
+describe('create end-to-end', function() {
+
+    beforeEach(function() {
+        shell.rm('-rf', project);
+    });
+    afterEach(function() {
+        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
+        shell.rm('-rf', tmpDir);
+    });
+
+    function checkProject() {
+        // Check if top level dirs exist.
+        var dirs = ['hooks', 'platforms', 'merges', 'plugins', 'www'];
+        dirs.forEach(function(d) {
+            expect(path.join(project, d)).toExist();
+        });
+
+        expect(path.join(project, 'hooks', 'README.md')).toExist();
+
+        // Check if config files exist.
+        expect(path.join(project, 'www', 'index.html')).toExist();
+
+        // Check that www/config.xml was updated.
+        var configXml = new ConfigParser(path.join(project, 'www', 'config.xml'));
+        expect(configXml.packageName()).toEqual(appId);
+
+        // TODO (kamrik): check somehow that we got the right config.xml from the fixture and not some place else.
+        // expect(configXml.name()).toEqual('TestBase');
+    }
+
+    var results;
+    events.on('results', function(res) { results = res; });
+
+    it('should successfully run with regular config', function(done) {
+        // Call cordova create with no args, should return help.
+        cordova.raw.create()
+        .then(function() {
+            expect(results).toMatch(/synopsis/gi);
+        })
+        .then(function() {
+            // Create a real project
+            return cordova.raw.create(project, appId, appName, configNormal);
+        })
+        .then(checkProject)
+        .fail(function(err) {
+            console.log(err);
+            expect(err).toBeUndefined();
+        })
+        .fin(done);
+    });
+
+    it('should successfully run with symlinked www', function(done) {
+        // Call cordova create with no args, should return help.
+        cordova.raw.create(project, appId, appName, configSymlink)
+        .then(checkProject)
+        .then(function() {
+            // Check that www is really a symlink
+            expect(fs.lstatSync(path.join(project, 'www')).isSymbolicLink()).toBe(true);
+        })
+        .fail(function(err) {
+            if(process.platform.slice(0, 3) == 'win') {
+                // Allow symlink error if not in admin mode
+                expect(err.message).toBe("Symlinks on Windows require Administrator privileges");
+            } else {
+                expect(err).toBeUndefined();
+            }
+        })
+        .fin(done);
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/emulate.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/emulate.spec.js b/cordova-lib/spec-cordova/emulate.spec.js
new file mode 100644
index 0000000..8435535
--- /dev/null
+++ b/cordova-lib/spec-cordova/emulate.spec.js
@@ -0,0 +1,115 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    platforms = require('../platforms'),
+    superspawn = require('../src/superspawn'),
+    path = require('path'),
+    fs = require('fs'),
+    hooker = require('../src/hooker'),
+    Q = require('q'),
+    util = require('../src/util'),
+    os = require('os');
+
+var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
+
+describe('emulate command', function() {
+    var is_cordova, cd_project_root, list_platforms, fire, result;
+    var project_dir = '/some/path';
+    var prepare_spy;
+
+    function wrapper(f, post) {
+        runs(function() {
+            Q().then(f).then(function() { result = true; }, function(err) { result = err; });
+        });
+        waitsFor(function() { return result; }, 'promise never resolved', 500);
+        runs(post);
+    }
+
+    beforeEach(function() {
+        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
+        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
+        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
+        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
+        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
+        spyOn(superspawn, 'spawn').andCallFake(Q);
+    });
+    describe('failure', function() {
+        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() {
+            list_platforms.andReturn([]);
+            wrapper(cordova.raw.emulate, function() {
+                expect(''+ result).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
+            });
+        });
+        it('should not run outside of a Cordova-based project', function() {
+            is_cordova.andReturn(false);
+            wrapper(cordova.raw.emulate, function() {
+                expect(result instanceof Error).toBe(true);
+            });
+        });
+    });
+
+    describe('success', function() {
+        it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the emulate script', function(done) {
+            cordova.raw.emulate(['android','ios']).then(function(err) {
+                expect(prepare_spy).toHaveBeenCalledWith(['android', 'ios']);
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), ['--emulator'], jasmine.any(Object));
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator'], jasmine.any(Object));
+
+                done();
+            });
+        });
+        it('should pass down options', function(done) {
+            cordova.raw.emulate({platforms: ['ios'], options:["--optionTastic"]}).then(function(err) {
+                expect(prepare_spy).toHaveBeenCalledWith(['ios']);
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator', '--optionTastic'], jasmine.any(Object));
+
+                done();
+            });
+        });
+    });
+
+    describe('hooks', function() {
+        describe('when platforms are added', function() {
+            it('should fire before hooks through the hooker module', function(done) {
+                cordova.raw.emulate(['android', 'ios']).then(function() {
+                    expect(fire).toHaveBeenCalledWith('before_emulate', {verbose: false, platforms:['android', 'ios'], options: []});
+                    done();
+                });
+            });
+            it('should fire after hooks through the hooker module', function(done) {
+                cordova.raw.emulate('android').then(function() {
+                     expect(fire).toHaveBeenCalledWith('after_emulate', {verbose: false, platforms:['android'], options: []});
+                     done();
+                });
+            });
+        });
+
+        describe('with no platforms added', function() {
+            it('should not fire the hooker', function(done) {
+                list_platforms.andReturn([]);
+                Q().then(cordova.raw.emulate).then(function() {
+                    expect('this call').toBe('fail');
+                }, function(err) {
+                    expect(fire).not.toHaveBeenCalled();
+                    expect(''+err).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.')
+                }).fin(done);
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json b/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json
new file mode 100644
index 0000000..662fc9d
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json
@@ -0,0 +1,22 @@
+{
+  "id": "org.testing",
+  "name":"TestBase",
+  "lib": {
+    "android": {
+      "uri": "/some/junk/path",
+      "version": "dev",
+      "id": "cordova-android-dev"
+    },
+    "ios": {
+      "uri": "/some/junk/path",
+      "version": "dev",
+      "id": "cordova-ios-dev"
+    },
+    "wp8": {
+      "uri": "/some/junk/path",
+      "version": "dev",
+      "id": "cordova-wp8-dev"
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/merges/.svn
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/merges/.svn b/cordova-lib/spec-cordova/fixtures/base/merges/.svn
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/plugins/.svn
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/plugins/.svn b/cordova-lib/spec-cordova/fixtures/base/plugins/.svn
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/www/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/config.xml b/cordova-lib/spec-cordova/fixtures/base/www/config.xml
new file mode 100644
index 0000000..9e7b9e0
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/base/www/config.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+    <name>TestBase</name>
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+    <author email="dev@cordova.apache.org" href="http://cordova.io">
+        Apache Cordova Team
+    </author>
+    <content src="index.html" />
+    <access origin="*" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/www/css/index.css
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/css/index.css b/cordova-lib/spec-cordova/fixtures/base/www/css/index.css
new file mode 100644
index 0000000..51daa79
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/base/www/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+* {
+    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
+    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
+    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
+    background-color:#E4E4E4;
+    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0, #A7A7A7),
+        color-stop(0.51, #E4E4E4)
+    );
+    background-attachment:fixed;
+    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+    font-size:12px;
+    height:100%;
+    margin:0px;
+    padding:0px;
+    text-transform:uppercase;
+    width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+    position:absolute;             /* position in the center of the screen */
+    left:50%;
+    top:50%;
+    height:50px;                   /* text area height */
+    width:225px;                   /* text area width */
+    text-align:center;
+    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
+    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
+                                   /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+    .app {
+        background-position:left center;
+        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
+        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
+                                      /* offset horizontal: half of image width and text area width */
+    }
+}
+
+h1 {
+    font-size:24px;
+    font-weight:normal;
+    margin:0px;
+    overflow:visible;
+    padding:0px;
+    text-align:center;
+}
+
+.event {
+    border-radius:4px;
+    -webkit-border-radius:4px;
+    color:#FFFFFF;
+    font-size:12px;
+    margin:0px 30px;
+    padding:2px 0px;
+}
+
+.event.listening {
+    background-color:#333333;
+    display:block;
+}
+
+.event.received {
+    background-color:#4B946A;
+    display:none;
+}
+
+@keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+@-webkit-keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+.blink {
+    animation:fade 3000ms infinite;
+    -webkit-animation:fade 3000ms infinite;
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png b/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png
new file mode 100644
index 0000000..9519e7d
Binary files /dev/null and b/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/www/index.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/index.html b/cordova-lib/spec-cordova/fixtures/base/www/index.html
new file mode 100644
index 0000000..bde5741
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/base/www/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <meta name="format-detection" content="telephone=no" />
+        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
+        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+        <link rel="stylesheet" type="text/css" href="css/index.css" />
+        <title>Hello World</title>
+    </head>
+    <body>
+        <div class="app">
+            <h1>Apache Cordova</h1>
+            <div id="deviceready" class="blink">
+                <p class="event listening">Connecting to Device</p>
+                <p class="event received">Device is Ready</p>
+            </div>
+        </div>
+        <script type="text/javascript" src="cordova.js"></script>
+        <script type="text/javascript" src="js/index.js"></script>
+        <script type="text/javascript">
+            app.initialize();
+        </script>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/www/js/index.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/js/index.js b/cordova-lib/spec-cordova/fixtures/base/www/js/index.js
new file mode 100644
index 0000000..31d9064
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/base/www/js/index.js
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+var app = {
+    // Application Constructor
+    initialize: function() {
+        this.bindEvents();
+    },
+    // Bind Event Listeners
+    //
+    // Bind any events that are required on startup. Common events are:
+    // 'load', 'deviceready', 'offline', and 'online'.
+    bindEvents: function() {
+        document.addEventListener('deviceready', this.onDeviceReady, false);
+    },
+    // deviceready Event Handler
+    //
+    // The scope of 'this' is the event. In order to call the 'receivedEvent'
+    // function, we must explicity call 'app.receivedEvent(...);'
+    onDeviceReady: function() {
+        app.receivedEvent('deviceready');
+    },
+    // Update DOM on a Received Event
+    receivedEvent: function(id) {
+        var parentElement = document.getElementById(id);
+        var listeningElement = parentElement.querySelector('.listening');
+        var receivedElement = parentElement.querySelector('.received');
+
+        listeningElement.setAttribute('style', 'display:none;');
+        receivedElement.setAttribute('style', 'display:block;');
+
+        console.log('Received Event: ' + id);
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/base/www/spec.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/spec.html b/cordova-lib/spec-cordova/fixtures/base/www/spec.html
new file mode 100644
index 0000000..71f00de
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/base/www/spec.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<html>
+    <head>
+        <title>Jasmine Spec Runner</title>
+
+        <!-- jasmine source -->
+        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
+        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
+
+        <!-- include source files here... -->
+        <script type="text/javascript" src="js/index.js"></script>
+
+        <!-- include spec files here... -->
+        <script type="text/javascript" src="spec/helper.js"></script>
+        <script type="text/javascript" src="spec/index.js"></script>
+
+        <script type="text/javascript">
+            (function() {
+                var jasmineEnv = jasmine.getEnv();
+                jasmineEnv.updateInterval = 1000;
+
+                var htmlReporter = new jasmine.HtmlReporter();
+
+                jasmineEnv.addReporter(htmlReporter);
+
+                jasmineEnv.specFilter = function(spec) {
+                    return htmlReporter.specFilter(spec);
+                };
+
+                var currentWindowOnload = window.onload;
+
+                window.onload = function() {
+                    if (currentWindowOnload) {
+                        currentWindowOnload();
+                    }
+                    execJasmine();
+                };
+
+                function execJasmine() {
+                    jasmineEnv.execute();
+                }
+            })();
+        </script>
+    </head>
+    <body>
+        <div id="stage" style="display:none;"></div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat
new file mode 100644
index 0000000..a89b4c8
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat
@@ -0,0 +1,2 @@
+@ECHO OFF
+EXIT /B 1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat
new file mode 100644
index 0000000..ada7136
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat
@@ -0,0 +1,2 @@
+@ECHO OFF
+ECHO "Dotted files in hook dirs should not be called" > dotted_hook_should_not_fire.txt
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat
new file mode 100644
index 0000000..a88c8c5
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat
@@ -0,0 +1,3 @@
+@ECHO OFF
+rem ECHO this is script 0 in %~dp0
+ECHO b >> hooks_order.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat
new file mode 100644
index 0000000..be004c5
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat
@@ -0,0 +1,5 @@
+@ECHO OFF
+rem ECHO this is script 1 in %~dp0
+ECHO a >> hooks_order.txt
+ECHO %1 > hooks_params.txt
+node -e "console.log(JSON.stringify(process.env, null, 2))" > hooks_env.json

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh
new file mode 100755
index 0000000..379a4c9
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh
@@ -0,0 +1 @@
+exit 1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh
new file mode 100755
index 0000000..e5fa07f
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh
@@ -0,0 +1 @@
+echo "Dotted files in hook dirs should not be called" > dotted_hook_should_not_fire.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh
new file mode 100755
index 0000000..f410ee2
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh
@@ -0,0 +1,2 @@
+#echo "this is script 0 in `pwd`";
+echo b >> hooks_order.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh
new file mode 100755
index 0000000..892869d
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh
@@ -0,0 +1,4 @@
+#echo "this is script 1 in `pwd`";
+echo a >> hooks_order.txt
+echo $1 > hooks_params.txt
+node -e "console.log(JSON.stringify(process.env, null, 2))" > hooks_env.json

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION b/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION
new file mode 100644
index 0000000..15a2799
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION
@@ -0,0 +1 @@
+3.3.0

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js b/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js
new file mode 100644
index 0000000..91c51fc
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js
@@ -0,0 +1 @@
+This is a placeholder file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml
new file mode 100644
index 0000000..be3f245
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" android:windowSoftInputMode="adjustPan" package="org.testing" xmlns:android="http://schemas.android.com/apk/res/android">
+    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application android:debuggable="true" android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
+        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="TestBase" android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
+</manifest>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml
new file mode 100644
index 0000000..9e7b9e0
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+    <name>TestBase</name>
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+    <author email="dev@cordova.apache.org" href="http://cordova.io">
+        Apache Cordova Team
+    </author>
+    <content src="index.html" />
+    <access origin="*" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>


[09/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/info.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/info.js b/cordova-lib/src/cordova/info.js
new file mode 100644
index 0000000..c8b8e24
--- /dev/null
+++ b/cordova-lib/src/cordova/info.js
@@ -0,0 +1,111 @@
+/**
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+'License'); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+ */
+
+/*
+A utility funciton to help output the information needed
+when submitting a help request.
+Outputs to a file
+ */
+var cordova_util = require('./util'),
+    superspawn   = require('./superspawn'),
+    package      = require('../package'),
+    path         = require('path'),
+    fs           = require('fs'),
+    Q            = require('q');
+
+// Execute using a child_process exec, for any async command
+function execSpawn(command, args, resultMsg, errorMsg) {
+    return superspawn.spawn(command, args).then(function(result) {
+        return resultMsg + result;
+    }, function(error) {
+        return errorMsg + error;
+    });
+}
+
+function getPlatformInfo(platform, projectRoot) {
+    switch (platform) {
+    case 'ios':
+        return execSpawn('xcodebuild', ['-version'], 'iOS platform:\n\n', 'Error retrieving iOS platform information: ');
+    case 'android':
+        return execSpawn('android', ['list', 'target'], 'Android platform:\n\n', 'Error retrieving Android platform information: ');
+    }
+}
+
+
+module.exports = function info() {
+    //Get projectRoot
+    var projectRoot = cordova_util.cdProjectRoot();
+    var output = '';
+    if (!projectRoot) {
+        return Q.reject(new Error('Current working directory is not a Cordova-based project.'));
+    }
+
+    //Array of functions, Q.allSettled
+    console.log('Collecting Data...\n\n');
+    return Q.allSettled([
+            //Get Node version
+            Q('Node version: ' + process.version),
+            //Get Cordova version
+            Q('Cordova version: ' + package.version),
+            //Get project config.xml file using ano
+            getProjectConfig(projectRoot),
+            //Get list of plugins
+            listPlugins(projectRoot),
+            //Get Platforms information
+            getPlatforms(projectRoot)
+        ]).then(function(promises) {
+        promises.forEach(function(p) {
+            output += p.state === 'fulfilled' ? p.value + '\n\n' : p.reason + '\n\n';
+        });
+        console.info(output);
+        fs.writeFile(path.join(projectRoot, 'info.txt'), output, 'utf-8', function (err) {
+            if (err)
+                throw err;
+        });
+    });
+};
+
+function getPlatforms(projectRoot) {
+    var platforms = cordova_util.listPlatforms(projectRoot);
+    if (platforms.length) {
+        return Q.all(platforms.map(function(p) {
+            return getPlatformInfo(p, projectRoot);
+        })).then(function(outs) {
+          return outs.join('\n\n');
+        });
+    }
+    return Q.reject('No Platforms Currently Installed');
+}
+
+function listPlugins(projectRoot) {
+    var pluginPath = path.join(projectRoot, 'plugins'),
+        plugins    = cordova_util.findPlugins(pluginPath);
+
+    if (!plugins.length) {
+        return Q.reject('No Plugins Currently Installed');
+    }
+    return Q('Plugins: \n\n' + plugins);
+}
+
+function getProjectConfig(projectRoot) {
+    if (!fs.existsSync(projectRoot)  ) {
+        return Q.reject('Config.xml file not found');
+    }
+    return Q('Config.xml file: \n\n' + (fs.readFileSync(cordova_util.projectConfig(projectRoot), 'utf-8')));
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/lazy_load.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/lazy_load.js b/cordova-lib/src/cordova/lazy_load.js
new file mode 100644
index 0000000..bd6cf77
--- /dev/null
+++ b/cordova-lib/src/cordova/lazy_load.js
@@ -0,0 +1,151 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var path          = require('path'),
+    fs            = require('fs'),
+    shell         = require('shelljs'),
+    platforms     = require('../platforms'),
+    npmconf       = require('npmconf'),
+    events        = require('./events'),
+    request       = require('request'),
+    config        = require('./config'),
+    hooker        = require('./hooker'),
+    zlib          = require('zlib'),
+    tar           = require('tar'),
+    URL           = require('url'),
+    Q             = require('q'),
+    util          = require('./util');
+
+module.exports = {
+    // Returns a promise for the path to the lazy-loaded directory.
+    cordova:function lazy_load(platform) {
+        if (!(platform in platforms)) {
+            return Q.reject(new Error('Cordova library "' + platform + '" not recognized.'));
+        }
+
+        var url = platforms[platform].url + ';a=snapshot;h=' + platforms[platform].version + ';sf=tgz';
+        return module.exports.custom(url, 'cordova', platform, platforms[platform].version);
+    },
+    // Returns a promise for the path to the lazy-loaded directory.
+    custom:function(url, id, platform, version) {
+        var download_dir;
+        var tmp_dir;
+        var lib_dir;
+
+        // Return early for already-cached remote URL, or for local URLs.
+        var uri = URL.parse(url);
+        var isUri = uri.protocol && uri.protocol[1] != ':'; // second part of conditional is for awesome windows support. fuuu windows
+        if (isUri) {
+            download_dir = (platform == 'wp7' || platform == 'wp8' ? path.join(util.libDirectory, 'wp', id, version) :
+                                                                     path.join(util.libDirectory, platform, id, version));
+            lib_dir = platforms[platform] && platforms[platform].subdirectory && platform !== "blackberry10" ? path.join(download_dir, platforms[platform].subdirectory) : download_dir;
+            if (fs.existsSync(download_dir)) {
+                events.emit('verbose', id + ' library for "' + platform + '" already exists. No need to download. Continuing.');
+                return Q(lib_dir);
+            }
+        } else {
+            // Local path.
+            lib_dir = platforms[platform] && platforms[platform].subdirectory ? path.join(url, platforms[platform].subdirectory) : url;
+            return Q(lib_dir);
+        }
+        return hooker.fire('before_library_download', {
+            platform:platform,
+            url:url,
+            id:id,
+            version:version
+        }).then(function() {
+            var uri = URL.parse(url);
+            var d = Q.defer();
+            npmconf.load(function(err, conf) {
+                // Check if NPM proxy settings are set. If so, include them in the request() call.
+                var proxy;
+                if (uri.protocol == 'https:') {
+                    proxy = conf.get('https-proxy');
+                } else if (uri.protocol == 'http:') {
+                    proxy = conf.get('proxy');
+                }
+                var strictSSL = conf.get('strict-ssl');
+
+                // Create a tmp dir. Using /tmp is a problem because it's often on a different partition and sehll.mv()
+                // fails in this case with "EXDEV, cross-device link not permitted".
+                tmp_subidr = 'tmp_' + id + '_' + process.pid + '_' + (new Date).valueOf();
+                tmp_dir = path.join(util.libDirectory, 'tmp', tmp_subidr);
+                shell.rm('-rf', tmp_dir);
+                shell.mkdir('-p', tmp_dir);
+
+                var size = 0;
+                var request_options = {uri:url};
+                if (proxy) {
+                    request_options.proxy = proxy;
+                }
+                if (typeof strictSSL == 'boolean') {
+                    request_options.strictSSL = strictSSL;
+                }
+                events.emit('verbose', 'Requesting ' + JSON.stringify(request_options) + '...');
+                events.emit('log', 'Downloading ' + id + ' library for ' + platform + '...');
+                var req = request.get(request_options, function(err, res, body) {
+                    if (err) {
+                        shell.rm('-rf', tmp_dir);
+                        d.reject(err);
+                    } else if (res.statusCode != 200) {
+                        shell.rm('-rf', tmp_dir);
+                        d.reject(new Error('HTTP error ' + res.statusCode + ' retrieving version ' + version + ' of ' + id + ' for ' + platform));
+                    } else {
+                        size = body.length;
+                    }
+                });
+
+                req.pipe(zlib.createUnzip())
+                .pipe(tar.Extract({path:tmp_dir}))
+                .on('error', function(err) {
+                    shell.rm('-rf', tmp_dir);
+                    d.reject(err);
+                })
+                .on('end', function() {
+                    events.emit('verbose', 'Downloaded, unzipped and extracted ' + size + ' byte response.');
+                    events.emit('log', 'Download complete');
+                    var entries = fs.readdirSync(tmp_dir);
+                    var entry = path.join(tmp_dir, entries[0]);
+                    shell.mkdir('-p', download_dir);
+                    shell.mv('-f', path.join(entry, (platform=='blackberry10'?'blackberry10':''), '*'), download_dir);
+                    shell.rm('-rf', tmp_dir);
+                    d.resolve(hooker.fire('after_library_download', {
+                        platform:platform,
+                        url:url,
+                        id:id,
+                        version:version,
+                        path: lib_dir,
+                        size:size,
+                        symlink:false
+                    }));
+                });
+            });
+            return d.promise.then(function () { return lib_dir; });
+        });
+    },
+    // Returns a promise for the path to the lazy-loaded directory.
+    based_on_config:function(project_root, platform) {
+        var custom_path = config.has_custom_path(project_root, platform);
+        if (custom_path) {
+            var dot_file = config.read(project_root);
+            return module.exports.custom(dot_file.lib[platform].uri, dot_file.lib[platform].id, platform, dot_file.lib[platform].version);
+        } else {
+            return module.exports.cordova(platform);
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js b/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
new file mode 100644
index 0000000..f119279
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
@@ -0,0 +1,183 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs            = require('fs'),
+    path          = require('path'),
+    xml           = require('../xml-helpers'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    project_config= require('../config'),
+    Q             = require('q'),
+    ConfigParser = require('../ConfigParser'),
+    CordovaError = require('../CordovaError');
+
+var awv_interface='awv_interface.jar';
+
+var default_prefs = {
+    "useBrowserHistory":"true",
+    "exit-on-suspend":"false"
+};
+
+module.exports = function android_parser(project) {
+    if (!fs.existsSync(path.join(project, 'AndroidManifest.xml'))) {
+        throw new CordovaError('The provided path "' + project + '" is not an Android project.');
+    }
+    this.path = project;
+    this.strings = path.join(this.path, 'res', 'values', 'strings.xml');
+    this.manifest = path.join(this.path, 'AndroidManifest.xml');
+    this.android_config = path.join(this.path, 'res', 'xml', 'config.xml');
+};
+
+// Returns a promise.
+// Returns a promise.
+module.exports.check_requirements = function(project_root) {
+    // Rely on platform's bin/create script to check requirements.
+    return Q(true);
+};
+
+module.exports.prototype = {
+    findOrientationPreference: function(config) {
+        var ret = config.getPreference('orientation');
+        if (ret && ret != 'default' && ret != 'portrait' && ret != 'landscape') {
+            events.emit('warn', 'Unknown value for orientation preference: ' + ret);
+            ret = null;
+        }
+
+        return ret;
+    },
+
+    update_from_config:function(config) {
+        if (config instanceof ConfigParser) {
+        } else throw new Error('update_from_config requires a ConfigParser object');
+
+        // Update app name by editing res/values/strings.xml
+        var name = config.name();
+        var strings = xml.parseElementtreeSync(this.strings);
+        strings.find('string[@name="app_name"]').text = name;
+        fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
+        events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
+
+        var manifest = xml.parseElementtreeSync(this.manifest);
+        // Update the version by changing the AndroidManifest android:versionName
+        var version = config.version();
+        manifest.getroot().attrib["android:versionName"] = version;
+
+        // Update package name by changing the AndroidManifest id and moving the entry class around to the proper package directory
+        var pkg = config.packageName();
+        pkg = pkg.replace(/-/g, '_'); // Java packages cannot support dashes
+        var orig_pkg = manifest.getroot().attrib.package;
+        manifest.getroot().attrib.package = pkg;
+
+         // Set the orientation in the AndroidManifest
+        var orientationPref = this.findOrientationPreference(config);
+        if (orientationPref) {
+            var act = manifest.getroot().find('./application/activity');
+            switch (orientationPref) {
+                case 'default':
+                    delete act.attrib["android:screenOrientation"];
+                    break;
+                case 'portrait':
+                    act.attrib["android:screenOrientation"] = 'userPortrait';
+                    break;
+                case 'landscape':
+                    act.attrib["android:screenOrientation"] = 'userLandscape';
+            }
+        }
+
+
+        // Write out AndroidManifest.xml
+        fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
+
+        var orig_pkgDir = path.join(this.path, 'src', path.join.apply(null, orig_pkg.split('.')));
+        var java_files = fs.readdirSync(orig_pkgDir).filter(function(f) {
+          return f.indexOf('.svn') == -1 && f.indexOf('.java') >= 0 && fs.readFileSync(path.join(orig_pkgDir, f), 'utf-8').match(/extends\s+CordovaActivity/);
+        });
+        if (java_files.length == 0) {
+          throw new Error('No Java files found which extend CordovaActivity.');
+        } else if(java_files.length > 1) {
+          events.emit('log', 'Multiple candidate Java files (.java files which extend CordovaActivity) found. Guessing at the first one, ' + java_files[0]);
+        }
+
+        var orig_java_class = java_files[0];
+        var pkgDir = path.join(this.path, 'src', path.join.apply(null, pkg.split('.')));
+        shell.mkdir('-p', pkgDir);
+        var orig_javs = path.join(orig_pkgDir, orig_java_class);
+        var new_javs = path.join(pkgDir, orig_java_class);
+        var javs_contents = fs.readFileSync(orig_javs, 'utf-8');
+        javs_contents = javs_contents.replace(/package [\w\.]*;/, 'package ' + pkg + ';');
+        events.emit('verbose', 'Wrote out Android package name to "' + pkg + '"');
+        fs.writeFileSync(new_javs, javs_contents, 'utf-8');
+    },
+
+    // Returns the platform-specific www directory.
+    www_dir:function() {
+        return path.join(this.path, 'assets', 'www');
+    },
+
+    config_xml:function(){
+        return this.android_config;
+    },
+
+     // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, 'framework', 'assets', 'www', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.path);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.path, 'platform_www');
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+    },
+
+    // update the overrides folder into the www folder
+    update_overrides:function() {
+        var projectRoot = util.isCordova(this.path);
+        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'amazon-fireos');
+        if (fs.existsSync(merges_path)) {
+            var overrides = path.join(merges_path, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+
+    // Returns a promise.
+    update_project:function(cfg) {
+        var platformWww = path.join(this.path, 'assets');
+        try {
+            this.update_from_config(cfg);
+        } catch(e) {
+            return Q.reject(e);
+        }
+        this.update_overrides();
+        // delete any .svn folders copied over
+        util.deleteSvnFolders(platformWww);
+        return Q();
+    }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/android_parser.js b/cordova-lib/src/cordova/metadata/android_parser.js
new file mode 100644
index 0000000..ef50caf
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/android_parser.js
@@ -0,0 +1,303 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs            = require('fs'),
+    path          = require('path'),
+    xml           = require('../xml-helpers'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    project_config= require('../config'),
+    Q             = require('q'),
+    ConfigParser  = require('../ConfigParser'),
+    CordovaError  = require('../CordovaError');
+
+var default_prefs = {
+    "useBrowserHistory":"true",
+    "exit-on-suspend":"false"
+};
+
+module.exports = function android_parser(project) {
+    if (!fs.existsSync(path.join(project, 'AndroidManifest.xml'))) {
+        throw new CordovaError('The provided path "' + project + '" is not an Android project.');
+    }
+    this.path = project;
+    this.strings = path.join(this.path, 'res', 'values', 'strings.xml');
+    this.manifest = path.join(this.path, 'AndroidManifest.xml');
+    this.android_config = path.join(this.path, 'res', 'xml', 'config.xml');
+};
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root) {
+    // Rely on platform's bin/create script to check requirements.
+    return Q(true);
+};
+
+module.exports.prototype = {
+    findOrientationPreference: function(config) {
+        var ret = config.getPreference('orientation');
+        if (ret && ret != 'default' && ret != 'portrait' && ret != 'landscape') {
+            events.emit('warn', 'Unknown value for orientation preference: ' + ret);
+            ret = null;
+        }
+
+        return ret;
+    },
+
+    findAndroidLaunchModePreference: function(config) {
+        var ret = config.getPreference('AndroidLaunchMode');
+        var valid = ['standard', 'singleTop', 'singleTask', 'singleInstance'].indexOf(ret) !== -1;
+        if (ret && !valid) {
+            events.emit('warn', 'Unknown value for launchMode preference: ' + ret);
+            ret = null;
+        }
+
+        return ret;
+    },
+
+    update_from_config:function(config) {
+        if (config instanceof ConfigParser) {
+        } else throw new Error('update_from_config requires a ConfigParser object');
+
+        // Update app name by editing res/values/strings.xml
+        var name = config.name();
+        var strings = xml.parseElementtreeSync(this.strings);
+        strings.find('string[@name="app_name"]').text = name;
+        fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
+        events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
+
+        var icons = config.getIcons('android');
+        // if there are icon elements in config.xml
+        if (icons) {
+          var haveSeenDefaultIcon = false;
+          var iconCount = 0;
+          var android_icons = {};
+          var projectRoot = util.isCordova(this.path);
+          var default_icon;
+          var max_size;
+          var max_density;
+          // http://developer.android.com/design/style/iconography.html
+          var densities = {
+            "ldpi" : 36,
+            "mdpi" : 48,
+            "hdpi" : 72,
+            "xhdpi" : 96
+          };
+          for (var i=0; i<icons.length; i++) {
+            var icon = icons[i];
+            var destfilepath;
+            var size = icon.width;
+            if (!size) {
+              size = icon.height;
+            }
+            if (!size && !icon.density) {
+              if (default_icon) {
+                  events.emit('verbose', "more than one default icon: " + JSON.stringify(icon));
+              } else {
+                  default_icon = icon;
+              }
+            } else {
+              var parseIcon = function(icon, icon_size, size, density) {
+                // if density is explicitly defined, no need to calculate it from width/height
+                if (icon.density) {
+                    android_icons[icon.density] = icon;
+                    return;
+                }
+
+                var i = parseInt(icon_size);
+                if (size == parseInt(icon_size)) {
+                  var previous = android_icons[density];
+                  if (previous) {
+                    // already have that density. platform rules
+                    if (!previous.platform) {
+                      android_icons[density] = icon;
+                    } // else already have a platform icon of that density
+                  } else {
+                    android_icons[density] = icon;
+                  }
+                  android_icons[density] = icon;
+                  if (!max_size) {
+                    max_size = size;
+                    max_density = density;
+                  } else {
+                    if (max_size < size) {
+                      max_size = size
+                      max_density = density;
+                    }
+                  }
+                }
+              };
+              for (var density in densities) {
+                parseIcon(icon, size, densities[density], density);
+              }
+            }
+          }
+
+          var copyIcon = function(density) {
+            var srcfilepath;
+            var destfilepath = path.join(this.path, 'res', 'drawable-'+density, 'icon.png');
+            if (android_icons[density]) {
+              srcfilepath = path.join(projectRoot, android_icons[density].src);
+            } else {
+              if (default_icon) {
+                srcfilepath = path.join(projectRoot, default_icon.src);
+              } else {
+                if (max_density) {
+                  srcfilepath = path.join(projectRoot, android_icons[max_density].src);
+                } else {
+                  events.emit('verbose', 'no icon found matching Android typical densities');
+                }
+              }
+            }
+            if (srcfilepath) {
+                events.emit('verbose', 'Copying icon from ' + srcfilepath + ' to ' + destfilepath);
+                shell.cp('-f', srcfilepath, destfilepath);
+            }
+          }.bind(this);
+          for (var density in densities) {
+            copyIcon(density);
+          }
+
+        }
+
+        var manifest = xml.parseElementtreeSync(this.manifest);
+        // Update the version by changing the AndroidManifest android:versionName
+        var version = config.version();
+        var versionCode = config.android_versionCode() || default_versionCode(version);
+        manifest.getroot().attrib["android:versionName"] = version;
+        manifest.getroot().attrib["android:versionCode"] = versionCode;
+
+        // Update package name by changing the AndroidManifest id and moving the entry class around to the proper package directory
+        var pkg = config.packageName();
+        pkg = pkg.replace(/-/g, '_'); // Java packages cannot support dashes
+        var orig_pkg = manifest.getroot().attrib.package;
+        manifest.getroot().attrib.package = pkg;
+
+        var act = manifest.getroot().find('./application/activity');
+
+        // Set the orientation in the AndroidManifest
+        var orientationPref = this.findOrientationPreference(config);
+        if (orientationPref) {
+            switch (orientationPref) {
+                case 'default':
+                    delete act.attrib["android:screenOrientation"];
+                    break;
+                case 'portrait':
+                    act.attrib["android:screenOrientation"] = 'portrait';
+                    break;
+                case 'landscape':
+                    act.attrib["android:screenOrientation"] = 'landscape';
+            }
+        }
+
+        // Set android:launchMode in AndroidManifest
+        var androidLaunchModePref = this.findAndroidLaunchModePreference(config);
+        if (androidLaunchModePref) {
+            act.attrib["android:launchMode"] = androidLaunchModePref;
+        } else { // User has (explicitly) set an invalid value for AndroidLaunchMode preference
+            delete act.attrib["android:launchMode"]; // use Android default value (standard)
+        }
+
+        // Write out AndroidManifest.xml
+        fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
+
+        var orig_pkgDir = path.join(this.path, 'src', path.join.apply(null, orig_pkg.split('.')));
+        var java_files = fs.readdirSync(orig_pkgDir).filter(function(f) {
+          return f.indexOf('.svn') == -1 && f.indexOf('.java') >= 0 && fs.readFileSync(path.join(orig_pkgDir, f), 'utf-8').match(/extends\s+CordovaActivity/);
+        });
+        if (java_files.length == 0) {
+          throw new Error('No Java files found which extend CordovaActivity.');
+        } else if(java_files.length > 1) {
+          events.emit('log', 'Multiple candidate Java files (.java files which extend CordovaActivity) found. Guessing at the first one, ' + java_files[0]);
+        }
+
+        var orig_java_class = java_files[0];
+        var pkgDir = path.join(this.path, 'src', path.join.apply(null, pkg.split('.')));
+        shell.mkdir('-p', pkgDir);
+        var orig_javs = path.join(orig_pkgDir, orig_java_class);
+        var new_javs = path.join(pkgDir, orig_java_class);
+        var javs_contents = fs.readFileSync(orig_javs, 'utf-8');
+        javs_contents = javs_contents.replace(/package [\w\.]*;/, 'package ' + pkg + ';');
+        events.emit('verbose', 'Wrote out Android package name to "' + pkg + '"');
+        fs.writeFileSync(new_javs, javs_contents, 'utf-8');
+    },
+
+    // Returns the platform-specific www directory.
+    www_dir:function() {
+        return path.join(this.path, 'assets', 'www');
+    },
+
+    config_xml:function(){
+        return this.android_config;
+    },
+
+    // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, 'framework', 'assets', 'www', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.path);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.path, 'platform_www');
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+    },
+
+    // update the overrides folder into the www folder
+    update_overrides:function() {
+        var projectRoot = util.isCordova(this.path);
+        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'android');
+        if (fs.existsSync(merges_path)) {
+            var overrides = path.join(merges_path, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    // Returns a promise.
+    update_project:function(cfg) {
+        var platformWww = path.join(this.path, 'assets');
+        try {
+            this.update_from_config(cfg);
+            this.update_overrides();
+        } catch(e) {
+            return Q.reject(e);
+        }
+        // delete any .svn folders copied over
+        util.deleteSvnFolders(platformWww);
+        return Q();
+    }
+};
+
+
+// Consturct the default value for versionCode as
+// PATCH + MINOR * 100 + MAJOR * 10000
+// see http://developer.android.com/tools/publishing/versioning.html
+function default_versionCode(version) {
+    nums = version.split('-')[0].split('.').map(Number);
+    var versionCode = nums[0] * 10000 + nums[1] * 100 + nums[2];
+    return versionCode;
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/blackberry10_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/blackberry10_parser.js b/cordova-lib/src/cordova/metadata/blackberry10_parser.js
new file mode 100644
index 0000000..ba6530f
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/blackberry10_parser.js
@@ -0,0 +1,145 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs            = require('fs'),
+    path          = require('path'),
+    shell         = require('shelljs'),
+    util          = require('../util'),
+    Q             = require('q'),
+    child_process = require('child_process'),
+    ConfigParser  = require('../ConfigParser'),
+    CordovaError  = require('../CordovaError'),
+    events        = require('../events'),
+    config        = require('../config');
+
+module.exports = function blackberry_parser(project) {
+    if (!fs.existsSync(path.join(project, 'www'))) {
+        throw new CordovaError('The provided path "' + project + '" is not a Cordova BlackBerry10 project.');
+    }
+    this.path = project;
+    this.config_path = path.join(this.path, 'www', 'config.xml');
+    this.xml = new ConfigParser(this.config_path);
+};
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root) {
+    var custom_path = config.has_custom_path(project_root, 'blackberry10');
+    var lib_path;
+    if (custom_path) {
+        lib_path = path.resolve(custom_path);
+    } else {
+        lib_path = path.join(util.libDirectory, 'blackberry10', 'cordova', require('../../platforms').blackberry10.version);
+    }
+    var d = Q.defer();
+    child_process.exec("\"" + path.join(lib_path, 'bin', 'check_reqs') + "\"", function(err, output, stderr) {
+        if (err) {
+            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
+        } else {
+            d.resolve();
+        }
+    });
+    return d.promise;
+};
+
+module.exports.prototype = {
+    update_from_config:function(config) {
+        var projectRoot = util.isCordova(this.path),
+            resDir = path.join(this.path, 'platform_www', 'res'),
+            icons,
+            i;
+
+        if (!config instanceof ConfigParser) {
+            throw new Error('update_from_config requires a ConfigParser object');
+        }
+
+        shell.rm('-rf', resDir);
+        shell.mkdir(resDir);
+
+        icons = config.getIcons('blackberry10');
+        if (icons) {
+            for (i = 0; i < icons.length; i++) {
+                var src = path.join(projectRoot, icons[i].src),
+                    dest = path.join(this.path, 'platform_www', icons[i].src),
+                    destFolder = path.join(dest, '..');
+
+                if (!fs.existsSync(destFolder)) {
+                    shell.mkdir(destFolder); // make sure target dir exists
+                }
+                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
+                shell.cp('-f', src, dest);
+            }
+        }
+    },
+
+    // Returns a promise.
+    update_project:function(cfg) {
+        var self = this;
+
+        try {
+            self.update_from_config(cfg);
+        } catch(e) {
+            return Q.reject(e);
+        }
+        self.update_overrides();
+        util.deleteSvnFolders(this.www_dir());
+        return Q();
+    },
+
+    // Returns the platform-specific www directory.
+    www_dir:function() {
+        return path.join(this.path, 'www');
+    },
+
+    config_xml:function(){
+        return this.config_path;
+    },
+
+    // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, 'javascript', 'cordova.blackberry10.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.path);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.path, 'platform_www');
+        var platform_cfg_backup = new ConfigParser(this.config_path);
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+        //Re-Write config.xml
+        platform_cfg_backup.write();
+    },
+
+    // update the overrides folder into the www folder
+    update_overrides:function() {
+        var projectRoot = util.isCordova(this.path);
+        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'blackberry10');
+        if (fs.existsSync(merges_path)) {
+            var overrides = path.join(merges_path, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/firefoxos_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/firefoxos_parser.js b/cordova-lib/src/cordova/metadata/firefoxos_parser.js
new file mode 100644
index 0000000..351a409
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/firefoxos_parser.js
@@ -0,0 +1,151 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs = require('fs'),
+    path = require('path'),
+    shell = require('shelljs'),
+    util = require('../util'),
+    events = require('../events'),
+    Q = require('q'),
+    ConfigParser = require('../ConfigParser');
+
+module.exports = function firefoxos_parser(project) {
+    this.path = project;
+};
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root) {
+    return Q(); // Requirements always met.
+};
+
+module.exports.prototype = {
+    // Returns a promise.
+    update_from_config: function() {
+        var config = new ConfigParser(this.config_xml());
+        var manifestPath = path.join(this.www_dir(), 'manifest.webapp');
+        var manifest;
+
+        if(fs.existsSync(manifestPath)) {
+            manifest = JSON.parse(fs.readFileSync(manifestPath));
+        }
+        else {
+            manifest = {
+                launch_path: "/index.html",
+                installs_allowed_from: ["*"]
+            };
+        }
+
+        manifest.version = config.version();
+        manifest.name = config.name();
+        manifest.pkgName = config.packageName();
+        manifest.description = config.description();
+        manifest.developer = {
+            name: config.author()
+        };
+
+        var authorNode = config.doc.find('author');
+        var authorUrl = authorNode.attrib['href'];
+
+        if (authorUrl) {
+            manifest.developer.url = authorUrl;
+        }
+
+        var permissionNodes = config.doc.findall('permission');
+        var privileged = false;
+
+        if (permissionNodes.length) {
+            manifest.permissions = manifest.permissions || {};
+
+            permissionNodes.forEach(function(node) {
+                var permissionName = node.attrib['name'];
+
+                // Don't change if it was already created
+                if (!manifest.permissions[permissionName]) {
+                    manifest.permissions[permissionName] = {
+                        description: node.attrib['description']
+                    };
+
+                    if (node.attrib['access']) {
+                        manifest.permissions[permissionName].access = node.attrib['access'];
+                    }
+
+                    if (node.attrib['privileged'] === "true") {
+                        privileged = true;
+                    }
+                }
+            });
+        }
+
+        if (privileged) {
+            manifest.type = 'privileged';
+        } else {
+            delete manifest.type;
+        }
+
+        fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 4));
+
+        return Q();
+    },
+
+    www_dir: function() {
+        return path.join(this.path, 'www');
+    },
+
+    // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, 'cordova-lib', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.path);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.path, 'platform_www');
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+    },
+
+    update_overrides: function() {
+        var projectRoot = util.isCordova(this.path);
+        var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'firefoxos');
+        if(fs.existsSync(mergesPath)) {
+            var overrides = path.join(mergesPath, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    config_xml:function(){
+        return path.join(this.path, 'config.xml');
+    },
+
+    // Returns a promise.
+    update_project: function(cfg) {
+        return this.update_from_config()
+            .then(function(){
+                this.update_overrides();
+                util.deleteSvnFolders(this.www_dir());
+            }.bind(this));
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/ios_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/ios_parser.js b/cordova-lib/src/cordova/metadata/ios_parser.js
new file mode 100644
index 0000000..f906ee3
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/ios_parser.js
@@ -0,0 +1,202 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var fs            = require('fs'),
+    path          = require('path'),
+    xcode         = require('xcode'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    plist         = require('plist-with-patches'),
+    Q             = require('q'),
+    ConfigParser  = require('../ConfigParser'),
+    CordovaError  = require('../CordovaError'),
+    config        = require('../config');
+
+module.exports = function ios_parser(project) {
+    try {
+        var xcodeproj_dir = fs.readdirSync(project).filter(function(e) { return e.match(/\.xcodeproj$/i); })[0];
+        if (!xcodeproj_dir) throw new CordovaError('The provided path "' + project + '" is not a Cordova iOS project.');
+        this.xcodeproj = path.join(project, xcodeproj_dir);
+        this.originalName = this.xcodeproj.substring(this.xcodeproj.lastIndexOf(path.sep)+1, this.xcodeproj.indexOf('.xcodeproj'));
+        this.cordovaproj = path.join(project, this.originalName);
+    } catch(e) {
+        throw new CordovaError('The provided path "'+project+'" is not a Cordova iOS project.');
+    }
+    this.path = project;
+    this.pbxproj = path.join(this.xcodeproj, 'project.pbxproj');
+    this.config_path = path.join(this.cordovaproj, 'config.xml');
+};
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root) {
+    // Rely on platform's bin/create script to check requirements.
+    return Q(true);
+};
+
+module.exports.prototype = {
+    // Returns a promise.
+    update_from_config:function(config) {
+        if (config instanceof ConfigParser) {
+        } else {
+            return Q.reject(new Error('update_from_config requires a ConfigParser object'));
+        }
+        var name = config.name();
+        var pkg = config.packageName();
+        var version = config.version();
+
+        // Update package id (bundle id)
+        var plistFile = path.join(this.cordovaproj, this.originalName + '-Info.plist');
+        var infoPlist = plist.parseFileSync(plistFile);
+        infoPlist['CFBundleIdentifier'] = pkg;
+
+        // Update version (bundle version)
+        infoPlist['CFBundleShortVersionString'] = version;
+        var CFBundleVersion = config.ios_CFBundleVersion() || default_CFBundleVersion(version);
+        infoPlist['CFBundleVersion'] = CFBundleVersion;
+
+        var info_contents = plist.build(infoPlist);
+        info_contents = info_contents.replace(/<string>[\s\r\n]*<\/string>/g,'<string></string>');
+        fs.writeFileSync(plistFile, info_contents, 'utf-8');
+        events.emit('verbose', 'Wrote out iOS Bundle Identifier to "' + pkg + '"');
+        events.emit('verbose', 'Wrote out iOS Bundle Version to "' + version + '"');
+
+        // Update icons
+        var icons = config.getIcons('ios');
+        var platformRoot = this.cordovaproj;
+        var appRoot = util.isCordova(platformRoot);
+
+        var platformIcons = [
+            {dest: "icon-60.png", width: 60, height: 60},
+            {dest: "icon-60@2x.png", width: 120, height: 120},
+            {dest: "icon-76.png", width: 76, height: 76},
+            {dest: "icon-76@2x.png", width: 152, height: 152},
+            {dest: "icon-small.png", width: 29, height: 29},
+            {dest: "icon-small@2x.png", width: 58, height: 58},
+            {dest: "icon-40.png", width: 40, height: 40},
+            {dest: "icon-40@2x.png", width: 80, height: 80},
+            {dest: "icon.png", width: 57, height: 57},
+            {dest: "icon@2x.png", width: 114, height: 114},
+            {dest: "icon-72.png", width: 72, height: 72},
+            {dest: "icon-72@2x.png", width: 144, height: 144},
+            {dest: "icon-50.png", width: 50, height: 50},
+            {dest: "icon-50@2x.png", width: 100, height: 100}
+        ];
+
+        platformIcons.forEach(function (item) {
+            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
+            if (icon){
+                var src = path.join(appRoot, icon.src),
+                    dest = path.join(platformRoot, 'Resources/icons/', item.dest);
+                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
+                shell.cp('-f', src, dest);
+            }
+        });
+
+        if (name != this.originalName) {
+            // Update product name inside pbxproj file
+            var proj = new xcode.project(this.pbxproj);
+            var parser = this;
+            var d = Q.defer();
+            proj.parse(function(err,hash) {
+                if (err) {
+                    d.reject(new Error('An error occured during parsing of project.pbxproj. Start weeping. Output: ' + err));
+                } else {
+                    proj.updateProductName(name);
+                    fs.writeFileSync(parser.pbxproj, proj.writeSync(), 'utf-8');
+                    // Move the xcodeproj and other name-based dirs over.
+                    shell.mv(path.join(parser.cordovaproj, parser.originalName + '-Info.plist'), path.join(parser.cordovaproj, name + '-Info.plist'));
+                    shell.mv(path.join(parser.cordovaproj, parser.originalName + '-Prefix.pch'), path.join(parser.cordovaproj, name + '-Prefix.pch'));
+                    shell.mv(parser.xcodeproj, path.join(parser.path, name + '.xcodeproj'));
+                    shell.mv(parser.cordovaproj, path.join(parser.path, name));
+                    // Update self object with new paths
+                    var old_name = parser.originalName;
+                    parser = new module.exports(parser.path);
+                    // Hack this shi*t
+                    var pbx_contents = fs.readFileSync(parser.pbxproj, 'utf-8');
+                    pbx_contents = pbx_contents.split(old_name).join(name);
+                    fs.writeFileSync(parser.pbxproj, pbx_contents, 'utf-8');
+                    events.emit('verbose', 'Wrote out iOS Product Name and updated XCode project file names from "'+old_name+'" to "' + name + '".');
+                    d.resolve();
+                }
+            });
+            return d.promise;
+        } else {
+            events.emit('verbose', 'iOS Product Name has not changed (still "' + this.originalName + '")');
+            return Q();
+        }
+    },
+
+    // Returns the platform-specific www directory.
+    www_dir:function() {
+        return path.join(this.path, 'www');
+    },
+
+    config_xml:function(){
+        return this.config_path;
+    },
+
+    // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, 'CordovaLib', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.path);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.path, 'platform_www');
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+    },
+
+    // update the overrides folder into the www folder
+    update_overrides:function() {
+        var projectRoot = util.isCordova(this.path);
+        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'ios');
+        if (fs.existsSync(merges_path)) {
+            var overrides = path.join(merges_path, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    // Returns a promise.
+    update_project:function(cfg) {
+        var self = this;
+        return this.update_from_config(cfg)
+        .then(function() {
+            self.update_overrides();
+            util.deleteSvnFolders(self.www_dir());
+        });
+    }
+};
+
+
+// Construct a default value for CFBundleVersion as the version with any
+// -rclabel stripped=.
+function default_CFBundleVersion(version) {
+    return version.split('-')[0];
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/ubuntu_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/ubuntu_parser.js b/cordova-lib/src/cordova/metadata/ubuntu_parser.js
new file mode 100644
index 0000000..947fb1e
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/ubuntu_parser.js
@@ -0,0 +1,162 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var fs            = require('fs'),
+    path          = require('path'),
+    et            = require('elementtree'),
+    xml           = require('../xml-helpers'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    project_config= require('../config'),
+    Q             = require('q'),
+    os            = require('os'),
+    ConfigParser  = require('../ConfigParser'),
+    CordovaError  = require('../CordovaError');
+
+module.exports = function(project) {
+    this.path = project;
+    this.config = new ConfigParser(this.config_xml());
+    this.update_manifest();
+};
+
+function sanitize(str) {
+    return str.replace(/\n/g, ' ').replace(/^\s+|\s+$/g, '');
+}
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root, callback) {
+    var d = Q.defer();
+
+    events.emit('log', 'Checking ubuntu requirements...');
+    command = "dpkg-query -Wf'${db:Status-abbrev}' cmake debhelper libx11-dev libicu-dev pkg-config qtbase5-dev qtchooser qtdeclarative5-dev qtfeedback5-dev qtlocation5-dev qtmultimedia5-dev qtpim5-dev qtsensors5-dev qtsystems5-dev 2>/dev/null | grep -q '^i'";
+    events.emit('log', 'Running "' + command + '" (output to follow)');
+    shell.exec(command, {silent:true, async:true}, function(code, output) {
+        events.emit('log', output);
+        if (code != 0) {
+            d.reject(new CordovaError('Make sure you have the following packages installed: ' + output));
+        } else {
+            d.resolve();
+        }
+    });
+
+    return d.promise;
+};
+
+module.exports.prototype = {
+    // Returns a promise.
+    update_from_config:function(config) {
+        if (config instanceof ConfigParser) {
+        } else {
+            return Q.reject(new Error('update_from_config requires a ConfigParser object'));
+        }
+
+        this.config = new ConfigParser(this.config_xml());
+        this.config.setName(config.name());
+        this.config.setVersion(config.version());
+        this.config.setPackageName(config.packageName());
+        this.config.setDescription(config.description());
+
+        this.config.write();
+
+        return this.update_manifest();
+    },
+
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, 'www', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    update_manifest: function() {
+        var nodearch2debarch = { 'arm': 'armhf',
+                                 'ia32': 'i386',
+                                 'x64': 'amd64'};
+        var arch;
+        if (os.arch() in nodearch2debarch)
+            arch = nodearch2debarch[os.arch()];
+        else
+            return Q.reject(new Error('unknown cpu arch'));
+
+        if (!this.config.author())
+            return Q.reject(new Error('config.xml should contain author'));
+
+        var manifest = { name: this.config.packageName(),
+                         version: this.config.version(),
+                         title: this.config.name(),
+                         hooks: { cordova: { desktop: "cordova.desktop",
+                                             apparmor: "apparmor.json" } },
+                         framework: "ubuntu-sdk-13.10",
+                         maintainer: sanitize(this.config.author()),
+                         architecture: arch,
+                         description: sanitize(this.config.description()) };
+        fs.writeFileSync(path.join(this.path, 'manifest.json'), JSON.stringify(manifest));
+
+        var name = this.config.name().replace(/\n/g, ' '); //FIXME: escaping
+        var content = "[Desktop Entry]\nName=" + name + "\nExec=./cordova-ubuntu www/\nIcon=qmlscene\nTerminal=false\nType=Application\nX-Ubuntu-Touch=true";
+
+        fs.writeFileSync(path.join(this.path, 'cordova.desktop'), content);
+
+        var policy = { policy_groups: ["networking", "audio"], policy_version: 1 };
+
+        this.config.doc.getroot().findall('./feature/param').forEach(function (element) {
+            if (element.attrib.policy_group && policy.policy_groups.indexOf(policy.policy_groups) === -1)
+                policy.policy_groups.push(element.attrib.policy_group);
+        });
+
+        fs.writeFileSync(path.join(this.path, 'apparmor.json'), JSON.stringify(policy));
+
+        return Q();
+    },
+
+    config_xml:function(){
+        return path.join(this.path, 'config.xml');
+    },
+
+    www_dir:function() {
+        return path.join(this.path, 'www');
+    },
+
+    update_www:function() {
+        var projectRoot = util.isCordova(this.path);
+        var www = util.projectWww(projectRoot);
+
+        shell.rm('-rf', this.www_dir());
+        shell.cp('-rf', www, this.path);
+    },
+
+    update_overrides:function() {
+        var projectRoot = util.isCordova(this.path);
+        var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'ubuntu');
+        if(fs.existsSync(mergesPath)) {
+            var overrides = path.join(mergesPath, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    // Returns a promise.
+    update_project:function(cfg) {
+        var self = this;
+
+        return this.update_from_config(cfg)
+        .then(function() {
+            self.update_overrides();
+            util.deleteSvnFolders(self.www_dir());
+        });
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/windows8_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/windows8_parser.js b/cordova-lib/src/cordova/metadata/windows8_parser.js
new file mode 100644
index 0000000..53c2d31
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/windows8_parser.js
@@ -0,0 +1,339 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs            = require('fs'),
+    path          = require('path'),
+    et            = require('elementtree'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    events        = require('../events'),
+    Q             = require('q'),
+    child_process = require('child_process'),
+    ConfigParser  = require('../ConfigParser'),
+    CordovaError  = require('../CordovaError'),
+    xml           = require('../xml-helpers'),
+    config        = require('../config'),
+    hooker        = require('../hooker');
+
+module.exports = function windows8_parser(project) {
+    try {
+        // TODO : Check that it's not a windows8 project?
+        var jsproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.jsproj$/i); })[0];
+        if (!jsproj_file) throw new CordovaError('No .jsproj file in "'+project+'"');
+        this.windows8_proj_dir = project;
+        this.jsproj_path  = path.join(this.windows8_proj_dir, jsproj_file);
+        this.sln_path     = path.join(this.windows8_proj_dir, jsproj_file.replace(/\.jsproj/, '.sln'));
+    } catch(e) {
+        throw new CordovaError('The provided path "' + project + '" is not a Windows 8 project. ' + e);
+    }
+    this.manifest_path  = path.join(this.windows8_proj_dir, 'package.appxmanifest');
+};
+
+// Returns a promise
+module.exports.check_requirements = function(project_root) {
+    events.emit('log', 'Checking windows8 requirements...');
+    var lib_path = path.join(util.libDirectory, 'windows8', 'cordova',
+                    require('../../platforms').windows8.version, 'windows8');
+
+    var custom_path = config.has_custom_path(project_root, 'windows8');
+    if (custom_path) {
+        lib_path = path.join(custom_path, "windows8");
+    }
+    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
+    events.emit('verbose', 'Running "' + command + '" (output to follow)');
+    var d = Q.defer();
+
+    child_process.exec(command, function(err, output, stderr) {
+        events.emit('verbose', output);
+        if (err) {
+            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
+        } else {
+            d.resolve();
+        }
+    });
+    return d.promise;
+};
+
+module.exports.prototype = {
+
+    update_from_config:function(config) {
+
+        //check config parser
+        if (config instanceof ConfigParser) {
+        } else throw new Error('update_from_config requires a ConfigParser object');
+
+        //Get manifest file
+        var manifest = xml.parseElementtreeSync(this.manifest_path);
+
+        var version = this.fixConfigVersion(config.version());
+        var name = config.name();
+        var pkgName = config.packageName();
+        var author = config.author();
+
+        var identityNode = manifest.find('.//Identity');
+        if(identityNode) {
+            // Update app name in identity
+            var appIdName = identityNode['attrib']['Name'];
+            if (appIdName != pkgName) {
+                identityNode['attrib']['Name'] = pkgName;
+            }
+
+            // Update app version
+            var appVersion = identityNode['attrib']['Version'];
+            if(appVersion != version) {
+                identityNode['attrib']['Version'] = version;
+            }
+        }
+
+        // Update name (windows8 has it in the Application[@Id] and Application.VisualElements[@DisplayName])
+        var app = manifest.find('.//Application');
+        if(app) {
+
+            var appId = app['attrib']['Id'];
+
+            if (appId != pkgName) {
+                app['attrib']['Id'] = pkgName;
+            }
+
+            var visualElems = manifest.find('.//VisualElements') || manifest.find('.//m2:VisualElements');
+
+            if(visualElems) {
+                var displayName = visualElems['attrib']['DisplayName'];
+                if(displayName != name) {
+                    visualElems['attrib']['DisplayName'] = name;
+                }
+            }
+            else {
+                throw new Error('update_from_config expected a valid package.appxmanifest' +
+                                ' with a <VisualElements> node');
+            }
+        }
+        else {
+            throw new Error('update_from_config expected a valid package.appxmanifest' +
+                            ' with a <Application> node');
+        }
+
+        // Update properties
+        var properties = manifest.find('.//Properties');
+        if (properties && properties.find) {
+            var displayNameElement = properties.find('.//DisplayName');
+            if (displayNameElement && displayNameElement.text != name) {
+                displayNameElement.text = name;
+            }
+
+            var publisherNameElement = properties.find('.//PublisherDisplayName');
+            if (publisherNameElement && publisherNameElement.text != author) {
+                publisherNameElement.text = author;
+            }
+        }
+
+        // sort Capability elements as per CB-5350 Windows8 build fails due to invalid 'Capabilities' definition
+        // to sort elements we remove them and then add again in the appropriate order
+        var capabilitiesRoot = manifest.find('.//Capabilities'),
+            capabilities = capabilitiesRoot._children || [];
+
+        capabilities.forEach(function(elem){
+            capabilitiesRoot.remove(0, elem);
+        });
+        capabilities.sort(function(a, b) {
+            return (a.tag > b.tag)? 1: -1;
+        });
+        capabilities.forEach(function(elem){
+            capabilitiesRoot.append(elem);
+        });
+
+        //Write out manifest
+        fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
+
+        // Update icons
+        var icons = config.getIcons('windows8');
+        var platformRoot = this.windows8_proj_dir;
+        var appRoot = util.isCordova(platformRoot);
+
+        // Icons, that should be added to platform
+        var platformIcons = [
+            {dest: "images/logo.png", width: 150, height: 150},
+            {dest: "images/smalllogo.png", width: 30, height: 30},
+            {dest: "images/storelogo.png", width: 50, height: 50},
+        ];
+
+        platformIcons.forEach(function (item) {
+            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
+            if (icon){
+                var src = path.join(appRoot, icon.src),
+                    dest = path.join(platformRoot, item.dest);
+                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
+                shell.cp('-f', src, dest);
+            }
+        });
+
+    },
+    // Returns the platform-specific www directory.
+    www_dir:function() {
+        return path.join(this.windows8_proj_dir, 'www');
+    },
+    config_xml:function() {
+        return path.join(this.windows8_proj_dir,"config.xml");
+    },
+    // copy files from merges directory to actual www dir
+    copy_merges:function(merges_sub_path) {
+        var merges_path = path.join(util.appDir(util.isCordova(this.windows8_proj_dir)), 'merges', merges_sub_path);
+        if (fs.existsSync(merges_path)) {
+            var overrides = path.join(merges_path, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, "template", 'www', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.windows8_proj_dir);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.windows8_proj_dir, 'platform_www');
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+
+        // Copy all files from merges directory.
+        this.copy_merges('windows8');
+
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+    },
+
+    // updates the jsproj file to explicitly list all www content.
+    update_jsproj:function() {
+        var jsproj_xml = xml.parseElementtreeSync(this.jsproj_path);
+        // remove any previous references to the www files
+        var item_groups = jsproj_xml.findall('ItemGroup');
+        for (var i = 0, l = item_groups.length; i < l; i++) {
+            var group = item_groups[i];
+            var files = group.findall('Content');
+            for (var j = 0, k = files.length; j < k; j++) {
+                var file = files[j];
+                if (file.attrib.Include.substr(0, 3) == 'www') {
+                    // remove file reference
+                    group.remove(0, file);
+                    // remove ItemGroup if empty
+                    var new_group = group.findall('Content');
+                    if(new_group.length < 1) {
+                        jsproj_xml.getroot().remove(0, group);
+                    }
+                }
+            }
+        }
+
+        // now add all www references back in from the root www folder
+        var project_root = util.isCordova(this.windows8_proj_dir);
+        var www_files = this.folder_contents('www', this.www_dir());
+        for(file in www_files) {
+            var item = new et.Element('ItemGroup');
+            var content = new et.Element('Content');
+            content.attrib.Include = www_files[file];
+            item.append(content);
+            jsproj_xml.getroot().append(item);
+        }
+        // save file
+        fs.writeFileSync(this.jsproj_path, jsproj_xml.write({indent:4}), 'utf-8');
+    },
+    // Returns an array of all the files in the given directory with relative paths
+    // - name     : the name of the top level directory (i.e all files will start with this in their path)
+    // - dir     : the directory whos contents will be listed under 'name' directory
+    folder_contents:function(name, dir) {
+        var results = [];
+        var folder_dir = fs.readdirSync(dir);
+        for(item in folder_dir) {
+            var stat = fs.statSync(path.join(dir, folder_dir[item]));
+
+            if(stat.isDirectory()) {
+                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
+                //Add all subfolder item paths
+                for(sub_item in sub_dir) {
+                    results.push(sub_dir[sub_item]);
+                }
+            }
+            else if(stat.isFile()) {
+                results.push(path.join(name, folder_dir[item]));
+            }
+            // else { it is a FIFO, or a Socket, Symbolic Link or something ... }
+        }
+        return results;
+    },
+
+    // calls the nessesary functions to update the windows8 project
+    update_project:function(cfg) {
+        //console.log("Updating windows8 project...");
+
+        try {
+            this.update_from_config(cfg);
+        } catch(e) {
+            return Q.reject(e);
+        }
+
+        var that = this;
+        var projectRoot = util.isCordova(process.cwd());
+
+        var hooks = new hooker(projectRoot);
+        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['windows8'] })
+        .then(function() {
+            // overrides (merges) are handled in update_www()
+            that.update_jsproj();
+            that.add_bom();
+            util.deleteSvnFolders(that.www_dir());
+        });
+    },
+
+    // Adjust version number as per CB-5337 Windows8 build fails due to invalid app version
+    fixConfigVersion: function (version) {
+        if(version && version.match(/\.\d/g)) {
+            var numVersionComponents = version.match(/\.\d/g).length + 1;
+            while (numVersionComponents++ < 4) {
+                version += '.0';
+            }
+        }
+        return version;
+    },
+
+    // CB-5421 Add BOM to all html, js, css files to ensure app can pass Windows Store Certification
+    add_bom: function () {
+        var www = this.www_dir();
+        var files = shell.ls('-R', www);
+
+        files.forEach(function (file) {
+            if (!file.match(/\.(js|html|css|json)/)) {
+                return;
+            }
+
+            var filePath = path.join(www, file);
+            var content = fs.readFileSync(filePath);
+
+            if (content[0] !== 0xEF && content[1] !== 0xBE && content[2] !== 0xBB) {
+                fs.writeFileSync(filePath, '\ufeff' + content);
+            }
+        });
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/wp7_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/wp7_parser.js b/cordova-lib/src/cordova/metadata/wp7_parser.js
new file mode 100644
index 0000000..91db24c
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/wp7_parser.js
@@ -0,0 +1,262 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs            = require('fs'),
+    path          = require('path'),
+    et            = require('elementtree'),
+    xml           = require('../xml-helpers'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    child_process = require('child_process'),
+    Q             = require('q'),
+    ConfigParser  = require('../ConfigParser'),
+    CordovaError  = require('../CordovaError'),
+    config        = require('../config'),
+    hooker        = require('../hooker');
+
+module.exports = function wp7_parser(project) {
+    try {
+        // TODO : Check that it's not a wp7 project?
+        var csproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
+        if (!csproj_file) throw new CordovaError('No .csproj file in "'+project+'"');
+        this.wp7_proj_dir = project;
+        this.csproj_path  = path.join(this.wp7_proj_dir, csproj_file);
+        this.sln_path     = path.join(this.wp7_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
+    } catch(e) {
+        throw new CordovaError('The provided path "' + project + '" is not a Windows Phone 7 project. ' + e);
+    }
+    this.manifest_path  = path.join(this.wp7_proj_dir, 'Properties', 'WMAppManifest.xml');
+};
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root) {
+    events.emit('log', 'Checking wp7 requirements...');
+    var lib_path = path.join(util.libDirectory, 'wp', 'cordova', require('../../platforms').wp7.version, 'wp7');
+    var custom_path = config.has_custom_path(project_root, 'wp7');
+    if (custom_path) {
+        lib_path = path.join(custom_path, 'wp7');
+    }
+    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
+    events.emit('verbose', 'Running "' + command + '" (output to follow)');
+    var d = Q.defer();
+    child_process.exec(command, function(err, output, stderr) {
+        events.emit('verbose', output+stderr);
+        if (err) {
+            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
+        } else {
+            d.resolve();
+        }
+    });
+    return d.promise;
+};
+
+module.exports.prototype = {
+    update_from_config:function(config) {
+        //check config parser
+        if (config instanceof ConfigParser) {
+        } else throw new Error('update_from_config requires a ConfigParser object');
+
+        //Get manifest file
+        var manifest = xml.parseElementtreeSync(this.manifest_path);
+
+        //Update app version
+        var version = config.version();
+        manifest.find('.//App').attrib.Version = version;
+
+        // Update app name by editing app title in Properties\WMAppManifest.xml
+        var name = config.name();
+        var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
+        if(prev_name != name) {
+            events.emit('verbose', "Updating app name from " + prev_name + " to " + name);
+            manifest.find('.//App').attrib.Title = name;
+            manifest.find('.//App').attrib.Publisher = name + " Publisher";
+            manifest.find('.//App').attrib.Author = name + " Author";
+            manifest.find('.//PrimaryToken').attrib.TokenID = name;
+            //update name of sln and csproj.
+            name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
+            prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
+            var sln_name = fs.readdirSync(this.wp7_proj_dir).filter(function(e) { return e.match(/\.sln$/i); })[0];
+            var sln_path = path.join(this.wp7_proj_dir, sln_name);
+            var sln_file = fs.readFileSync(sln_path, 'utf-8');
+            var name_regex = new RegExp(prev_name, "g");
+            fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
+            shell.mv('-f', this.csproj_path, path.join(this.wp7_proj_dir, name + '.csproj'));
+            this.csproj_path = path.join(this.wp7_proj_dir, name + '.csproj');
+            shell.mv('-f', sln_path, path.join(this.wp7_proj_dir, name + '.sln'));
+            this.sln_path    = path.join(this.wp7_proj_dir, name + '.sln');
+        }
+
+        // Update package name by changing:
+        /*  - CordovaAppProj.csproj
+         *  - MainPage.xaml
+         *  - MainPage.xaml.cs
+         *  - App.xaml
+         *  - App.xaml.cs
+         */
+         var pkg = config.packageName();
+         var csproj = xml.parseElementtreeSync(this.csproj_path);
+         prev_name = csproj.find('.//RootNamespace').text;
+         if(prev_name != pkg) {
+            events.emit('verbose', "Updating package name from " + prev_name + " to " + pkg);
+            //CordovaAppProj.csproj
+            csproj.find('.//RootNamespace').text = pkg;
+            csproj.find('.//AssemblyName').text = pkg;
+            csproj.find('.//XapFilename').text = pkg + '.xap';
+            csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
+            fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
+            //MainPage.xaml
+            var mainPageXAML = xml.parseElementtreeSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'));
+            mainPageXAML.getroot().attrib['x:Class'] = pkg + '.MainPage';
+            fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
+            //MainPage.xaml.cs
+            var mainPageCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
+            var namespaceRegEx = new RegExp('namespace ' + prev_name);
+            fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+            //App.xaml
+            var appXAML = xml.parseElementtreeSync(path.join(this.wp7_proj_dir, 'App.xaml'));
+            appXAML.getroot().attrib['x:Class'] = pkg + '.App';
+            fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
+            //App.xaml.cs
+            var appCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), 'utf-8');
+            fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+         }
+
+         //Write out manifest
+         fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
+    },
+    // Returns the platform-specific www directory.
+    www_dir:function() {
+        return path.join(this.wp7_proj_dir, 'www');
+    },
+    config_xml:function() {
+        return path.join(this.wp7_proj_dir, 'config.xml');
+    },
+    // copy files from merges directory to actual www dir
+    copy_merges:function(merges_sub_path) {
+        var merges_path = path.join(util.appDir(util.isCordova(this.wp7_proj_dir)), 'merges', merges_sub_path);
+        if (fs.existsSync(merges_path)) {
+            var overrides = path.join(merges_path, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, '..', 'common', 'www', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.wp7_proj_dir);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.wp7_proj_dir, 'platform_www');
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+
+        // Copy all files from merges directories - wp generic first, then wp7 specific.
+        this.copy_merges('wp');
+        this.copy_merges('wp7');
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+    },
+
+    // updates the csproj file to explicitly list all www content.
+    update_csproj:function() {
+        var csproj_xml = xml.parseElementtreeSync(this.csproj_path);
+        // remove any previous references to the www files
+        var item_groups = csproj_xml.findall('ItemGroup');
+        for (var i = 0, l = item_groups.length; i < l; i++) {
+            var group = item_groups[i];
+            var files = group.findall('Content');
+            for (var j = 0, k = files.length; j < k; j++) {
+                var file = files[j];
+                if (file.attrib.Include.substr(0, 3) == 'www') {
+                    // remove file reference
+                    group.remove(0, file);
+                    // remove ItemGroup if empty
+                    var new_group = group.findall('Content');
+                    if(new_group.length < 1) {
+                        csproj_xml.getroot().remove(0, group);
+                    }
+                }
+            }
+        }
+
+        // now add all www references back in from the wp www folder
+        var www_files = this.folder_contents('www', this.www_dir());
+        for(file in www_files) {
+            var item = new et.Element('ItemGroup');
+            var content = new et.Element('Content');
+            content.attrib.Include = www_files[file];
+            item.append(content);
+            csproj_xml.getroot().append(item);
+        }
+        // save file
+        fs.writeFileSync(this.csproj_path, csproj_xml.write({indent:4}), 'utf-8');
+    },
+    // Returns an array of all the files in the given directory with relative paths
+    // - name     : the name of the top level directory (i.e all files will start with this in their path)
+    // - dir      : the directory whos contents will be listed under 'name' directory
+    folder_contents:function(name, dir) {
+        var results = [];
+        var folder_dir = fs.readdirSync(dir);
+        for(item in folder_dir) {
+            var stat = fs.statSync(path.join(dir, folder_dir[item]));
+
+            if(stat.isDirectory()) {
+                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
+                //Add all subfolder item paths
+                for(sub_item in sub_dir) {
+                    results.push(sub_dir[sub_item]);
+                }
+            }
+            else if(stat.isFile()) {
+                results.push(path.join(name, folder_dir[item]));
+            }
+            // else { it is a FIFO, or a Socket or something ... }
+        }
+        return results;
+    },
+
+    // calls the nessesary functions to update the wp7 project
+    // Returns a promise.
+    update_project:function(cfg) {
+        try {
+            this.update_from_config(cfg);
+        } catch(e) {
+            return Q.reject(e);
+        }
+        // trigger an event in case anyone needs to modify the contents of the www folder before we package it.
+        var that = this;
+        var projectRoot = util.isCordova(process.cwd());
+        var hooks = new hooker(projectRoot);
+
+        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['wp7']  })
+        .then(function() {
+            that.update_csproj();
+            // TODO: Add overrides support? Why is this missing?
+            util.deleteSvnFolders(that.www_dir());
+        });
+    }
+};


[22/24] git commit: Remove all cordova-lib files

Posted by ka...@apache.org.
Remove all cordova-lib files


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

Branch: refs/heads/cordova-lib
Commit: 5e3515ab338a70d1fba15764441dd730165ff0c1
Parents: b51e1c1
Author: Mark Koudritsky <ka...@gmail.com>
Authored: Wed Apr 30 18:12:00 2014 -0400
Committer: Mark Koudritsky <ka...@gmail.com>
Committed: Wed Apr 30 18:12:00 2014 -0400

----------------------------------------------------------------------
 cordova-lib/spec-cordova/ConfigParser.spec.js   |   84 -
 cordova-lib/spec-cordova/build.spec.js          |  129 --
 cordova-lib/spec-cordova/compile.spec.js        |  113 --
 cordova-lib/spec-cordova/create.spec.js         |  138 --
 cordova-lib/spec-cordova/emulate.spec.js        |  115 --
 .../fixtures/base/.cordova/config.json          |   22 -
 .../spec-cordova/fixtures/base/merges/.svn      |    0
 .../spec-cordova/fixtures/base/plugins/.svn     |    0
 .../spec-cordova/fixtures/base/www/config.xml   |   14 -
 .../fixtures/base/www/css/index.css             |  115 --
 .../spec-cordova/fixtures/base/www/img/logo.png |  Bin 21814 -> 0 bytes
 .../spec-cordova/fixtures/base/www/index.html   |   43 -
 .../spec-cordova/fixtures/base/www/js/index.js  |   49 -
 .../spec-cordova/fixtures/base/www/spec.html    |   68 -
 .../fixtures/hooks_bat/fail/fail.bat            |    2 -
 .../fixtures/hooks_bat/test/.dotted.bat         |    2 -
 .../spec-cordova/fixtures/hooks_bat/test/07.bat |    3 -
 .../spec-cordova/fixtures/hooks_bat/test/1.bat  |    5 -
 .../spec-cordova/fixtures/hooks_sh/fail/fail.sh |    1 -
 .../fixtures/hooks_sh/test/.dotted.sh           |    1 -
 .../spec-cordova/fixtures/hooks_sh/test/07.sh   |    2 -
 .../spec-cordova/fixtures/hooks_sh/test/1.sh    |    4 -
 .../fixtures/platforms/android-lib/VERSION      |    1 -
 .../android-lib/framework/assets/www/cordova.js |    1 -
 .../platforms/android/AndroidManifest.xml       |   14 -
 .../platforms/android/assets/www/config.xml     |   14 -
 .../platforms/android/assets/www/cordova.js     | 1712 ------------------
 .../android/assets/www/cordova_plugins.js       |    3 -
 .../platforms/android/assets/www/css/index.css  |  115 --
 .../platforms/android/assets/www/img/logo.png   |  Bin 21814 -> 0 bytes
 .../platforms/android/assets/www/index.html     |   43 -
 .../platforms/android/assets/www/js/index.js    |   49 -
 .../platforms/android/assets/www/spec.html      |   68 -
 .../fixtures/platforms/android/build.xml        |   92 -
 .../fixtures/platforms/android/cordova/build    |   35 -
 .../platforms/android/cordova/check_reqs        |   27 -
 .../fixtures/platforms/android/cordova/clean    |   34 -
 .../platforms/android/cordova/defaults.xml      |   50 -
 .../platforms/android/cordova/lib/appinfo.js    |   41 -
 .../platforms/android/cordova/lib/build.js      |   89 -
 .../platforms/android/cordova/lib/check_reqs.js |   78 -
 .../platforms/android/cordova/lib/clean.js      |   43 -
 .../platforms/android/cordova/lib/device.js     |   95 -
 .../platforms/android/cordova/lib/emulator.js   |  337 ----
 .../android/cordova/lib/install-device          |   38 -
 .../android/cordova/lib/install-emulator        |   38 -
 .../platforms/android/cordova/lib/list-devices  |   28 -
 .../android/cordova/lib/list-emulator-images    |   29 -
 .../android/cordova/lib/list-started-emulators  |   29 -
 .../platforms/android/cordova/lib/log.js        |   43 -
 .../platforms/android/cordova/lib/run.js        |  124 --
 .../android/cordova/lib/start-emulator          |   38 -
 .../fixtures/platforms/android/cordova/log      |   33 -
 .../fixtures/platforms/android/cordova/run      |   35 -
 .../fixtures/platforms/android/cordova/version  |   25 -
 .../fixtures/platforms/android/local.properties |   10 -
 .../platforms/android/proguard-project.txt      |   20 -
 .../platforms/android/project.properties        |   14 -
 .../android/res/drawable-hdpi/icon.png          |  Bin 6080 -> 0 bytes
 .../android/res/drawable-ldpi/icon.png          |  Bin 3096 -> 0 bytes
 .../android/res/drawable-mdpi/icon.png          |  Bin 4090 -> 0 bytes
 .../android/res/drawable-xhdpi/icon.png         |  Bin 7685 -> 0 bytes
 .../platforms/android/res/drawable/icon.png     |  Bin 7685 -> 0 bytes
 .../platforms/android/res/values/strings.xml    |    4 -
 .../platforms/android/res/xml/config.xml        |   18 -
 .../android/src/org/testing/TestBase.java       |   37 -
 .../fixtures/plugins/ChildBrowser/plugin.xml    |  142 --
 .../ChildBrowser/src/android/ChildBrowser.java  |   19 -
 .../plugins/ChildBrowser/www/childbrowser.js    |   19 -
 .../ChildBrowser/www/childbrowser/image.jpg     |    1 -
 .../ChildBrowser/www/childbrowser_file.html     |    1 -
 .../fixtures/plugins/android/plugin.xml         |   14 -
 .../plugins/android/src/android/Android.java    |    0
 .../android/src/android/SomethingWithR.java     |    6 -
 .../fixtures/plugins/android/www/android.js     |    0
 .../fixtures/plugins/fake1/plugin.xml           |   10 -
 .../fixtures/plugins/test/plugin.xml            |   14 -
 .../fixtures/plugins/test/www/test.js           |    0
 .../projects/android/AndroidManifest.xml        |   69 -
 .../projects/android/assets/www/.gitkeep        |    0
 .../projects/android/res/xml/config.xml         |   54 -
 .../fixtures/projects/android/src/.gitkeep      |    0
 .../fixtures/projects/windows/bom_test.xml      |   24 -
 .../fixtures/templates/no_content_config.xml    |   19 -
 cordova-lib/spec-cordova/helper.js              |   19 -
 cordova-lib/spec-cordova/helpers.js             |   46 -
 cordova-lib/spec-cordova/hooker.spec.js         |  261 ---
 cordova-lib/spec-cordova/lazy_load.spec.js      |  200 --
 .../metadata/android_parser.spec.js             |  211 ---
 .../metadata/blackberry_parser.spec.js          |  225 ---
 .../metadata/firefoxos_parser.spec.js           |   74 -
 .../spec-cordova/metadata/ios_parser.spec.js    |  199 --
 .../metadata/windows8_parser.spec.js            |  189 --
 .../spec-cordova/metadata/wp7_parser.spec.js    |  208 ---
 .../spec-cordova/metadata/wp8_parser.spec.js    |  208 ---
 cordova-lib/spec-cordova/platform.spec.js       |  108 --
 cordova-lib/spec-cordova/plugin.spec.js         |   68 -
 cordova-lib/spec-cordova/plugin_parser.spec.js  |   48 -
 cordova-lib/spec-cordova/prepare.spec.js        |  290 ---
 cordova-lib/spec-cordova/run.spec.js            |  114 --
 cordova-lib/spec-cordova/serve.spec.js          |  132 --
 cordova-lib/spec-cordova/test-config.xml        |   26 -
 cordova-lib/spec-cordova/util.spec.js           |  186 --
 cordova-lib/spec-cordova/wrappers.spec.js       |   40 -
 cordova-lib/spec-cordova/xml-helpers.spec.js    |  137 --
 cordova-lib/src/cordova/ConfigParser.js         |  163 --
 cordova-lib/src/cordova/CordovaError.js         |   31 -
 cordova-lib/src/cordova/build.js                |   47 -
 cordova-lib/src/cordova/compile.js              |   45 -
 cordova-lib/src/cordova/config.js               |   82 -
 cordova-lib/src/cordova/cordova.js              |   68 -
 cordova-lib/src/cordova/create.js               |  220 ---
 cordova-lib/src/cordova/emulate.js              |   50 -
 cordova-lib/src/cordova/events.js               |   23 -
 cordova-lib/src/cordova/hooker.js               |  161 --
 cordova-lib/src/cordova/info.js                 |  111 --
 cordova-lib/src/cordova/lazy_load.js            |  151 --
 .../cordova/metadata/amazon_fireos_parser.js    |  183 --
 .../src/cordova/metadata/android_parser.js      |  303 ----
 .../src/cordova/metadata/blackberry10_parser.js |  145 --
 .../src/cordova/metadata/firefoxos_parser.js    |  151 --
 cordova-lib/src/cordova/metadata/ios_parser.js  |  202 ---
 .../src/cordova/metadata/ubuntu_parser.js       |  162 --
 .../src/cordova/metadata/windows8_parser.js     |  339 ----
 cordova-lib/src/cordova/metadata/wp7_parser.js  |  262 ---
 cordova-lib/src/cordova/metadata/wp8_parser.js  |  287 ---
 cordova-lib/src/cordova/platform.js             |  399 ----
 cordova-lib/src/cordova/platforms.js            |   88 -
 cordova-lib/src/cordova/plugin.js               |  210 ---
 cordova-lib/src/cordova/plugin_parser.js        |   30 -
 cordova-lib/src/cordova/prepare.js              |  187 --
 cordova-lib/src/cordova/run.js                  |   48 -
 cordova-lib/src/cordova/serve.js                |  224 ---
 cordova-lib/src/cordova/superspawn.js           |  139 --
 cordova-lib/src/cordova/util.js                 |  214 ---
 cordova-lib/src/cordova/xml-helpers.js          |  171 --
 cordova-lib/templates/config.xml                |   19 -
 cordova-lib/templates/hooks-README.md           |   83 -
 138 files changed, 12793 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/ConfigParser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/ConfigParser.spec.js b/cordova-lib/spec-cordova/ConfigParser.spec.js
deleted file mode 100644
index 1faec88..0000000
--- a/cordova-lib/spec-cordova/ConfigParser.spec.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var path = require('path'),
-    fs = require('fs'),
-    ConfigParser = require('../src/ConfigParser'),
-    xml = path.join(__dirname, 'test-config.xml'),
-    xml_contents = fs.readFileSync(xml, 'utf-8');
-
-describe('config.xml parser', function () {
-    var readFile;
-    beforeEach(function() {
-        readFile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
-    });
-
-    it('should create an instance based on an xml file', function() {
-        var cfg;
-        expect(function () {
-            cfg = new ConfigParser(xml);
-        }).not.toThrow();
-        expect(cfg).toBeDefined();
-        expect(cfg.doc).toBeDefined();
-    });
-
-    describe('methods', function() {
-        var cfg;
-        beforeEach(function() {
-            cfg = new ConfigParser(xml);
-        });
-
-        describe('package name / id', function() {
-            it('should get the (default) packagename', function() {
-                expect(cfg.packageName()).toEqual('io.cordova.hellocordova');
-            });
-            it('should allow setting the packagename', function() {
-                cfg.setPackageName('this.is.bat.country');
-                expect(cfg.packageName()).toEqual('this.is.bat.country');
-            });
-        });
-
-        describe('version', function() {
-            it('should get the version', function() {
-                expect(cfg.version()).toEqual('0.0.1');
-            });
-            it('should allow setting the version', function() {
-                cfg.setVersion('2.0.1');
-                expect(cfg.version()).toEqual('2.0.1');
-            });
-        });
-
-        describe('app name', function() {
-            it('should get the (default) app name', function() {
-                expect(cfg.name()).toEqual('Hello Cordova');
-            });
-            it('should allow setting the app name', function() {
-                cfg.setName('this.is.bat.country');
-                expect(cfg.name()).toEqual('this.is.bat.country');
-            });
-        });
-        describe('preference', function() {
-            it('should get value of existing preference', function() {
-                expect(cfg.getPreference('fullscreen')).toEqual('true');
-            });
-            it('should get undefined as non existing preference', function() {
-                expect(cfg.getPreference('zimzooo!')).toEqual(undefined);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/build.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/build.spec.js b/cordova-lib/spec-cordova/build.spec.js
deleted file mode 100644
index 259c3d4..0000000
--- a/cordova-lib/spec-cordova/build.spec.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    shell = require('shelljs'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    Q = require('q'),
-    util = require('../src/util');
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-describe('build command', function() {
-    var is_cordova, cd_project_root, list_platforms, fire;
-    var project_dir = '/some/path';
-    var prepare_spy, compile_spy;
-    var result;
-
-    function buildPromise(f) {
-        f.then(function() { result = true; }, function(err) { result = err; });
-    }
-
-    function wrapper(f, post) {
-        runs(function() {
-            buildPromise(f);
-        });
-        waitsFor(function() { return result; }, 'promise never resolved', 500);
-        runs(post);
-    }
-
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
-        compile_spy = spyOn(cordova.raw, 'compile').andReturn(Q());
-    });
-    describe('failure', function() {
-        it('should not run inside a project with no platforms', function(done) {
-            list_platforms.andReturn([]);
-            Q().then(cordova.raw.build).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual(
-                    'No platforms added to this project. Please use `cordova platform add <platform>`.'
-                )
-            }).fin(done);
-        });
-
-        it('should not run outside of a Cordova-based project', function(done) {
-            is_cordova.andReturn(false);
-
-            Q().then(cordova.raw.build).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual(
-                    'Current working directory is not a Cordova-based project.'
-                )
-            }).fin(done);
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and call both prepare and compile', function(done) {
-            cordova.raw.build(['android','ios']).then(function() {
-                var opts = {verbose: false, platforms: ['android', 'ios'], options: []};
-                expect(prepare_spy).toHaveBeenCalledWith(opts);
-                expect(compile_spy).toHaveBeenCalledWith(opts);
-                done();
-            });
-        });
-        it('should pass down options', function(done) {
-            cordova.raw.build({platforms: ['android'], options: ['--release']}).then(function() {
-                var opts = {platforms: ['android'], options: ["--release"], verbose: false};
-                expect(prepare_spy).toHaveBeenCalledWith(opts);
-                expect(compile_spy).toHaveBeenCalledWith(opts);
-                done();
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.build(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_build', {verbose: false, platforms:['android', 'ios'], options: []});
-                    done();
-                });
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.build('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_build', {verbose: false, platforms:['android'], options: []});
-                     done();
-                });
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.build).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(err.message).toEqual(
-                        'No platforms added to this project. Please use `cordova platform add <platform>`.'
-                    )
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/compile.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/compile.spec.js b/cordova-lib/spec-cordova/compile.spec.js
deleted file mode 100644
index c1fc8b9..0000000
--- a/cordova-lib/spec-cordova/compile.spec.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    superspawn = require('../src/superspawn'),
-    util = require('../src/util'),
-    Q = require('q'),
-    os = require('os');
-
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-
-describe('compile command', function() {
-    var is_cordova, list_platforms, fire, result, cd_project_root;
-    var project_dir = '/some/path';
-
-    function wrapper(f, post) {
-        runs(function() {
-            Q().then(f).then(function() { result = true; }, function(err) { result = err; });
-        });
-        waitsFor(function() { return result; }, 'promise never resolved', 500);
-        runs(post);
-    }
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        spyOn(superspawn, 'spawn').andCallFake(function() { return Q() });
-    });
-    describe('failure', function() {
-        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() {
-            list_platforms.andReturn([]);
-            wrapper(cordova.raw.compile, function() {
-                expect('' + result).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            });
-        });
-        it('should not run outside of a Cordova-based project', function() {
-            is_cordova.andReturn(false);
-            wrapper(cordova.raw.compile, function() {
-                expect(result instanceof Error).toBe(true);
-            });
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and shell out to build', function(done) {
-            cordova.raw.compile(['android','ios']).then(function() {
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'build'), [], jasmine.any(Object));
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'build'), [], jasmine.any(Object));
-                done();
-            });
-        });
-
-        it('should pass down optional parameters', function (done) {
-            cordova.raw.compile({platforms:["blackberry10"], options:["--release"]}).then(function () {
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'build'), ['--release'], jasmine.any(Object));
-                done();
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.compile(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_compile', {verbose: false, platforms:['android', 'ios'], options: []});
-                    done();
-                });
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.compile('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_compile', {verbose: false, platforms:['android'], options: []});
-                     done();
-                });
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.compile).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(fire).not.toHaveBeenCalled();
-                    expect(err.message).toContain(
-                        'No platforms added to this project. Please use `cordova platform add <platform>`.'
-                    )
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/create.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/create.spec.js b/cordova-lib/spec-cordova/create.spec.js
deleted file mode 100644
index ebdfab5..0000000
--- a/cordova-lib/spec-cordova/create.spec.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var helpers = require('./helpers'),
-    path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    Q = require('q'),
-    config = require('../src/config'),
-    events = require('../src/events'),
-    util = require('../src/util'),
-    ConfigParser = require('../src/ConfigParser'),
-    cordova = require('../cordova');
-
-// A utility function to generate all combinations of elements from 2 arrays.
-// crossConcat(['x', 'y'], ['1', '2', '3'])
-// -> [ 'x1', 'x2', 'x3', 'y1', 'y2', 'y3']
-var crossConcat = function(a, b, delimiter){
-    var result = [];
-    delimiter = delimiter || '';
-    for (var i = 0; i < a.length; i++) {
-        for (var j = 0; j < b.length; j++) {
-            result.push(a[i] + delimiter + b[j]);
-        }
-    }
-    return result;
-};
-
-var tmpDir = helpers.tmpDir('create_test');
-var appName = 'TestBase';
-var appId = 'org.testing';
-var project = path.join(tmpDir, appName);
-var cordovaDir = path.join(project, '.cordova');
-var configNormal = {
-      lib: {
-        www: {
-          uri: path.join(__dirname, 'fixtures', 'base', 'www'),
-          version: "testCordovaCreate",
-          id: appName
-        }
-      }
-    };
-var configSymlink = {
-      lib: {
-        www: {
-          uri: path.join(__dirname, 'fixtures', 'base'), // "create" should copy or link the www child of this dir and not the dir itself.
-          link: true
-        }
-      }
-    };
-
-
-describe('create end-to-end', function() {
-
-    beforeEach(function() {
-        shell.rm('-rf', project);
-    });
-    afterEach(function() {
-        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
-        shell.rm('-rf', tmpDir);
-    });
-
-    function checkProject() {
-        // Check if top level dirs exist.
-        var dirs = ['hooks', 'platforms', 'merges', 'plugins', 'www'];
-        dirs.forEach(function(d) {
-            expect(path.join(project, d)).toExist();
-        });
-
-        expect(path.join(project, 'hooks', 'README.md')).toExist();
-
-        // Check if config files exist.
-        expect(path.join(project, 'www', 'index.html')).toExist();
-
-        // Check that www/config.xml was updated.
-        var configXml = new ConfigParser(path.join(project, 'www', 'config.xml'));
-        expect(configXml.packageName()).toEqual(appId);
-
-        // TODO (kamrik): check somehow that we got the right config.xml from the fixture and not some place else.
-        // expect(configXml.name()).toEqual('TestBase');
-    }
-
-    var results;
-    events.on('results', function(res) { results = res; });
-
-    it('should successfully run with regular config', function(done) {
-        // Call cordova create with no args, should return help.
-        cordova.raw.create()
-        .then(function() {
-            expect(results).toMatch(/synopsis/gi);
-        })
-        .then(function() {
-            // Create a real project
-            return cordova.raw.create(project, appId, appName, configNormal);
-        })
-        .then(checkProject)
-        .fail(function(err) {
-            console.log(err);
-            expect(err).toBeUndefined();
-        })
-        .fin(done);
-    });
-
-    it('should successfully run with symlinked www', function(done) {
-        // Call cordova create with no args, should return help.
-        cordova.raw.create(project, appId, appName, configSymlink)
-        .then(checkProject)
-        .then(function() {
-            // Check that www is really a symlink
-            expect(fs.lstatSync(path.join(project, 'www')).isSymbolicLink()).toBe(true);
-        })
-        .fail(function(err) {
-            if(process.platform.slice(0, 3) == 'win') {
-                // Allow symlink error if not in admin mode
-                expect(err.message).toBe("Symlinks on Windows require Administrator privileges");
-            } else {
-                expect(err).toBeUndefined();
-            }
-        })
-        .fin(done);
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/emulate.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/emulate.spec.js b/cordova-lib/spec-cordova/emulate.spec.js
deleted file mode 100644
index 8435535..0000000
--- a/cordova-lib/spec-cordova/emulate.spec.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    superspawn = require('../src/superspawn'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    Q = require('q'),
-    util = require('../src/util'),
-    os = require('os');
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-describe('emulate command', function() {
-    var is_cordova, cd_project_root, list_platforms, fire, result;
-    var project_dir = '/some/path';
-    var prepare_spy;
-
-    function wrapper(f, post) {
-        runs(function() {
-            Q().then(f).then(function() { result = true; }, function(err) { result = err; });
-        });
-        waitsFor(function() { return result; }, 'promise never resolved', 500);
-        runs(post);
-    }
-
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
-        spyOn(superspawn, 'spawn').andCallFake(Q);
-    });
-    describe('failure', function() {
-        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() {
-            list_platforms.andReturn([]);
-            wrapper(cordova.raw.emulate, function() {
-                expect(''+ result).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            });
-        });
-        it('should not run outside of a Cordova-based project', function() {
-            is_cordova.andReturn(false);
-            wrapper(cordova.raw.emulate, function() {
-                expect(result instanceof Error).toBe(true);
-            });
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the emulate script', function(done) {
-            cordova.raw.emulate(['android','ios']).then(function(err) {
-                expect(prepare_spy).toHaveBeenCalledWith(['android', 'ios']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), ['--emulator'], jasmine.any(Object));
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator'], jasmine.any(Object));
-
-                done();
-            });
-        });
-        it('should pass down options', function(done) {
-            cordova.raw.emulate({platforms: ['ios'], options:["--optionTastic"]}).then(function(err) {
-                expect(prepare_spy).toHaveBeenCalledWith(['ios']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator', '--optionTastic'], jasmine.any(Object));
-
-                done();
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.emulate(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_emulate', {verbose: false, platforms:['android', 'ios'], options: []});
-                    done();
-                });
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.emulate('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_emulate', {verbose: false, platforms:['android'], options: []});
-                     done();
-                });
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.emulate).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(fire).not.toHaveBeenCalled();
-                    expect(''+err).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.')
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json b/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json
deleted file mode 100644
index 662fc9d..0000000
--- a/cordova-lib/spec-cordova/fixtures/base/.cordova/config.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "id": "org.testing",
-  "name":"TestBase",
-  "lib": {
-    "android": {
-      "uri": "/some/junk/path",
-      "version": "dev",
-      "id": "cordova-android-dev"
-    },
-    "ios": {
-      "uri": "/some/junk/path",
-      "version": "dev",
-      "id": "cordova-ios-dev"
-    },
-    "wp8": {
-      "uri": "/some/junk/path",
-      "version": "dev",
-      "id": "cordova-wp8-dev"
-    }
-  }
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/merges/.svn
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/merges/.svn b/cordova-lib/spec-cordova/fixtures/base/merges/.svn
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/plugins/.svn
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/plugins/.svn b/cordova-lib/spec-cordova/fixtures/base/plugins/.svn
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/www/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/config.xml b/cordova-lib/spec-cordova/fixtures/base/www/config.xml
deleted file mode 100644
index 9e7b9e0..0000000
--- a/cordova-lib/spec-cordova/fixtures/base/www/config.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <name>TestBase</name>
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-    <author email="dev@cordova.apache.org" href="http://cordova.io">
-        Apache Cordova Team
-    </author>
-    <content src="index.html" />
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/www/css/index.css
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/css/index.css b/cordova-lib/spec-cordova/fixtures/base/www/css/index.css
deleted file mode 100644
index 51daa79..0000000
--- a/cordova-lib/spec-cordova/fixtures/base/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-* {
-    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
-}
-
-body {
-    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
-    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
-    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
-    background-color:#E4E4E4;
-    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-gradient(
-        linear,
-        left top,
-        left bottom,
-        color-stop(0, #A7A7A7),
-        color-stop(0.51, #E4E4E4)
-    );
-    background-attachment:fixed;
-    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
-    font-size:12px;
-    height:100%;
-    margin:0px;
-    padding:0px;
-    text-transform:uppercase;
-    width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
-    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
-    position:absolute;             /* position in the center of the screen */
-    left:50%;
-    top:50%;
-    height:50px;                   /* text area height */
-    width:225px;                   /* text area width */
-    text-align:center;
-    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
-    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
-                                   /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
-    .app {
-        background-position:left center;
-        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
-        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
-                                      /* offset horizontal: half of image width and text area width */
-    }
-}
-
-h1 {
-    font-size:24px;
-    font-weight:normal;
-    margin:0px;
-    overflow:visible;
-    padding:0px;
-    text-align:center;
-}
-
-.event {
-    border-radius:4px;
-    -webkit-border-radius:4px;
-    color:#FFFFFF;
-    font-size:12px;
-    margin:0px 30px;
-    padding:2px 0px;
-}
-
-.event.listening {
-    background-color:#333333;
-    display:block;
-}
-
-.event.received {
-    background-color:#4B946A;
-    display:none;
-}
-
-@keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-@-webkit-keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-.blink {
-    animation:fade 3000ms infinite;
-    -webkit-animation:fade 3000ms infinite;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png b/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
Binary files a/cordova-lib/spec-cordova/fixtures/base/www/img/logo.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/www/index.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/index.html b/cordova-lib/spec-cordova/fixtures/base/www/index.html
deleted file mode 100644
index bde5741..0000000
--- a/cordova-lib/spec-cordova/fixtures/base/www/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <meta name="format-detection" content="telephone=no" />
-        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
-        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
-        <link rel="stylesheet" type="text/css" href="css/index.css" />
-        <title>Hello World</title>
-    </head>
-    <body>
-        <div class="app">
-            <h1>Apache Cordova</h1>
-            <div id="deviceready" class="blink">
-                <p class="event listening">Connecting to Device</p>
-                <p class="event received">Device is Ready</p>
-            </div>
-        </div>
-        <script type="text/javascript" src="cordova.js"></script>
-        <script type="text/javascript" src="js/index.js"></script>
-        <script type="text/javascript">
-            app.initialize();
-        </script>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/www/js/index.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/js/index.js b/cordova-lib/spec-cordova/fixtures/base/www/js/index.js
deleted file mode 100644
index 31d9064..0000000
--- a/cordova-lib/spec-cordova/fixtures/base/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-var app = {
-    // Application Constructor
-    initialize: function() {
-        this.bindEvents();
-    },
-    // Bind Event Listeners
-    //
-    // Bind any events that are required on startup. Common events are:
-    // 'load', 'deviceready', 'offline', and 'online'.
-    bindEvents: function() {
-        document.addEventListener('deviceready', this.onDeviceReady, false);
-    },
-    // deviceready Event Handler
-    //
-    // The scope of 'this' is the event. In order to call the 'receivedEvent'
-    // function, we must explicity call 'app.receivedEvent(...);'
-    onDeviceReady: function() {
-        app.receivedEvent('deviceready');
-    },
-    // Update DOM on a Received Event
-    receivedEvent: function(id) {
-        var parentElement = document.getElementById(id);
-        var listeningElement = parentElement.querySelector('.listening');
-        var receivedElement = parentElement.querySelector('.received');
-
-        listeningElement.setAttribute('style', 'display:none;');
-        receivedElement.setAttribute('style', 'display:block;');
-
-        console.log('Received Event: ' + id);
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/base/www/spec.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/base/www/spec.html b/cordova-lib/spec-cordova/fixtures/base/www/spec.html
deleted file mode 100644
index 71f00de..0000000
--- a/cordova-lib/spec-cordova/fixtures/base/www/spec.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <title>Jasmine Spec Runner</title>
-
-        <!-- jasmine source -->
-        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
-        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
-
-        <!-- include source files here... -->
-        <script type="text/javascript" src="js/index.js"></script>
-
-        <!-- include spec files here... -->
-        <script type="text/javascript" src="spec/helper.js"></script>
-        <script type="text/javascript" src="spec/index.js"></script>
-
-        <script type="text/javascript">
-            (function() {
-                var jasmineEnv = jasmine.getEnv();
-                jasmineEnv.updateInterval = 1000;
-
-                var htmlReporter = new jasmine.HtmlReporter();
-
-                jasmineEnv.addReporter(htmlReporter);
-
-                jasmineEnv.specFilter = function(spec) {
-                    return htmlReporter.specFilter(spec);
-                };
-
-                var currentWindowOnload = window.onload;
-
-                window.onload = function() {
-                    if (currentWindowOnload) {
-                        currentWindowOnload();
-                    }
-                    execJasmine();
-                };
-
-                function execJasmine() {
-                    jasmineEnv.execute();
-                }
-            })();
-        </script>
-    </head>
-    <body>
-        <div id="stage" style="display:none;"></div>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat
deleted file mode 100644
index a89b4c8..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_bat/fail/fail.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@ECHO OFF
-EXIT /B 1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat
deleted file mode 100644
index ada7136..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/.dotted.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@ECHO OFF
-ECHO "Dotted files in hook dirs should not be called" > dotted_hook_should_not_fire.txt
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat
deleted file mode 100644
index a88c8c5..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/07.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@ECHO OFF
-rem ECHO this is script 0 in %~dp0
-ECHO b >> hooks_order.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat b/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat
deleted file mode 100644
index be004c5..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_bat/test/1.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-@ECHO OFF
-rem ECHO this is script 1 in %~dp0
-ECHO a >> hooks_order.txt
-ECHO %1 > hooks_params.txt
-node -e "console.log(JSON.stringify(process.env, null, 2))" > hooks_env.json

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh
deleted file mode 100755
index 379a4c9..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_sh/fail/fail.sh
+++ /dev/null
@@ -1 +0,0 @@
-exit 1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh
deleted file mode 100755
index e5fa07f..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/.dotted.sh
+++ /dev/null
@@ -1 +0,0 @@
-echo "Dotted files in hook dirs should not be called" > dotted_hook_should_not_fire.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh
deleted file mode 100755
index f410ee2..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/07.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#echo "this is script 0 in `pwd`";
-echo b >> hooks_order.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh b/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh
deleted file mode 100755
index 892869d..0000000
--- a/cordova-lib/spec-cordova/fixtures/hooks_sh/test/1.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#echo "this is script 1 in `pwd`";
-echo a >> hooks_order.txt
-echo $1 > hooks_params.txt
-node -e "console.log(JSON.stringify(process.env, null, 2))" > hooks_env.json

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION b/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION
deleted file mode 100644
index 15a2799..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android-lib/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-3.3.0

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js b/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js
deleted file mode 100644
index 91c51fc..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android-lib/framework/assets/www/cordova.js
+++ /dev/null
@@ -1 +0,0 @@
-This is a placeholder file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml
deleted file mode 100644
index be3f245..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/AndroidManifest.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" android:windowSoftInputMode="adjustPan" package="org.testing" xmlns:android="http://schemas.android.com/apk/res/android">
-    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <application android:debuggable="true" android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
-        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="TestBase" android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
-</manifest>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml
deleted file mode 100644
index 9e7b9e0..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/config.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <name>TestBase</name>
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-    <author email="dev@cordova.apache.org" href="http://cordova.io">
-        Apache Cordova Team
-    </author>
-    <content src="index.html" />
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>


[16/24] Remove all cordova-lib files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/wp8_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/wp8_parser.js b/cordova-lib/src/cordova/metadata/wp8_parser.js
deleted file mode 100644
index b5f0326..0000000
--- a/cordova-lib/src/cordova/metadata/wp8_parser.js
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    child_process = require('child_process'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    xml           = require('../xml-helpers'),
-    config        = require('../config'),
-    hooker        = require('../hooker');
-
-module.exports = function wp8_parser(project) {
-    try {
-        // TODO : Check that it's not a wp8 project?
-        var csproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
-        if (!csproj_file) throw new CordovaError('No .csproj file in "'+project+'"');
-        this.wp8_proj_dir = project;
-        this.csproj_path  = path.join(this.wp8_proj_dir, csproj_file);
-        this.sln_path     = path.join(this.wp8_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
-    } catch(e) {
-        throw new CordovaError('The provided path "' + project + '" is not a Windows Phone 8 project. ' + e);
-    }
-    this.manifest_path  = path.join(this.wp8_proj_dir, 'Properties', 'WMAppManifest.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking wp8 requirements...');
-    var lib_path = path.join(util.libDirectory, 'wp', 'cordova', require('../../platforms').wp8.version, 'wp8');
-    var custom_path = config.has_custom_path(project_root, 'wp8');
-    if (custom_path) {
-        lib_path = path.join(custom_path, 'wp8');
-    }
-    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output);
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-    update_from_config:function(config) {
-        //check config parser
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        //Get manifest file
-        var manifest = xml.parseElementtreeSync(this.manifest_path);
-
-        //Update app version
-        var version = config.version();
-        manifest.find('.//App').attrib.Version = version;
-
-        // Update app name by editing app title in Properties\WMAppManifest.xml
-        var name = config.name();
-        var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
-        if(prev_name != name) {
-            //console.log("Updating app name from " + prev_name + " to " + name);
-            manifest.find('.//App').attrib.Title = name;
-            manifest.find('.//App').attrib.Publisher = name + " Publisher";
-            manifest.find('.//App').attrib.Author = name + " Author";
-            manifest.find('.//PrimaryToken').attrib.TokenID = name;
-            //update name of sln and csproj.
-            name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
-            prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
-            // TODO: might return .sln.user? (generated file)
-            var sln_name = fs.readdirSync(this.wp8_proj_dir).filter(function(e) { return e.match(/\.sln$/i); })[0];
-            var sln_path = path.join(this.wp8_proj_dir, sln_name);
-            var sln_file = fs.readFileSync(sln_path, 'utf-8');
-            var name_regex = new RegExp(prev_name, "g");
-            fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
-            shell.mv('-f', this.csproj_path, path.join(this.wp8_proj_dir, name + '.csproj'));
-            this.csproj_path = path.join(this.wp8_proj_dir, name + '.csproj');
-            shell.mv('-f', sln_path, path.join(this.wp8_proj_dir, name + '.sln'));
-            this.sln_path    = path.join(this.wp8_proj_dir, name + '.sln');
-        }
-
-        // Update package name by changing:
-        /*  - CordovaAppProj.csproj
-         *  - MainPage.xaml
-         *  - MainPage.xaml.cs
-         *  - App.xaml
-         *  - App.xaml.cs
-         */
-         var pkg = config.packageName();
-         var csproj = xml.parseElementtreeSync(this.csproj_path);
-         prev_name = csproj.find('.//RootNamespace').text;
-         if(prev_name != pkg) {
-            //console.log("Updating package name from " + prev_name + " to " + pkg);
-            //CordovaAppProj.csproj
-            csproj.find('.//RootNamespace').text = pkg;
-            csproj.find('.//AssemblyName').text = pkg;
-            csproj.find('.//XapFilename').text = pkg + '.xap';
-            csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
-            fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
-            //MainPage.xaml
-            var mainPageXAML = xml.parseElementtreeSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'));
-            mainPageXAML.getroot().attrib['x:Class'] = pkg + '.MainPage';
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
-            //MainPage.xaml.cs
-            var mainPageCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
-            var namespaceRegEx = new RegExp('namespace ' + prev_name);
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-            //App.xaml
-            var appXAML = xml.parseElementtreeSync(path.join(this.wp8_proj_dir, 'App.xaml'));
-            appXAML.getroot().attrib['x:Class'] = pkg + '.App';
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
-            //App.xaml.cs
-            var appCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), 'utf-8');
-            fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-         }
-
-         //Write out manifest
-         fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
-
-        // Update icons
-        var icons = config.getIcons('wp8');
-        var platformRoot = this.wp8_proj_dir;
-        var appRoot = util.isCordova(platformRoot);
-
-        // icons, that should be added to platform
-        // @param dest {string} Path to copy icon to, relative to platform root
-        var platformIcons = [
-            {dest: "ApplicationIcon.png", width: 99, height: 99},
-            {dest: "Background.png", width: 159, height: 159},
-        ];
-
-        platformIcons.forEach(function (item) {
-            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
-            if (icon){
-                var src = path.join(appRoot, icon.src),
-                    dest = path.join(platformRoot, item.dest);
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        });
-
-    },
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.wp8_proj_dir, 'www');
-    },
-    config_xml:function() {
-        return path.join(this.wp8_proj_dir, 'config.xml');
-    },
-    // copy files from merges directory to actual www dir
-    copy_merges:function(merges_sub_path) {
-        var merges_path = path.join(util.appDir(util.isCordova(this.wp8_proj_dir)), 'merges', merges_sub_path);
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, '..', 'common', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.wp8_proj_dir);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.wp8_proj_dir, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-
-        // Copy all files from merges directories - wp generic first, then wp8 specific.
-        this.copy_merges('wp');
-        this.copy_merges('wp8');
-
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // updates the csproj file to explicitly list all www content.
-    update_csproj:function() {
-        var csproj_xml = xml.parseElementtreeSync(this.csproj_path);
-        // remove any previous references to the www files
-        var item_groups = csproj_xml.findall('ItemGroup');
-        for (var i = 0, l = item_groups.length; i < l; i++) {
-            var group = item_groups[i];
-            var files = group.findall('Content');
-            for (var j = 0, k = files.length; j < k; j++) {
-                var file = files[j];
-                if (file.attrib.Include.substr(0, 3) == 'www') {
-                    // remove file reference
-                    group.remove(0, file);
-                    // remove ItemGroup if empty
-                    var new_group = group.findall('Content');
-                    if(new_group.length < 1) {
-                        csproj_xml.getroot().remove(0, group);
-                    }
-                }
-            }
-        }
-
-        // now add all www references back in from the root www folder
-        var www_files = this.folder_contents('www', this.www_dir());
-        for(file in www_files) {
-            var item = new et.Element('ItemGroup');
-            var content = new et.Element('Content');
-            content.attrib.Include = www_files[file];
-            item.append(content);
-            csproj_xml.getroot().append(item);
-        }
-        // save file
-        fs.writeFileSync(this.csproj_path, csproj_xml.write({indent:4}), 'utf-8');
-    },
-    // Returns an array of all the files in the given directory with relative paths
-    // - name     : the name of the top level directory (i.e all files will start with this in their path)
-    // - dir     : the directory whos contents will be listed under 'name' directory
-    folder_contents:function(name, dir) {
-        var results = [];
-        var folder_dir = fs.readdirSync(dir);
-        for(item in folder_dir) {
-            var stat = fs.statSync(path.join(dir, folder_dir[item]));
-
-            if(stat.isDirectory()) {
-                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
-                //Add all subfolder item paths
-                for(sub_item in sub_dir) {
-                    results.push(sub_dir[sub_item]);
-                }
-            }
-            else if(stat.isFile()) {
-                results.push(path.join(name, folder_dir[item]));
-            }
-            // else { it is a FIFO, or a Socket or something ... }
-        }
-        return results;
-    },
-
-    // calls the nessesary functions to update the wp8 project
-    // Returns a promise.
-    update_project:function(cfg) {
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-
-        // trigger an event in case anyone needs to modify the contents of the www folder before we package it.
-        var that = this;
-        var projectRoot = util.isCordova(process.cwd());
-
-        var hooks = new hooker(projectRoot);
-        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['wp8']  })
-        .then(function() {
-            that.update_csproj();
-            util.deleteSvnFolders(that.www_dir());
-        });
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/platform.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/platform.js b/cordova-lib/src/cordova/platform.js
deleted file mode 100644
index bd20780..0000000
--- a/cordova-lib/src/cordova/platform.js
+++ /dev/null
@@ -1,399 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var config            = require('./config'),
-    cordova           = require('../cordova'),
-    cordova_util      = require('./util'),
-    ConfigParser     = require('./ConfigParser'),
-    util              = require('util'),
-    fs                = require('fs'),
-    os                = require('os'),
-    path              = require('path'),
-    hooker            = require('./hooker'),
-    events            = require('./events'),
-    lazy_load         = require('./lazy_load'),
-    CordovaError      = require('./CordovaError'),
-    Q                 = require('q'),
-    platforms         = require('../platforms'),
-    superspawn        = require('./superspawn'),
-    semver            = require('semver'),
-    shell             = require('shelljs');
-
-function getVersionFromScript(script, defaultValue) {
-    var versionPromise = Q(defaultValue);
-    if (fs.existsSync(script)) {
-        versionPromise = superspawn.spawn(script);
-    } else {
-        /* if you are here, it's probably because you're in Jasmine: fix your existsSync stub */
-        versionPromise = Q(defaultValue);
-    }
-    return versionPromise;
-}
-
-function add(hooks, projectRoot, targets, opts) {
-    var xml = cordova_util.projectConfig(projectRoot);
-    var cfg = new ConfigParser(xml);
-    if (!targets || !targets.length) {
-        return Q.reject(new CordovaError('No platform specified. Please specify a platform to add. See "platform list".'));
-    }
-    var config_json = config.read(projectRoot);
-    var platformsDir = path.join(projectRoot, 'platforms');
-
-    // The "platforms" dir is safe to delete, it's almost equivalent to
-    // cordova platfrom rm <list of all platforms>
-    if ( !fs.existsSync(platformsDir)) {
-        shell.mkdir('-p', platformsDir);
-    }
-
-    return hooks.fire('before_platform_add', opts)
-    .then(function() {
-        return targets.reduce(function(soFar, t) {
-            return soFar.then(function() {
-                return lazy_load.based_on_config(projectRoot, t)
-                .then(function(libDir) {
-                    var template = config_json.lib && config_json.lib[t] && config_json.lib[t].template || null;
-                    var copts = null;
-                    if ('spawnoutput' in opts) {
-                        copts = opts.spawnoutput;
-                    }
-                    return call_into_create(t, projectRoot, cfg, libDir, template, copts);
-                }, function(err) {
-                    throw new CordovaError('Unable to fetch platform ' + t + ': ' + err);
-                });
-            });
-        }, Q());
-    })
-    .then(function() {
-        return hooks.fire('after_platform_add', opts);
-    });
-};
-
-function remove(hooks, projectRoot, targets, opts) {
-    if (!targets || !targets.length) {
-        return Q.reject(new CordovaError('No platform[s] specified. Please specify platform[s] to remove. See "platform list".'));
-    }
-    return hooks.fire('before_platform_rm', opts)
-    .then(function() {
-        targets.forEach(function(target) {
-            shell.rm('-rf', path.join(projectRoot, 'platforms', target));
-            var plugins_json = path.join(projectRoot, 'plugins', target + '.json');
-            if (fs.existsSync(plugins_json)) shell.rm(plugins_json);
-        });
-    }).then(function() {
-        return hooks.fire('after_platform_rm', opts);
-    });
-}
-
-function update(hooks, projectRoot, targets, opts) {
-    // Shell out to the update script provided by the named platform.
-    if (!targets || !targets.length) {
-        return Q.reject(new CordovaError('No platform specified. Please specify a platform to update. See "platform list".'));
-    } else if (targets.length > 1) {
-        return Q.reject(new CordovaError('Platform update can only be executed on one platform at a time.'));
-    } else {
-        var plat = targets[0];
-        var platformPath = path.join(projectRoot, 'platforms', plat);
-        var installed_platforms = cordova_util.listPlatforms(projectRoot);
-        if (installed_platforms.indexOf(plat) < 0) {
-            return Q.reject(new CordovaError('Platform "' + plat + '" is not installed. See "platform list".'));
-        }
-
-        function copyCordovaJs() {
-            var parser = new platforms[plat].parser(platformPath);
-            var platform_www = path.join(platformPath, 'platform_www');
-            shell.mkdir('-p', platform_www);
-            shell.cp('-f', path.join(parser.www_dir(), 'cordova.js'), path.join(platform_www, 'cordova.js'));
-        }
-
-        // First, lazy_load the latest version.
-        return hooks.fire('before_platform_update', opts)
-        .then(function() {
-            return lazy_load.based_on_config(projectRoot, plat);
-        }).then(function(libDir) {
-            // Call the platform's update script.
-            var script = path.join(libDir, 'bin', 'update');
-            return superspawn.spawn(script, [platformPath], { stdio: 'inherit' })
-            .then(function() {
-                // Copy the new cordova.js from www -> platform_www.
-                copyCordovaJs();
-                // Leave it to the update script to log out "updated to v FOO".
-            });
-        });
-    }
-}
-
-function check(hooks, projectRoot) {
-    var platformsText = [],
-        platforms_on_fs = cordova_util.listPlatforms(projectRoot),
-        scratch = path.join(os.tmpdir(), "cordova-platform-check-"+Date.now()),
-        listeners = events._events;
-        events._events = {};
-    var result = Q.defer();
-    cordova.raw.create(scratch)
-    .then(function () {
-        var h = new hooker(scratch);
-        // Acquire the version number of each platform we have installed, and output that too.
-        Q.all(platforms_on_fs.map(function(p) {
-            var d = Q.defer();
-            add(h, scratch, [p], {spawnoutput: {stdio: 'ignore'}})
-            .then(function() {
-                var d_avail = Q.defer(),
-                    d_cur = Q.defer();
-                getVersionFromScript(path.join(scratch, 'platforms', p, 'cordova', 'version'), null)
-                .then(function(avail) {
-                    if (!avail) {
-                        /* Platform version script was silent, we can't work with this */
-                        d_avail.resolve('');
-                    } else {
-                        d_avail.resolve(avail);
-                    }
-                })
-                .catch(function () {
-                    /* Platform version script failed, we can't work with this */
-                    d_avail.resolve('');
-                });
-                getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
-                .catch(function () {
-                    d_cur.resolve('broken');
-                }).then(function(v) {
-                    d_cur.resolve(v || '');
-                });
-                Q.all([d_avail.promise, d_cur.promise]).spread(function (avail, v) {
-                    var m;
-                    if (avail && (!v || v == 'broken' || semver.gt(avail, v))) {
-                        m = p + ' @ ' + (v || 'unknown') + ' could be updated to: ' + avail;
-                        platformsText.push(m);
-                    }
-                    d.resolve(m);
-                })
-                .catch(function () {
-                    return '?';
-                })
-                .done();
-            })
-            .catch(function () {
-                /* If a platform doesn't install, then we can't realistically suggest updating */
-                d.resolve();
-            });
-            return d.promise;
-        })).then(function() {
-            var results = '';
-            events._events = listeners;
-            shell.rm('-rf', scratch);
-            if (platformsText) {
-                results = platformsText.filter(function (p) {return !!p}).sort().join('\n');
-            }
-            if (!results) {
-                results = 'All platforms are up-to-date.';
-            }
-            events.emit('results', results);
-            result.resolve();
-        })
-        .done();
-    }).catch(function (){
-        events._events = listeners;
-        shell.rm('-rf', scratch);
-    })
-    .done();
-    return result.promise;
-}
-
-function list(hooks, projectRoot) {
-    var platforms_on_fs = cordova_util.listPlatforms(projectRoot);
-    return hooks.fire('before_platform_ls')
-    .then(function() {
-        // Acquire the version number of each platform we have installed, and output that too.
-        return Q.all(platforms_on_fs.map(function(p) {
-            return getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
-            .then(function(v) {
-                if (!v) return p;
-                return p + ' ' + v;
-            }, function(v) {
-                return p + ' broken';
-            });
-        }));
-    }).then(function(platformsText) {
-        var results = 'Installed platforms: ' + platformsText.sort().join(', ') + '\n';
-        var available = Object.getOwnPropertyNames(platforms).filter(function(p) {
-            var platform = platforms[p] || {},
-                hostos = platform.hostos || null;
-            if (!hostos)
-                return true;
-            if (hostos.indexOf('*') >= 0)
-                return true;
-            if (hostos.indexOf(process.platform) >= 0)
-                return true;
-            return false;
-        });
-
-        available = available.filter(function(p) {
-            return platforms_on_fs.indexOf(p) < 0; // Only those not already installed.
-        });
-        results += 'Available platforms: ' + available.sort().join(', ');
-
-        events.emit('results', results);
-    }).then(function() {
-        return hooks.fire('after_platform_ls');
-    });
-}
-
-// Returns a promise.
-module.exports = function platform(command, targets) {
-    var projectRoot = cordova_util.cdProjectRoot();
-
-    var hooks = new hooker(projectRoot);
-
-    if (arguments.length === 0) command = 'ls';
-    if (targets) {
-        if (!(targets instanceof Array)) targets = [targets];
-        var err;
-        targets.forEach(function(t) {
-            if (!(t in platforms)) {
-                err = new CordovaError('Platform "' + t + '" not recognized as a core cordova platform. See "platform list".');
-            }
-        });
-        if (err) return Q.reject(err);
-    } else {
-        if (command == 'add' || command == 'rm') {
-            return Q.reject(new CordovaError('You need to qualify `add` or `remove` with one or more platforms!'));
-        }
-    }
-
-    var opts = {
-        platforms:targets
-    };
-    switch(command) {
-        case 'add':
-            return add(hooks, projectRoot, targets, opts);
-        case 'rm':
-        case 'remove':
-            return remove(hooks, projectRoot, targets, opts);
-        case 'update':
-        case 'up':
-            return update(hooks, projectRoot, targets, opts);
-        case 'check':
-            return check(hooks, projectRoot);
-        case 'ls':
-        case 'list':
-        default:
-            return list(hooks, projectRoot);
-    }
-};
-
-/**
- * Check Platform Support.
- *
- *   - {String} `name` of the platform to test.
- *   - Returns a promise, which shows any errors.
- *
- */
-
-function supports(project_root, name) {
-    // required parameters
-    if (!name) return Q.reject(new CordovaError('requires a platform name parameter'));
-
-    // check if platform exists
-    var platform = platforms[name];
-    if (!platform) {
-        return Q.reject(new CordovaError(util.format('"%s" platform does not exist', name)));
-    }
-
-    // look up platform meta-data parser
-    var platformParser = platforms[name].parser;
-    if (!platformParser) {
-        return Q.reject(new Error(util.format('"%s" platform parser does not exist', name)));
-    }
-
-    // check for platform support
-    return platformParser.check_requirements(project_root);
-};
-
-// Expose the platform parsers on top of this command
-for (var p in platforms) {
-    module.exports[p] = platforms[p];
-}
-function createOverrides(projectRoot, target) {
-    shell.mkdir('-p', path.join(cordova_util.appDir(projectRoot), 'merges', target));
-};
-
-// Returns a promise.
-function call_into_create(target, projectRoot, cfg, libDir, template_dir, opts) {
-    var output = path.join(projectRoot, 'platforms', target);
-
-    // Check if output directory already exists.
-    if (fs.existsSync(output)) {
-        return Q.reject(new CordovaError('Platform ' + target + ' already added'));
-    } else {
-        // Make sure we have minimum requirements to work with specified platform
-        events.emit('verbose', 'Checking if platform "' + target + '" passes minimum requirements...');
-        /* XXX this is calling the public symbol so that Jasmine Spy can attack it */
-        return module.exports.supports(projectRoot, target)
-        .then(function() {
-            events.emit('log', 'Creating ' + target + ' project...');
-            var bin = path.join(libDir, 'bin', 'create');
-            var args = [];
-            if (target == 'android') {
-                var platformVersion = fs.readFileSync(path.join(libDir, 'VERSION'), 'UTF-8').trim();
-                if (semver.gt(platformVersion, '3.3.0')) {
-                    args.push('--cli');
-                }
-            } else if (target == 'ios') {
-                var platformVersion = fs.readFileSync(path.join(libDir, 'CordovaLib', 'VERSION'), 'UTF-8').trim();
-                args.push('--arc');
-                if (semver.gt(platformVersion, '3.3.0')) {
-                    args.push('--cli');
-                }
-            }
-
-            var pkg = cfg.packageName().replace(/[^\w.]/g,'_');
-            var name = cfg.name();
-            args.push(output, pkg, name);
-            if (template_dir) {
-                args.push(template_dir);
-            }
-            return superspawn.spawn(bin, args, opts || { stdio: 'inherit' })
-            .then(function() {
-                return require('../cordova').raw.prepare(target);
-            })
-            .then(function() {
-                createOverrides(projectRoot, target);
-                // Install all currently installed plugins into this new platform.
-                var plugins_dir = path.join(projectRoot, 'plugins');
-                var plugins = cordova_util.findPlugins(plugins_dir);
-                var parser = new platforms[target].parser(output);
-                if (!plugins) return Q();
-
-                var plugman = require('plugman');
-                // Install them serially.
-                return plugins.reduce(function(soFar, plugin) {
-                    return soFar.then(function() {
-                        events.emit('verbose', 'Installing plugin "' + plugin + '" following successful platform add of ' + target);
-                        return plugman.raw.install(target, output, path.basename(plugin), plugins_dir);
-                    });
-                }, Q());
-            });
-        });
-    }
-}
-
-module.exports.add = add;
-module.exports.remove = remove;
-module.exports.update = update;
-module.exports.check = check;
-module.exports.list = list;
-module.exports.supports = supports;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/platforms.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/platforms.js b/cordova-lib/src/cordova/platforms.js
deleted file mode 100644
index 5bb82f1..0000000
--- a/cordova-lib/src/cordova/platforms.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-module.exports = {
-    'ios' : {
-        hostos : ['darwin'],
-        parser : './src/metadata/ios_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ios.git',
-        version: '3.4.1'
-    }, 
-    'android' : {
-        parser : './src/metadata/android_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git',
-        version: '3.4.0'
-    }, 
-    'ubuntu' : {
-        hostos : ['linux'],
-        parser : './src/metadata/ubuntu_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ubuntu.git',
-        version: '3.4.0'
-    }, 
-     'amazon-fireos' : {
-        parser : './src/metadata/amazon_fireos_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-amazon-fireos.git',
-        version: '3.4.0'
-    },
-    'wp7' : {
-        hostos : ['win32'],
-        parser : './src/metadata/wp7_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',
-        version: '3.4.0',
-        subdirectory: 'wp7'
-    },
-    'wp8' : {
-        hostos : ['win32'],
-        parser : './src/metadata/wp8_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',
-        version: '3.4.0',
-        subdirectory: 'wp8'
-    },
-    'blackberry10' : {
-        parser : './src/metadata/blackberry10_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-blackberry.git',
-        version: '3.4.0',
-        subdirectory: 'blackberry10'
-    },
-    'www':{
-        hostos : [],
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-app-hello-world.git',
-        version: '3.4.0'
-    },
-    'firefoxos':{
-        parser: './src/metadata/firefoxos_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-firefoxos.git',
-        version: '3.4.0'
-    },
-    'windows8':{
-        hostos : ['win32'],
-        parser: './src/metadata/windows8_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-windows.git',
-        version: '3.4.0',
-        subdirectory: 'windows8'
-    }
-};
-
-var addModuleProperty = require('./src/util').addModuleProperty;
-Object.keys(module.exports).forEach(function(key) {
-    var obj = module.exports[key];
-    if (obj.parser) {
-        addModuleProperty(module, 'parser', obj.parser, false, obj);
-    }
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/plugin.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/plugin.js b/cordova-lib/src/cordova/plugin.js
deleted file mode 100644
index f0e01f7..0000000
--- a/cordova-lib/src/cordova/plugin.js
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-// Returns a promise.
-module.exports = function plugin(command, targets, opts) {
-    var cordova_util  = require('./util'),
-        path          = require('path'),
-        hooker        = require('./hooker'),
-        config        = require('./config'),
-        Q             = require('q'),
-        CordovaError  = require('./CordovaError'),
-        events        = require('./events');
-
-    var projectRoot = cordova_util.cdProjectRoot(),
-        err;
-
-    // Dance with all the possible call signatures we've come up over the time. They can be:
-    // 1. plugin() -> list the plugins
-    // 2. plugin(command, Array of targets, maybe opts object)
-    // 3. plugin(command, target1, target2, target3 ... )
-    // The targets are not really targets, they can be a mixture of plugins and options to be passed to plugman.
-
-    command = command || 'ls';
-    targets = targets || [];
-    opts = opts || {};
-    if ( opts.length ) {
-        // This is the case with multiple targes as separate arguments and opts is not opts but another target.
-        targets = Array.prototype.slice.call(arguments, 1);
-        opts = {};
-    }
-    if ( !Array.isArray(targets) ) {
-        // This means we had a single target given as string.
-        targets = [targets];
-    }
-    opts.options = [];
-    opts.plugins = [];
-
-    var hooks = new hooker(projectRoot);
-    var platformList = cordova_util.listPlatforms(projectRoot);
-
-    // Massage plugin name(s) / path(s)
-    var pluginPath, plugins;
-    pluginPath = path.join(projectRoot, 'plugins');
-    plugins = cordova_util.findPlugins(pluginPath);
-    if (!targets || !targets.length) {
-        if (command == 'add' || command == 'rm') {
-            return Q.reject(new CordovaError('You need to qualify `add` or `remove` with one or more plugins!'));
-        } else {
-            targets = [];
-        }
-    }
-
-    //Split targets between plugins and options
-    //Assume everything after a token with a '-' is an option
-    var i;
-    for (i = 0; i < targets.length; i++) {
-        if (targets[i].match(/^-/)) {
-            opts.options = targets.slice(i);
-            break;
-        } else {
-            opts.plugins.push(targets[i]);
-        }
-    }
-
-    switch(command) {
-        case 'add':
-            if (!targets || !targets.length) {
-                return Q.reject(new CordovaError('No plugin specified. Please specify a plugin to add. See "plugin search".'));
-            }
-
-            var config_json = config(projectRoot, {});
-            var searchPath = config_json.plugin_search_path || [];
-            if (typeof opts.searchpath == 'string') {
-                searchPath = opts.searchpath.split(path.delimiter).concat(searchPath);
-            } else if (opts.searchpath) {
-                searchPath = opts.searchpath.concat(searchPath);
-            }
-            // Blank it out to appease unit tests.
-            if (searchPath.length === 0) {
-                searchPath = undefined;
-            }
-
-            return hooks.fire('before_plugin_add', opts)
-            .then(function() {
-                return opts.plugins.reduce(function(soFar, target) {
-                    var pluginsDir = path.join(projectRoot, 'plugins');
-                    return soFar.then(function() {
-                        if (target[target.length - 1] == path.sep) {
-                            target = target.substring(0, target.length - 1);
-                        }
-
-                        // Fetch the plugin first.
-                        events.emit('verbose', 'Calling plugman.fetch on plugin "' + target + '"');
-                        var plugman = require('plugman');
-                        return plugman.raw.fetch(target, pluginsDir, { searchpath: searchPath});
-                    })
-                    .then(function(dir) {
-                        // Iterate (in serial!) over all platforms in the project and install the plugin.
-                        return platformList.reduce(function(soFar, platform) {
-                            return soFar.then(function() {
-                                var platforms = require('../platforms');
-                                var platformRoot = path.join(projectRoot, 'platforms', platform),
-                                    parser = new platforms[platform].parser(platformRoot),
-                                    options = {
-                                        cli_variables: {},
-                                        searchpath: searchPath
-                                    },
-                                    tokens,
-                                    key,
-                                    i;
-                                //parse variables into cli_variables
-                                for (i=0; i< opts.options.length; i++) {
-                                    if (opts.options[i] === "--variable" && typeof opts.options[++i] === "string") {
-                                        tokens = opts.options[i].split('=');
-                                        key = tokens.shift().toUpperCase();
-                                        if (/^[\w-_]+$/.test(key)) {
-                                            options.cli_variables[key] = tokens.join('=');
-                                        }
-                                    }
-                                }
-
-                                events.emit('verbose', 'Calling plugman.install on plugin "' + dir + '" for platform "' + platform + '" with options "' + JSON.stringify(options)  + '"');
-                                return plugman.raw.install(platform, platformRoot, path.basename(dir), pluginsDir, options);
-                            });
-                        }, Q());
-                    });
-                }, Q()); // end Q.all
-            }).then(function() {
-                return hooks.fire('after_plugin_add', opts);
-            });
-            break;
-        case 'rm':
-        case 'remove':
-            if (!targets || !targets.length) {
-                return Q.reject(new CordovaError('No plugin specified. Please specify a plugin to remove. See "plugin list".'));
-            }
-            return hooks.fire('before_plugin_rm', opts)
-            .then(function() {
-                return opts.plugins.reduce(function(soFar, target) {
-                    // Check if we have the plugin.
-                    if (plugins.indexOf(target) < 0) {
-                        return Q.reject(new CordovaError('Plugin "' + target + '" is not present in the project. See "plugin list".'));
-                    }
-
-                    var targetPath = path.join(pluginPath, target);
-                    // Iterate over all installed platforms and uninstall.
-                    // If this is a web-only or dependency-only plugin, then
-                    // there may be nothing to do here except remove the
-                    // reference from the platform's plugin config JSON.
-                    var plugman = require('plugman');
-                    return platformList.reduce(function(soFar, platform) {
-                        return soFar.then(function() {
-                            var platformRoot = path.join(projectRoot, 'platforms', platform);
-                            var platforms = require('../platforms');
-                            var parser = new platforms[platform].parser(platformRoot);
-                            events.emit('verbose', 'Calling plugman.uninstall on plugin "' + target + '" for platform "' + platform + '"');
-                            return plugman.raw.uninstall.uninstallPlatform(platform, platformRoot, target, path.join(projectRoot, 'plugins'));
-                        });
-                    }, Q())
-                    .then(function() {
-                        return plugman.raw.uninstall.uninstallPlugin(target, path.join(projectRoot, 'plugins'));
-                    });
-                }, Q());
-            }).then(function() {
-                return hooks.fire('after_plugin_rm', opts);
-            });
-            break;
-        case 'search':
-            return hooks.fire('before_plugin_search')
-            .then(function() {
-                var plugman = require('plugman');
-                return plugman.raw.search(opts.plugins);
-            }).then(function(plugins) {
-                for(var plugin in plugins) {
-                    events.emit('results', plugins[plugin].name, '-', plugins[plugin].description || 'no description provided');
-                }
-            }).then(function() {
-                return hooks.fire('after_plugin_search');
-            });
-            break;
-        case 'ls':
-        case 'list':
-        default:
-            return hooks.fire('before_plugin_ls')
-            .then(function() {
-                events.emit('results', (plugins.length ? plugins : 'No plugins added. Use `cordova plugin add <plugin>`.'));
-                return hooks.fire('after_plugin_ls')
-                .then(function() {
-                    return plugins;
-                });
-            });
-            break;
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/plugin_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/plugin_parser.js b/cordova-lib/src/cordova/plugin_parser.js
deleted file mode 100644
index d3099c0..0000000
--- a/cordova-lib/src/cordova/plugin_parser.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var xml = require('./xml-helpers'),
-    fs  = require('fs');
-
-function plugin_parser(xmlPath) {
-    this.path = xmlPath;
-    this.doc = xml.parseElementtreeSync(xmlPath);
-    this.platforms = this.doc.findall('platform').map(function(p) {
-        return p.attrib.name;
-    });
-}
-
-module.exports = plugin_parser;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/prepare.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/prepare.js b/cordova-lib/src/cordova/prepare.js
deleted file mode 100644
index eef0123..0000000
--- a/cordova-lib/src/cordova/prepare.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_util      = require('./util'),
-    ConfigParser = require('./ConfigParser'),
-    path              = require('path'),
-    platforms         = require('../platforms'),
-    platform          = require('./platform'),
-    fs                = require('fs'),
-    shell             = require('shelljs'),
-    et                = require('elementtree'),
-    hooker            = require('./hooker'),
-    lazy_load         = require('./lazy_load'),
-    events            = require('./events'),
-    Q                 = require('q'),
-    plugman           = require('plugman'),
-    util              = require('util');
-
-// Returns a promise.
-exports = module.exports = function prepare(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-
-    if (!options) {
-        options = {
-            verbose: false,
-            platforms: [],
-            options: []
-        };
-    }
-
-    options = cordova_util.preProcessOptions(options);
-
-    var xml = cordova_util.projectConfig(projectRoot);
-    var paths = options.platforms.map(function(p) {
-        var platform_path = path.join(projectRoot, 'platforms', p);
-        var parser = (new platforms[p].parser(platform_path));
-        return parser.www_dir();
-    });
-    options.paths = paths;
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_prepare', options)
-    .then(function() {
-        var cfg = new ConfigParser(xml);
-
-        // Iterate over each added platform
-        return Q.all(options.platforms.map(function(platform) {
-            var platformPath = path.join(projectRoot, 'platforms', platform);
-            return lazy_load.based_on_config(projectRoot, platform)
-            .then(function(libDir) {
-                var parser = new platforms[platform].parser(platformPath),
-                    defaults_xml_path = path.join(platformPath, "cordova", "defaults.xml");
-                //If defaults.xml is present, overwrite platform config.xml with it
-                //Otherwise save whatever is there as defaults so it can be restored
-                //or copy project config into platform if none exists
-                if (fs.existsSync(defaults_xml_path)) {
-                    shell.cp("-f", defaults_xml_path, parser.config_xml());
-                    events.emit('verbose', 'Generating config.xml from defaults for platform "' + platform + '"');
-                } else {
-                    if(fs.existsSync(parser.config_xml())){
-                        shell.cp("-f", parser.config_xml(), defaults_xml_path);
-                    }else{
-                        shell.cp("-f",xml,parser.config_xml());
-                    }
-                }
-
-                var stagingPath = path.join(platformPath, '.staging');
-                if (fs.existsSync(stagingPath)) {
-                    events.emit('log', 'Deleting now-obsolete intermediate directory: ' + stagingPath);
-                    shell.rm('-rf', stagingPath);
-                }
-
-                var platform_www = path.join(platformPath, 'platform_www');
-                // Create platfom_www if project was created with older version.
-                if (!fs.existsSync(platform_www)) {
-                    shell.mkdir(platform_www);
-                    shell.cp(parser.cordovajs_path(libDir), path.join(platform_www, 'cordova.js'));
-                }
-
-                // Replace the existing web assets with the app master versions
-                parser.update_www();
-
-                // Call plugman --prepare for this platform. sets up js-modules appropriately.
-                var plugins_dir = path.join(projectRoot, 'plugins');
-                events.emit('verbose', 'Calling plugman.prepare for platform "' + platform + '"');
-                plugman.prepare(platformPath, platform, plugins_dir);
-
-                // Make sure that config changes for each existing plugin is in place
-                var munger = new plugman.config_changes.PlatformMunger(platform, platformPath, plugins_dir);
-                munger.reapply_global_munge();
-                munger.save_all();
-
-                // Update platform config.xml based on top level config.xml
-                var platform_cfg = new ConfigParser(parser.config_xml());
-                exports._mergeXml(cfg.doc.getroot(), platform_cfg.doc.getroot(), platform, true);
-                platform_cfg.write();
-
-                return parser.update_project(cfg);
-            });
-        })).then(function() {
-            return hooks.fire('after_prepare', options);
-        });
-    });
-};
-
-var BLACKLIST = ["platform"];
-var SINGLETONS = ["content", "author"];
-function mergeXml(src, dest, platform, clobber) {
-    if (BLACKLIST.indexOf(src.tag) === -1) {
-        //Handle attributes
-        Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
-            if (clobber || !dest.attrib[attribute]) {
-                dest.attrib[attribute] = src.attrib[attribute];
-            }
-        });
-        //Handle text
-        if (src.text && (clobber || !dest.text)) {
-            dest.text = src.text;
-        }
-        //Handle platform
-        if (platform) {
-            src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
-                platformElement.getchildren().forEach(mergeChild);
-            });
-        }
-
-        //Handle children
-        src.getchildren().forEach(mergeChild);
-
-        function mergeChild (srcChild) {
-            var srcTag = srcChild.tag,
-                destChild = new et.Element(srcTag),
-                foundChild,
-                query = srcTag + "",
-                shouldMerge = true;
-
-            if (BLACKLIST.indexOf(srcTag) === -1) {
-                if (SINGLETONS.indexOf(srcTag) !== -1) {
-                    foundChild = dest.find(query);
-                    if (foundChild) {
-                        destChild = foundChild;
-                        dest.remove(0, destChild);
-                    }
-                } else {
-                    //Check for an exact match and if you find one don't add
-                    Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
-                        query += "[@" + attribute + '="' + srcChild.attrib[attribute] + '"]';
-                    });
-                    foundChild = dest.find(query);
-                    if (foundChild && textMatch(srcChild, foundChild)) {
-                        destChild = foundChild;
-                        dest.remove(0, destChild);
-                        shouldMerge = false;
-                    }
-                }
-
-                mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
-                dest.append(destChild);
-            }
-        }
-
-        function textMatch(elm1, elm2) {
-            var text1 = elm1.text ? elm1.text.replace(/\s+/, "") : "",
-                text2 = elm2.text ? elm2.text.replace(/\s+/, "") : "";
-            return (text1 === "" || text1 === text2);
-        }
-    }
-}
-
-// Expose for testing.
-exports._mergeXml = mergeXml;
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/run.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/run.js b/cordova-lib/src/cordova/run.js
deleted file mode 100644
index 5de3031..0000000
--- a/cordova-lib/src/cordova/run.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-/*global require: true, module: true, process: true*/
-/*jslint sloppy: true, white: true, newcap: true */
-
-var cordova_util      = require('./util'),
-    path              = require('path'),
-    hooker            = require('./hooker'),
-    superspawn        = require('./superspawn'),
-    Q                 = require('q');
-
-// Returns a promise.
-module.exports = function run(options) {
-    var projectRoot = cordova_util.cdProjectRoot(),
-    options = cordova_util.preProcessOptions(options);
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_run', options)
-    .then(function() {
-        // Run a prepare first, then shell out to run
-        return require('../cordova').raw.prepare(options.platforms)
-    }).then(function() {
-        // Deploy in parallel (output gets intermixed though...)
-        return Q.all(options.platforms.map(function(platform) {
-            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'run');
-            return superspawn.spawn(cmd, options.options, { printCommand: true, stdio: 'inherit' });
-        }));
-    }).then(function() {
-        return hooks.fire('after_run', options);
-    });
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/serve.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/serve.js b/cordova-lib/src/cordova/serve.js
deleted file mode 100644
index bd17fa3..0000000
--- a/cordova-lib/src/cordova/serve.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_util = require('./util'),
-    crypto = require('crypto'),
-    path = require('path'),
-    shell = require('shelljs'),
-    platforms     = require('../platforms'),
-    ConfigParser = require('./ConfigParser'),
-    hooker        = require('./hooker'),
-    fs = require('fs'),
-    http = require("http"),
-    url = require("url"),
-    mime = require("mime"),
-    zlib = require("zlib");
-
-function launchServer(projectRoot, port) {
-    var server = http.createServer(function(request, response) {
-        function do404() {
-            console.log('404 ' + request.url);
-            response.writeHead(404, {"Content-Type": "text/plain"});
-            response.write("404 Not Found\n");
-            response.end();
-        }
-        function do302(where) {
-            console.log('302 ' + request.url);
-            response.setHeader("Location", where);
-            response.writeHead(302, {"Content-Type": "text/plain"});
-            response.end();
-        }
-        function doRoot() {
-            response.writeHead(200, {"Content-Type": "text/html"});
-            var config = new ConfigParser(cordova_util.projectConfig(projectRoot));
-            response.write("<html><head><title>"+config.name()+"</title></head><body>");
-            response.write("<table border cellspacing=0><thead><caption><h3>Package Metadata</h3></caption></thead><tbody>");
-            for (var c in {"name": true, "packageName": true, "version": true}) {
-                response.write("<tr><th>"+c+"</th><td>"+config[c]()+"</td></tr>");
-            }
-            response.write("</tbody></table>");
-            response.write("<h3>Platforms</h3><ul>");
-            var installed_platforms = cordova_util.listPlatforms(projectRoot);
-            for (var p in platforms) {
-                if (installed_platforms.indexOf(p) >= 0) {
-                    response.write("<li><a href='"+p+"/'>"+p+"</a></li>\n");
-                } else {
-                    response.write("<li><em>"+p+"</em></li>\n");
-                }
-            }
-            response.write("</ul>");
-            response.write("<h3>Plugins</h3><ul>");
-            var pluginPath = path.join(projectRoot, 'plugins');
-            var plugins = cordova_util.findPlugins(pluginPath);
-            for (var p in plugins) {
-                response.write("<li>"+plugins[p]+"</li>\n");
-            }
-            response.write("</ul>");
-            response.write("</body></html>");
-            response.end();
-        }
-        var urlPath = url.parse(request.url).pathname;
-        var firstSegment = /\/(.*?)\//.exec(urlPath);
-        if (!firstSegment) {
-            return doRoot();
-        }
-        var platformId = firstSegment[1];
-        if (!platforms[platformId]) {
-            return do404();
-        }
-        // Strip the platform out of the path.
-        urlPath = urlPath.slice(platformId.length + 1);
-
-        try {
-            var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
-        } catch (e) {
-            return do404();
-        }
-        var filePath = null;
-
-        if (urlPath == '/config.xml') {
-            filePath = parser.config_xml();
-        } else if (urlPath == '/project.json') {
-            processAddRequest(request, response, platformId, projectRoot);
-            return;
-        } else if (/^\/www\//.test(urlPath)) {
-            filePath = path.join(parser.www_dir(), urlPath.slice(5));
-        } else if (/^\/+[^\/]*$/.test(urlPath)) {
-            return do302("/" + platformId + "/www/");
-        } else {
-            return do404();
-        }
-
-        fs.exists(filePath, function(exists) {
-            if (exists) {
-                if (fs.statSync(filePath).isDirectory()) {
-                    index = path.join(filePath, "index.html");
-                    try {
-                        if (fs.statSync(index)) {
-                            filePath = index;
-                        }
-                    } catch (e) {}
-                }
-                if (fs.statSync(filePath).isDirectory()) {
-                    if (!/\/$/.test(urlPath)) {
-                        return do302("/" + platformId + urlPath + "/");
-                    }
-                    console.log('200 ' + request.url);
-                    response.writeHead(200, {"Content-Type": "text/html"});
-                    response.write("<html><head><title>Directory listing of "+ urlPath + "</title></head>");
-                    response.write("<h3>Items in this directory</h3>");
-                    var items = fs.readdirSync(filePath);
-                    response.write("<ul>");
-                    for (var i in items) {
-                        var file = items[i];
-                        if (file) {
-                            response.write('<li><a href="'+file+'">'+file+'</a></li>\n');
-                        }
-                    }
-                    response.write("</ul>");
-                    response.end();
-                } else {
-                    var mimeType = mime.lookup(filePath);
-                    var respHeaders = {
-                      'Content-Type': mimeType
-                    };
-                    var readStream = fs.createReadStream(filePath);
-
-                    var acceptEncoding = request.headers['accept-encoding'] || '';
-                    if (acceptEncoding.match(/\bgzip\b/)) {
-                        respHeaders['content-encoding'] = 'gzip';
-                        readStream = readStream.pipe(zlib.createGzip());
-                    } else if (acceptEncoding.match(/\bdeflate\b/)) {
-                        respHeaders['content-encoding'] = 'deflate';
-                        readStream = readStream.pipe(zlib.createDeflate());
-                    }
-                    console.log('200 ' + request.url);
-                    response.writeHead(200, respHeaders);
-                    readStream.pipe(response);
-                }
-            } else {
-                return do404();
-            }
-        });
-    }).on('listening', function () {
-        console.log("Static file server running on port " + port + " (i.e. http://localhost:" + port + ")\nCTRL + C to shut down");
-    }).on('error', function (e) {
-        if (e && e.toString().indexOf('EADDRINUSE') !== -1) {
-            port++;
-            server.listen(port);
-        } else {
-            console.log("An error occured starting static file server: " + e);
-        }
-    }).listen(port);
-    return server;
-}
-
-function calculateMd5(fileName) {
-    var BUF_LENGTH = 64*1024,
-        buf = new Buffer(BUF_LENGTH),
-        bytesRead = BUF_LENGTH,
-        pos = 0,
-        fdr = fs.openSync(fileName, 'r');
-
-    try {
-        var md5sum = crypto.createHash('md5');
-        while (bytesRead === BUF_LENGTH) {
-            bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
-            pos += bytesRead;
-            md5sum.update(buf.slice(0, bytesRead));
-        }
-    } finally {
-        fs.closeSync(fdr);
-    }
-    return md5sum.digest('hex');
-}
-
-function processAddRequest(request, response, platformId, projectRoot) {
-    var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
-    var wwwDir = parser.www_dir();
-    var payload = {
-        'configPath': '/' + platformId + '/config.xml',
-        'wwwPath': '/' + platformId + '/www',
-        'wwwFileList': shell.find(wwwDir)
-            .filter(function(a) { return !fs.statSync(a).isDirectory() && !/(^\.)|(\/\.)/.test(a) })
-            .map(function(a) { return {'path': a.slice(wwwDir.length), 'etag': '' + calculateMd5(a)}; })
-    };
-    console.log('200 ' + request.url);
-    response.writeHead(200, {
-        'Content-Type': 'application/json',
-        'Cache-Control': 'no-cache'
-    });
-    response.write(JSON.stringify(payload));
-    response.end();
-}
-
-module.exports = function server(port) {
-    var projectRoot = cordova_util.cdProjectRoot();
-    port = +port || 8000;
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_serve')
-    .then(function() {
-        // Run a prepare first!
-        return require('../cordova').raw.prepare([]);
-    }).then(function() {
-        launchServer(projectRoot, port);
-        return hooks.fire('after_serve');
-    });
-};
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/superspawn.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/superspawn.js b/cordova-lib/src/cordova/superspawn.js
deleted file mode 100644
index 60c9fdc..0000000
--- a/cordova-lib/src/cordova/superspawn.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var child_process = require('child_process');
-var fs = require('fs');
-var path = require('path');
-var _ = require('underscore');
-var Q = require('q');
-var shell = require('shelljs');
-var events = require('./events');
-var iswin32 = process.platform == 'win32';
-
-// On Windows, spawn() for batch files requires absolute path & having the extension.
-function resolveWindowsExe(cmd) {
-    var winExtensions = ['.exe', '.cmd', '.bat', '.js', '.vbs'];
-    function isValidExe(c) {
-        return winExtensions.indexOf(path.extname(c)) !== -1 && fs.existsSync(c);
-    }
-    if (isValidExe(cmd)) {
-        return cmd;
-    }
-    cmd = shell.which(cmd) || cmd;
-    if (!isValidExe(cmd)) {
-        winExtensions.some(function(ext) {
-            if (fs.existsSync(cmd + ext)) {
-                cmd = cmd + ext;
-                return true;
-            }
-        });
-    }
-    return cmd;
-}
-
-function maybeQuote(a) {
-    if (a.indexOf(' ') != -1) {
-        a = '"' + a + '"';
-    }
-    return a;
-}
-
-// opts:
-//   printCommand: Whether to log the command (default: false)
-//   stdio: 'default' is to capture output and returning it as a string to success (same as exec)
-//          'ignore' means don't bother capturing it
-//          'inherit' means pipe the input & output. This is required for anything that prompts.
-//   env: Map of extra environment variables.
-//   cwd: Working directory for the command.
-// Returns a promise that succeeds only for return code = 0.
-exports.spawn = function(cmd, args, opts) {
-    args = args || [];
-    opts = opts || {};
-    var spawnOpts = {};
-    var d = Q.defer();
-
-    if (iswin32) {
-        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' && cmd.indexOf(' ') != -1) {
-            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
-            args = [['/s', '/c', '"'+[cmd].concat(args).map(function(a){if (/^[^"].* .*[^"]/.test(a)) return '"'+a+'"'; return a;}).join(" ")+'"'].join(" ")];
-            cmd = 'cmd';
-            spawnOpts.windowsVerbatimArguments = true;
-        } else if (!fs.existsSync(cmd)) {
-            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
-            args = ['/s', '/c', cmd].concat(args);
-        }
-    }
-
-    if (opts.stdio == 'ignore') {
-        spawnOpts.stdio = 'ignore';
-    } else if (opts.stdio == 'inherit') {
-        spawnOpts.stdio = 'inherit';
-    }
-    if (opts.cwd) {
-        spawnOpts.cwd = opts.cwd;
-    }
-    if (opts.env) {
-        spawnOpts.env = _.extend(_.extend({}, process.env), opts.env);
-    }
-
-    events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' '));
-
-    var child = child_process.spawn(cmd, args, spawnOpts);
-    var capturedOut = '';
-    var capturedErr = '';
-
-    if (child.stdout) {
-        child.stdout.setEncoding('utf8');
-        child.stdout.on('data', function(data) {
-            capturedOut += data;
-        });
-
-        child.stderr.setEncoding('utf8');
-        child.stderr.on('data', function(data) {
-            capturedErr += data;
-        });
-    }
-
-    child.on('close', whenDone);
-    child.on('error', whenDone);
-    function whenDone(arg) {
-        child.removeListener('close', whenDone);
-        child.removeListener('error', whenDone);
-        var code = typeof arg == 'number' ? arg : arg && arg.code;
-
-        events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args);
-        if (code === 0) {
-            d.resolve(capturedOut.trim());
-        } else {
-            var errMsg = cmd + ': Command failed with exit code ' + code;
-            if (capturedErr) {
-                errMsg += ' Error output:\n' + capturedErr.trim();
-            }
-            var err = new Error(errMsg);
-            err.code = code;
-            d.reject(err);
-        }
-    }
-
-    return d.promise;
-};
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/util.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/util.js b/cordova-lib/src/cordova/util.js
deleted file mode 100644
index 2d3b12a..0000000
--- a/cordova-lib/src/cordova/util.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    CordovaError  = require('./CordovaError'),
-    shell         = require('shelljs');
-
-// Global configuration paths
-var HOME = process.env[(process.platform.slice(0, 3) == 'win') ? 'USERPROFILE' : 'HOME'];
-var global_config_path = path.join(HOME, '.cordova');
-var lib_path = path.join(global_config_path, 'lib');
-shell.mkdir('-p', lib_path);
-
-function isRootDir(dir) {
-    if (fs.existsSync(path.join(dir, 'www'))) {
-        if (fs.existsSync(path.join(dir, 'config.xml'))) {
-            // For sure is.
-            if (fs.existsSync(path.join(dir, 'platforms'))) {
-                return 2;
-            } else {
-                return 1;
-            }
-        }
-        // Might be (or may be under platforms/).
-        if (fs.existsSync(path.join(dir, 'www', 'config.xml'))) {
-            return 1;
-        }
-    }
-    return 0;
-}
-
-exports = module.exports = {
-    globalConfig:global_config_path,
-    libDirectory:lib_path,
-    // 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.
-    isCordova: 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) {
-                return this.isCordova(pwd) || this.isCordova(cwd);
-            }
-            return this.isCordova(cwd);
-        }
-        var bestReturnValueSoFar = false;
-        for (var i = 0; i < 1000; ++i) {
-            var result = isRootDir(dir);
-            if (result === 2) {
-                return dir;
-            }
-            if (result === 1) {
-                bestReturnValueSoFar = dir;
-            }
-            var parentDir = path.normalize(path.join(dir, '..'));
-            // Detect fs root.
-            if (parentDir == dir) {
-                return bestReturnValueSoFar;
-            }
-            dir = parentDir;
-        }
-        console.error('Hit an unhandled case in util.isCordova');
-        return false;
-    },
-    // Cd to project root dir and return its path. Throw CordovaError if not in a Corodva project.
-    cdProjectRoot: function() {
-        var projectRoot = this.isCordova();
-        if (!projectRoot) {
-            throw new CordovaError('Current working directory is not a Cordova-based project.');
-        }
-        process.chdir(projectRoot);
-        return projectRoot;
-    },
-    // Recursively deletes .svn folders from a target path
-    deleteSvnFolders:function(dir) {
-        var contents = fs.readdirSync(dir);
-        contents.forEach(function(entry) {
-            var fullpath = path.join(dir, entry);
-            if (fs.statSync(fullpath).isDirectory()) {
-                if (entry == '.svn') {
-                    shell.rm('-rf', fullpath);
-                } else module.exports.deleteSvnFolders(fullpath);
-            }
-        });
-    },
-    listPlatforms:function(project_dir) {
-        var core_platforms = require('../platforms');
-        var platforms_dir = path.join(project_dir, 'platforms');
-        if ( !fs.existsSync(platforms_dir)) {
-            return [];
-        }
-        var subdirs = fs.readdirSync(platforms_dir);
-        return subdirs.filter(function(p) {
-            return Object.keys(core_platforms).indexOf(p) > -1;
-        });
-    },
-    // list the directories in the path, ignoring any files
-    findPlugins:function(pluginPath) {
-        var plugins = [],
-            stats;
-
-        if (fs.existsSync(pluginPath)) {
-            plugins = fs.readdirSync(pluginPath).filter(function (fileName) {
-               stats = fs.statSync(path.join(pluginPath, fileName));
-               return fileName != '.svn' && fileName != 'CVS' && stats.isDirectory();
-            });
-        }
-
-        return plugins;
-    },
-    appDir: function(projectDir) {
-        return projectDir;
-    },
-    projectWww: function(projectDir) {
-        return path.join(projectDir, 'www');
-    },
-    projectConfig: function(projectDir) {
-        var rootPath = path.join(projectDir, 'config.xml');
-        var wwwPath = path.join(projectDir, 'www', 'config.xml');
-        if (fs.existsSync(rootPath)) {
-            return rootPath;
-        } else if (fs.existsSync(wwwPath)) {
-            return wwwPath;
-        }
-        return rootPath;
-    },
-    preProcessOptions: function (inputOptions) {
-        /**
-         * Current Desired Arguments
-         * options: {verbose: boolean, platforms: [String], options: [String]}
-         * Accepted Arguments
-         * platformList: [String] -- assume just a list of platforms
-         * platform: String -- assume this is a platform
-         */
-        var result = inputOptions || {};
-        if (Array.isArray(inputOptions)) {
-            result = { platforms: inputOptions };
-        } else if (typeof inputOptions === 'string') {
-            result = { platforms: [inputOptions] };
-        }
-        result.verbose = result.verbose || false;
-        result.platforms = result.platforms || [];
-        result.options = result.options || [];
-
-        var projectRoot = this.isCordova();
-
-        if (!projectRoot) {
-            throw new CordovaError('Current working directory is not a Cordova-based project.');
-        }
-        var projectPlatforms = this.listPlatforms(projectRoot);
-        if (projectPlatforms.length === 0) {
-            throw new CordovaError('No platforms added to this project. Please use `cordova platform add <platform>`.');
-        }
-        if (result.platforms.length === 0) {
-            result.platforms = projectPlatforms;
-        }
-
-        return result;
-    }
-};
-
-// opt_wrap is a boolean: True means that a callback-based wrapper for the promise-based function
-// should be created.
-function addModuleProperty(module, symbol, modulePath, opt_wrap, opt_obj) {
-    var val = null;
-    if (opt_wrap) {
-        module.exports[symbol] = function() {
-            val = val || module.require(modulePath);
-            if (arguments.length && typeof arguments[arguments.length - 1] === 'function') {
-                // If args exist and the last one is a function, it's the callback.
-                var args = Array.prototype.slice.call(arguments);
-                var cb = args.pop();
-                val.apply(module.exports, args).done(function(result) {cb(undefined, result)}, cb);
-            } else {
-                val.apply(module.exports, arguments).done(null, function(err) { throw err; });
-            }
-        };
-    } else {
-        Object.defineProperty(opt_obj || module.exports, symbol, {
-            get : function() { return val = val || module.require(modulePath); },
-            set : function(v) { val = v; }
-        });
-    }
-
-    // Add the module.raw.foo as well.
-    if(module.exports.raw) {
-        Object.defineProperty(module.exports.raw, symbol, {
-            get : function() { return val = val || module.require(modulePath); },
-            set : function(v) { val = v; }
-        });
-    }
-}
-
-addModuleProperty(module, 'plugin_parser', './plugin_parser');
-
-exports.addModuleProperty = addModuleProperty;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/xml-helpers.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/xml-helpers.js b/cordova-lib/src/cordova/xml-helpers.js
deleted file mode 100644
index 70ec96b..0000000
--- a/cordova-lib/src/cordova/xml-helpers.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- *
- * Copyright 2013 Anis Kadri
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/**
- * contains XML utility functions, some of which are specific to elementtree
- */
-
-var fs = require('fs')
-  , path = require('path')
-  , et = require('elementtree');
-
-module.exports = {
-    // Returns a promise.
-    moveProjFile: function(origFile, projPath) {
-        var src = path.resolve(projPath, origFile)
-          , dest = src.replace('.orig', '');
-
-        var d = Q.defer();
-        fs.createReadStream(src)
-            .pipe(fs.createWriteStream(dest))
-            .on('close', d.resolve)
-            .on('error', d.reject);
-        return d.promise;
-    },
-
-    // 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) {
-            return false;
-        } else if (one.text.trim() != two.text.trim()) {
-            return false;
-        } else if (one._children.length != two._children.length) {
-            return false;
-        }
-
-        var oneAttribKeys = Object.keys(one.attrib),
-            twoAttribKeys = Object.keys(two.attrib),
-            i = 0, attribName;
-
-        if (oneAttribKeys.length != twoAttribKeys.length) {
-            return false;
-        }
-
-        for (i; i < oneAttribKeys.length; i++) {
-            attribName = oneAttribKeys[i];
-
-            if (one.attrib[attribName] != two.attrib[attribName]) {
-                return false;
-            }
-        }
-
-        for (i; i < one._children.length; i++) {
-            if (!module.exports.equalNodes(one._children[i], two._children[i])) {
-                return false;
-            }
-        }
-
-        return true;
-    },
-
-    // adds node to doc at selector
-    graftXML: function(doc, nodes, selector) {
-        var parent = resolveParent(doc, selector);
-        if (!parent) return false;
-
-        nodes.forEach(function (node) {
-            // check if child is unique first
-            if (uniqueChild(node, parent)) {
-                parent.append(node);
-            }
-        });
-
-        return true;
-    },
-
-    // removes node from doc at selector
-    pruneXML: function(doc, nodes, selector) {
-        var parent = resolveParent(doc, selector);
-        if (!parent) return false;
-
-        nodes.forEach(function (node) {
-            var matchingKid = null;
-            if ((matchingKid = findChild(node, parent)) != null) {
-                // stupid elementtree takes an index argument it doesn't use
-                // and does not conform to the python lib
-                parent.remove(0, matchingKid);
-            }
-        });
-
-        return true;
-    },
-
-    parseElementtreeSync: function (filename) {
-        var contents = fs.readFileSync(filename, 'utf-8');
-        if(contents) {
-            contents = contents.substring(contents.indexOf("<")); //Windows is the BOM
-        }
-        return new et.ElementTree(et.XML(contents));
-    }
-};
-
-function findChild(node, parent) {
-    var matchingKids = parent.findall(node.tag)
-      , i, j;
-
-    for (i = 0, j = matchingKids.length ; i < j ; i++) {
-        if (module.exports.equalNodes(node, matchingKids[i])) {
-            return matchingKids[i];
-        }
-    }
-    return null;
-}
-
-function uniqueChild(node, parent) {
-    var matchingKids = parent.findall(node.tag)
-      , i = 0;
-
-    if (matchingKids.length == 0) {
-        return true;
-    } else  {
-        for (i; i < matchingKids.length; i++) {
-            if (module.exports.equalNodes(node, matchingKids[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
-
-var ROOT = /^\/([^\/]*)/,
-    ABSOLUTE = /^\/([^\/]*)\/(.*)/;
-function resolveParent(doc, selector) {
-    var parent, tagName, subSelector;
-
-    // handle absolute selector (which elementtree doesn't like)
-    if (ROOT.test(selector)) {
-        tagName = selector.match(ROOT)[1];
-        // test for wildcard "any-tag" root selector
-        if (tagName == '*' || tagName === doc._root.tag) {
-            parent = doc._root;
-
-            // could be an absolute path, but not selecting the root
-            if (ABSOLUTE.test(selector)) {
-                subSelector = selector.match(ABSOLUTE)[2];
-                parent = parent.find(subSelector)
-            }
-        } else {
-            return false;
-        }
-    } else {
-        parent = doc.find(selector)
-    }
-    return parent;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/templates/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/templates/config.xml b/cordova-lib/templates/config.xml
deleted file mode 100644
index 4a9a4d8..0000000
--- a/cordova-lib/templates/config.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
-        id        = "io.cordova.hellocordova"
-        version   = "0.0.1">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <content src="index.html" />
-
-    <access origin="*" />
-</widget>


[12/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js
new file mode 100755
index 0000000..c064499
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js
@@ -0,0 +1,78 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    fs    = require('fs'),
+    ROOT  = path.join(__dirname, '..', '..');
+
+// Get valid target from framework/project.properties
+module.exports.get_target = function() {
+    if(fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
+        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties'));
+        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+    } else if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
+        // if no target found, we're probably in a project and project.properties is in ROOT.
+        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
+        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+    }
+}
+
+module.exports.check_ant = function() {
+    var test = shell.exec('ant -version', {silent:true, async:false});
+    if(test.code > 0) {
+        console.error('ERROR : executing command \'ant\', make sure you have ant installed and added to your path.');
+        return false;
+    }
+    return true;
+}
+
+module.exports.check_java = function() {
+    if(process.env.JAVA_HOME) {
+        var test = shell.exec('java', {silent:true, async:false});
+        if(test.code > 0) {
+            console.error('ERROR : executing command \'java\', make sure you java environment is set up. Including your JDK and JRE.');
+            return false;
+        }
+        return true;
+    } else {
+        console.error('ERROR : Make sure JAVA_HOME is set, as well as paths to your JDK and JRE for java.');
+        return false;
+    }
+}
+
+module.exports.check_android = function() {
+    var valid_target = this.get_target();
+    var targets = shell.exec('android list targets', {silent:true, async:false});
+
+    if(targets.code > 0 && targets.output.match(/command\snot\sfound/)) {
+        console.error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.');
+        return false;
+    } else if(!targets.output.match(valid_target)) {
+        console.error('Please install Android target ' + valid_target.split('-')[1] + ' (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools.');
+        return false;
+    }
+    return true;
+}
+
+module.exports.run = function() {
+    return this.check_ant() && this.check_java && this.check_android();
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js
new file mode 100755
index 0000000..8f14015
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js
@@ -0,0 +1,43 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Cleans the project using ant
+ */
+module.exports.run = function() {
+    var cmd = 'ant clean -f ' + path.join(ROOT, 'build.xml');
+    var result = shell.exec(cmd, {silent:false, async:false});
+    if (result.code > 0) {
+        console.error('ERROR: Failed to clean android project.');
+        console.error(result.output);
+        process.exit(2);
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'clean')));
+    console.log('Cleans the project directory.');
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js
new file mode 100755
index 0000000..363dc2b
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js
@@ -0,0 +1,95 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    build = require('./build'),
+    appinfo = require('./appinfo'),
+    exec  = require('child_process').exec,
+    ROOT = path.join(__dirname, '..', '..');
+
+/**
+ * Returns a list of the device ID's found
+ */
+module.exports.list = function() {
+    var cmd = 'adb devices';
+    var result = shell.exec(cmd, {silent:true, async:false});
+    if (result.code > 0) {
+        console.error('Failed to execute android command \'' + cmd + '\'.');
+        process.exit(2);
+    } else {
+        var response = result.output.split('\n');
+        var device_list = [];
+        for (var i = 1; i < response.length; i++) {
+            if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
+                device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
+            }
+        }
+        return device_list;
+    }
+}
+
+/*
+ * Installs a previously built application on the device
+ * and launches it.
+ */
+module.exports.install = function(target) {
+    var device_list = this.list();
+    if (device_list.length > 0) {
+        // default device
+        target = typeof target !== 'undefined' ? target : device_list[0];
+        if (device_list.indexOf(target) > -1) {
+            var apk_path = build.get_apk();
+            var launchName = appinfo.getActivityName();
+            console.log('Installing app on device...');
+            cmd = 'adb -s ' + target + ' install -r ' + apk_path;
+            var install = shell.exec(cmd, {silent:false, async:false});
+            if (install.error || install.output.match(/Failure/)) {
+                console.error('ERROR : Failed to install apk to device : ');
+                console.error(install.output);
+                process.exit(2);
+            }
+
+            //unlock screen
+            cmd = 'adb -s ' + target + ' shell input keyevent 82';
+            shell.exec(cmd, {silent:true, async:false});
+
+            // launch the application
+            console.log('Launching application...');
+            cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
+            var launch = shell.exec(cmd, {silent:true, async:false});
+            if(launch.code > 0) {
+                console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
+                console.error(launch.output);
+                process.exit(2);
+            } else {
+                console.log('LAUNCH SUCCESS');
+            }
+        } else {
+            console.error('ERROR : Unable to find target \'' + target + '\'.');
+            console.error('Failed to deploy to device.');
+            process.exit(2);
+        }
+    } else {
+        console.error('ERROR : Failed to deploy to device, no devices found.');
+        process.exit(2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js
new file mode 100755
index 0000000..cc658a9
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js
@@ -0,0 +1,337 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    appinfo = require('./appinfo'),
+    build = require('./build'),
+    ROOT  = path.join(__dirname, '..', '..'),
+    new_emulator = 'cordova_emulator';
+
+/**
+ * Returns a list of emulator images in the form of objects
+ * {
+       name   : <emulator_name>,
+       path   : <path_to_emulator_image>,
+       target : <api_target>,
+       abi    : <cpu>,
+       skin   : <skin>
+   }
+ */
+module.exports.list_images = function() {
+    var cmd = 'android list avds';
+    var result = shell.exec(cmd, {silent:true, async:false});
+    if (result.code > 0) {
+        console.error('Failed to execute android command \'' + cmd + '\'.');
+        process.exit(2);
+    } else {
+        var response = result.output.split('\n');
+        var emulator_list = [];
+        for (var i = 1; i < response.length; i++) {
+            // To return more detailed information use img_obj
+            var img_obj = {};
+            if (response[i].match(/Name:\s/)) {
+                img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
+                if (response[i + 1].match(/Path:\s/)) {
+                    i++;
+                    img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
+                }
+                if (response[i + 1].match(/\(API\slevel\s/)) {
+                    i++;
+                    img_obj['target'] = response[i].replace('\r', '');
+                }
+                if (response[i + 1].match(/ABI:\s/)) {
+                    i++;
+                    img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
+                }
+                if (response[i + 1].match(/Skin:\s/)) {
+                    i++;
+                    img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
+                }
+
+                emulator_list.push(img_obj);
+            }
+            /* To just return a list of names use this
+            if (response[i].match(/Name:\s/)) {
+                emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
+            }*/
+
+        }
+        return emulator_list;
+    }
+}
+
+/**
+ * Will return the closest avd to the projects target
+ * or undefined if no avds exist.
+ */
+module.exports.best_image = function() {
+    var project_target = this.get_target().replace('android-', '');
+    var images = this.list_images();
+    var closest = 9999;
+    var best = images[0];
+    for (i in images) {
+        var target = images[i].target;
+        if(target) {
+            var num = target.split('(API level ')[1].replace(')', '');
+            if (num == project_target) {
+                return images[i];
+            } else if (project_target - num < closest && project_target > num) {
+                var closest = project_target - num;
+                best = images[i];
+            }
+        }
+    }
+    return best;
+}
+
+module.exports.list_started = function() {
+    var cmd = 'adb devices';
+    var result = shell.exec(cmd, {silent:true, async:false});
+    if (result.code > 0) {
+        console.error('Failed to execute android command \'' + cmd + '\'.');
+        process.exit(2);
+    } else {
+        var response = result.output.split('\n');
+        var started_emulator_list = [];
+        for (var i = 1; i < response.length; i++) {
+            if (response[i].match(/device/) && response[i].match(/emulator/)) {
+                started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
+            }
+        }
+        return started_emulator_list;
+    }
+}
+
+module.exports.get_target = function() {
+    var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
+    return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+}
+
+module.exports.list_targets = function() {
+    var target_out = shell.exec('android list targets', {silent:true, async:false}).output.split('\n');
+    var targets = [];
+    for (var i = target_out.length; i >= 0; i--) {
+        if(target_out[i].match(/id:/)) {
+            targets.push(targets[i].split(' ')[1]);
+        }
+    }
+    return targets;
+}
+
+/*
+ * Starts an emulator with the given ID,
+ * and returns the started ID of that emulator.
+ * If no ID is given it will used the first image availible,
+ * if no image is availible it will error out (maybe create one?).
+ */
+module.exports.start = function(emulator_ID) {
+    var started_emulators = this.list_started();
+    var num_started = started_emulators.length;
+    if (typeof emulator_ID === 'undefined') {
+        var emulator_list = this.list_images();
+        if (emulator_list.length > 0) {
+            emulator_ID = this.best_image().name;
+            console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID);
+        } else {
+            console.error('ERROR : No emulator images (avds) found, if you would like to create an');
+            console.error(' avd follow the instructions provided here : ');
+            console.error(' http://developer.android.com/tools/devices/index.html')
+            console.error(' Or run \'android create avd --name <name> --target <targetID>\' ');
+            console.error(' in on the command line.');
+            process.exit(2);
+            /*console.log('WARNING : no emulators availible, creating \'' + new_emulator + '\'.');
+            this.create_image(new_emulator, this.get_target());
+            emulator_ID = new_emulator;*/
+        }
+    }
+
+    var pipe_null = (process.platform == 'win32' || process.platform == 'win64'? '> NUL' : '> /dev/null');
+    var cmd = 'emulator -avd ' + emulator_ID + ' ' + pipe_null + ' &';
+    if(process.platform == 'win32' || process.platform == 'win64') {
+        cmd = '%comspec% /c start cmd /c ' + cmd;
+    }
+    var result = shell.exec(cmd, {silent:true, async:false}, function(code, output) {
+        if (code > 0) {
+            console.error('Failed to execute android command \'' + cmd + '\'.');
+            console.error(output);
+            process.exit(2);
+        }
+    });
+
+    // wait for emulator to start
+    console.log('Waiting for emulator...');
+    var new_started = this.wait_for_emulator(num_started);
+    var emulator_id;
+    if (new_started.length > 1) {
+        for (i in new_started) {
+            console.log(new_started[i]);
+            console.log(started_emulators.indexOf(new_started[i]));
+            if (started_emulators.indexOf(new_started[i]) < 0) {
+                emulator_id = new_started[i];
+            }
+        }
+    } else {
+        emulator_id = new_started[0];
+    }
+    if (!emulator_id) {
+        console.error('ERROR :  Failed to start emulator, could not find new emulator');
+        process.exit(2);
+    }
+
+    //wait for emulator to boot up
+    process.stdout.write('Booting up emulator (this may take a while)...');
+    this.wait_for_boot(emulator_id);
+    console.log('BOOT COMPLETE');
+
+    //unlock screen
+    cmd = 'adb -s ' + emulator_id + ' shell input keyevent 82';
+    shell.exec(cmd, {silent:false, async:false});
+
+    //return the new emulator id for the started emulators
+    return emulator_id;
+}
+
+/*
+ * Waits for the new emulator to apear on the started-emulator list.
+ */
+module.exports.wait_for_emulator = function(num_running) {
+    var new_started = this.list_started();
+    if (new_started.length > num_running) {
+        return new_started;
+    } else {
+        this.sleep(1);
+        return this.wait_for_emulator(num_running);
+    }
+}
+
+/*
+ * Waits for the boot animation property of the emulator to switch to 'stopped'
+ */
+module.exports.wait_for_boot = function(emulator_id) {
+    var cmd;
+    // ShellJS opens a lot of file handles, and the default on OS X is too small.
+    // TODO : This is not working, need to find a better way to increese the ulimit.
+    if(process.platform == 'win32' || process.platform == 'win64') {
+        cmd = 'adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
+    } else {
+        cmd = 'ulimit -S -n 4096; adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
+    }
+    var boot_anim = shell.exec(cmd, {silent:true, async:false});
+    if (boot_anim.output.match(/stopped/)) {
+        return;
+    } else {
+        process.stdout.write('.');
+        this.sleep(3);
+        return this.wait_for_boot(emulator_id);
+    }
+}
+
+/*
+ * TODO : find a better way to wait for the emulator (maybe using async methods?)
+ */
+module.exports.sleep = function(time_sec) {
+    if (process.platform == 'win32' || process.platform == 'win64') {
+        shell.exec('ping 127.0.0.1 -n ' + time_sec, {silent:true, async:false});
+    } else {
+        shell.exec('sleep ' + time_sec, {silent:true, async:false});
+    }
+}
+
+/*
+ * Create avd
+ * TODO : Enter the stdin input required to complete the creation of an avd.
+ */
+module.exports.create_image = function(name, target) {
+    console.log('Creating avd named ' + name);
+    if (target) {
+        var cmd = 'android create avd --name ' + name + ' --target ' + target;
+        var create = shell.exec(cmd, {sient:false, async:false});
+        if (create.error) {
+            console.error('ERROR : Failed to create emulator image : ');
+            console.error(' Do you have the latest android targets including ' + target + '?');
+            console.error(create.output);
+            process.exit(2);
+        }
+    } else {
+        console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
+        var cmd = 'android create avd --name ' + name + ' --target ' + this.list_targets()[0];
+        var create = shell.exec(cmd, {sient:false, async:false});
+        if (create.error) {
+            console.error('ERROR : Failed to create emulator image : ');
+            console.error(create.output);
+            process.exit(2);
+        }
+        console.error('ERROR : Unable to create an avd emulator, no targets found.');
+        console.error('Please insure you have targets availible by runing the "android" command').
+        process.exit(2);
+    }
+}
+
+/*
+ * Installs a previously built application on the emulator and launches it.
+ * If no target is specified, then it picks one.
+ * If no started emulators are found, error out.
+ */
+module.exports.install = function(target) {
+    var emulator_list = this.list_started();
+    if (emulator_list.length < 1) {
+        console.error('ERROR : No started emulators found, please start an emultor before deploying your project.');
+        process.exit(2);
+        /*console.log('WARNING : No started emulators found, attemting to start an avd...');
+        this.start(this.best_image().name);*/
+    }
+    // default emulator
+    target = typeof target !== 'undefined' ? target : emulator_list[0];
+    if (emulator_list.indexOf(target) > -1) {
+        console.log('Installing app on emulator...');
+        var apk_path = build.get_apk();
+        var cmd = 'adb -s ' + target + ' install -r ' + apk_path;
+        var install = shell.exec(cmd, {sient:false, async:false});
+        if (install.error || install.output.match(/Failure/)) {
+            console.error('ERROR : Failed to install apk to emulator : ');
+            console.error(install.output);
+            process.exit(2);
+        }
+
+        //unlock screen
+        cmd = 'adb -s ' + target + ' shell input keyevent 82';
+        shell.exec(cmd, {silent:true, async:false});
+
+        // launch the application
+        console.log('Launching application...');
+        var launchName = appinfo.getActivityName();
+        cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
+        console.log(cmd);
+        var launch = shell.exec(cmd, {silent:false, async:false});
+        if(launch.code > 0) {
+            console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
+            console.error(launch.output);
+            process.exit(2);
+        } else {
+            console.log('LAUNCH SUCCESS');
+        }
+    } else {
+        console.error('ERROR : Unable to find target \'' + target + '\'.');
+        console.error('Failed to deploy to emulator.');
+        process.exit(2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device
new file mode 100755
index 0000000..679efbf
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var device = require('./device'),
+    args   = process.argv;
+
+if(args.length > 2) {
+    var install_target;
+    if (args[2].substring(0, 9) == '--target=') {
+        install_target = args[2].substring(9, args[2].length);
+        device.install(install_target);
+        process.exit(0);
+     } else {
+        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+        process.exit(2);
+     }
+} else {
+    device.install();
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator
new file mode 100755
index 0000000..c006eb2
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulator = require('./emulator'),
+    args     = process.argv;
+
+if(args.length > 2) {
+    var install_target;
+    if (args[2].substring(0, 9) == '--target=') {
+        install_target = args[2].substring(9, args[2].length);
+        emulator.install(install_target);
+        process.exit(0);
+     } else {
+        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+        process.exit(2);
+     }
+} else {
+    emulator.install();
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices
new file mode 100755
index 0000000..3ef4efa
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices
@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var devices = require('./device');
+
+// Usage support for when args are given
+var device_list = devices.list();
+for(device in device_list) {
+    console.log(device_list[device]);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images
new file mode 100755
index 0000000..3230537
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images
@@ -0,0 +1,29 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulators = require('./emulator');
+
+// Usage support for when args are given
+var emulator_list = emulators.list_images();
+for(emulator in emulator_list) {
+    console.log(emulator_list[emulator].name);
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators
new file mode 100755
index 0000000..525a64c
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators
@@ -0,0 +1,29 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulators = require('./emulator');
+
+// Usage support for when args are given
+var emulator_list = emulators.list_started();
+for(emulator in emulator_list) {
+    console.log(emulator_list[emulator]);
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js
new file mode 100755
index 0000000..b85cf60
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js
@@ -0,0 +1,43 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Starts running logcat in the shell.
+ */
+module.exports.run = function() {
+    var cmd = 'adb logcat | grep -v nativeGetEnabledTags';
+    var result = shell.exec(cmd, {silent:false, async:false});
+    if (result.code > 0) {
+        console.error('ERROR: Failed to run logcat command.');
+        console.error(result.output);
+        process.exit(2);
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'log')));
+    console.log('Gives the logcat output on the command line.');
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js
new file mode 100755
index 0000000..787d123
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js
@@ -0,0 +1,124 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var path  = require('path'),
+    build = require('./build'),
+    emulator = require('./emulator'),
+    device   = require('./device'),
+    ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Runs the application on a device if availible.
+ * If not device is found, it will use a started emulator.
+ * If no started emulators are found it will attempt to start an avd.
+ * If no avds are found it will error out.
+ */
+ module.exports.run = function(args) {
+    var build_type;
+    var install_target;
+
+    for (var i=2; i<args.length; i++) {
+        if (args[i] == '--debug') {
+            build_type = '--debug';
+        } else if (args[i] == '--release') {
+            build_type = '--release';
+        } else if (args[i] == '--nobuild') {
+            build_type = '--nobuild';
+        } else if (args[i] == '--device') {
+            install_target = '--device';
+        } else if (args[i] == '--emulator') {
+            install_target = '--emulator';
+        } else if (args[i].substring(0, 9) == '--target=') {
+            install_target = args[i].substring(9, args[i].length);
+        } else {
+            console.error('ERROR : Run option \'' + args[i] + '\' not recognized.');
+            process.exit(2);
+        }
+    }
+    build.run(build_type);
+    if (install_target == '--device') {
+        device.install();
+    } else if (install_target == '--emulator') {
+        if (emulator.list_started() == 0) {
+            emulator.start();
+        }
+        emulator.install();
+    } else if (install_target) {
+        var devices = device.list();
+        var started_emulators = emulator.list_started();
+        var avds = emulator.list_images();
+        if (devices.indexOf(install_target) > -1) {
+            device.install(install_target);
+        } else if (started_emulators.indexOf(install_target) > -1) {
+            emulator.install(install_target);
+        } else {
+            // if target emulator isn't started, then start it.
+            var emulator_ID;
+            for(avd in avds) {
+                if(avds[avd].name == install_target) {
+                    emulator_ID = emulator.start(install_target);
+                    emulator.install(emulator_ID);
+                    break;
+                }
+            }
+            if(!emulator_ID) {
+                console.error('ERROR : Target \'' + install_target + '\' not found, unalbe to run project');
+                process.exit(2);
+            }
+        }
+    } else {
+        // no target given, deploy to device if availible, otherwise use the emulator.
+        var device_list = device.list();
+        if (device_list.length > 0) {
+            console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.');
+            device.install(device_list[0])
+        } else {
+            var emulator_list = emulator.list_started();
+            if (emulator_list.length > 0) {
+                console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.');
+                emulator.install(emulator_list[0]);
+            } else {
+                console.log('WARNING : No started emulators found, starting an emulator.');
+                var best_avd = emulator.best_image();
+                if(best_avd) {
+                    var emulator_ID = emulator.start(best_avd.name);
+                    console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.');
+                    emulator.install(emulator_ID);
+                } else {
+                    emulator.start();
+                }
+            }
+        }
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'run')) + ' [options]');
+    console.log('Build options :');
+    console.log('    --debug : Builds project in debug mode');
+    console.log('    --release : Builds project in release mode');
+    console.log('    --nobuild : Runs the currently built project without recompiling');
+    console.log('Deploy options :');
+    console.log('    --device : Will deploy the built project to a device');
+    console.log('    --emulator : Will deploy the built project to an emulator if one exists');
+    console.log('    --target=<target_id> : Installs to the target with the specified id.');
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator
new file mode 100755
index 0000000..5d6c4dd
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulator = require('./emulator'),
+      args   = process.argv;
+
+if(args.length > 2) {
+    var install_target;
+    if (args[2].substring(0, 9) == '--target=') {
+        install_target = args[2].substring(9, args[2].length);
+        emulator.start(install_target);
+        process.exit(0);
+     } else {
+        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+        process.exit(2);
+     }
+} else {
+    emulator.start();
+    process.exit(0);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log
new file mode 100755
index 0000000..087325f
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log
@@ -0,0 +1,33 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var log  = require('./lib/log'),
+    reqs = require('./lib/check_reqs'),
+    args = process.argv;
+
+// Usage support for when args are given
+if(args.length > 2) {
+    log.help();
+} else if(reqs.run()) {
+    log.run();
+} else {
+    process.exit(2);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run
new file mode 100755
index 0000000..57d7345
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run
@@ -0,0 +1,35 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var run  = require('./lib/run'),
+    reqs = require('./lib/check_reqs'),
+    args = process.argv;
+
+// Support basic help commands
+if (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
+                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
+    run.help();
+} else if(reqs.run()) {
+    run.run(args);
+    process.exit(0);
+} else {
+    process.exit(2);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version
new file mode 100755
index 0000000..de1a76d
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version
@@ -0,0 +1,25 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+// Coho updates this line:
+var VERSION = "3.1.0";
+
+console.log(VERSION);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties b/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties
new file mode 100644
index 0000000..d3f5072
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties
@@ -0,0 +1,10 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+
+# location of the SDK. This is only used by Ant
+# For customization when using a Version Control System, please read the
+# header note.
+sdk.dir=/Users/braden/cordova/android/android-sdk-macosx

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt b/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties b/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties
new file mode 100644
index 0000000..a3ee5ab
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-17

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..4d27634
Binary files /dev/null and b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..cd5032a
Binary files /dev/null and b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..e79c606
Binary files /dev/null and b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png
new file mode 100644
index 0000000..ec7ffbf
Binary files /dev/null and b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png
new file mode 100644
index 0000000..ec7ffbf
Binary files /dev/null and b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml
new file mode 100644
index 0000000..1e706b3
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='utf-8'?>
+<resources>
+    <string name="app_name">TestBase</string>
+</resources>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml
new file mode 100644
index 0000000..17ca237
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+    <name>Hello Cordova</name>
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+    <access origin="*" />
+    <preference name="loglevel" value="DEBUG" />
+    <feature name="App">
+        <param name="android-package" value="org.apache.cordova.App" />
+    </feature>
+    <author email="dev@cordova.apache.org" href="http://cordova.io">
+        Apache Cordova Team
+    </author>
+    <content src="index.html" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java b/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java
new file mode 100644
index 0000000..928e074
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java
@@ -0,0 +1,37 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+ */
+
+package org.testing;
+
+import android.os.Bundle;
+import org.apache.cordova.*;
+
+public class TestBase extends CordovaActivity 
+{
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        super.init();
+        // Set by <content src="index.html" /> in config.xml
+        super.loadUrl(Config.getStartUrl());
+        //super.loadUrl("file:///android_asset/www/index.html")
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml
new file mode 100644
index 0000000..512c02f
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2013 Anis Kadri
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    id="com.phonegap.plugins.childbrowser"
+    version="0.6.0">
+
+    <name>Child Browser</name>
+
+    <asset src="www/childbrowser" target="childbrowser" />
+    <asset src="www/childbrowser_file.html" target="childbrowser_file.html" />
+
+    <js-module src="www/childbrowser.js" name="ChildBrowser">
+        <clobbers target="childbrowser" />
+    </js-module>
+
+    <config-file target="config.xml" parent="/*">
+        <access origin="build.phonegap.com" />
+        <access origin="s3.amazonaws.com" />
+    </config-file>
+    
+    <info>No matter what platform you are installing to, this notice is very important.</info>
+
+    <!-- android -->
+    <platform name="android">
+        <config-file target="AndroidManifest.xml" parent="/manifest/application">
+            <activity android:name="com.phonegap.plugins.childBrowser.ChildBrowser"
+                      android:label="@string/app_name">
+                <intent-filter>
+                </intent-filter>
+            </activity>
+        </config-file>
+
+        <!-- CDV < 2.0 -->
+        <config-file target="res/xml/plugins.xml" parent="/plugins">
+            <plugin name="ChildBrowser"
+                value="com.phonegap.plugins.childBrowser.ChildBrowser"/>
+        </config-file>
+
+        <!-- CDV 2.0+ (for now) -->
+        <config-file target="res/xml/config.xml" parent="/cordova/plugins">
+            <plugin name="ChildBrowser"
+                value="com.phonegap.plugins.childBrowser.ChildBrowser"/>
+        </config-file>
+
+        <source-file src="src/android/ChildBrowser.java"
+                target-dir="src/com/phonegap/plugins/childBrowser" />
+        <info>Please make sure you read this because it is very important to complete the installation of your plugin.</info>
+    </platform>
+
+    <!-- ios -->
+    <platform name="ios">
+        <plugins-plist key="com.phonegap.plugins.childbrowser"
+            string="ChildBrowserCommand" />
+
+        <config-file target="config.xml" parent="/widget/plugins">
+            <plugin name="ChildBrowser"
+                value="ChildBrowserCommand" />
+        </config-file>
+
+        <resource-file src="src/ios/ChildBrowser.bundle" />
+        <resource-file src="src/ios/ChildBrowserViewController.xib" />
+
+        <config-file target="*-Info.plist" parent="AppId">
+            <string>$APP_ID</string>
+        </config-file>
+        
+        <config-file target="*-Info.plist" parent="CFBundleURLTypes">
+            <array>
+              <dict>
+                <key>PackageName</key>
+                <string>$PACKAGE_NAME</string>
+              </dict>
+            </array>
+        </config-file>
+
+        <header-file src="src/ios/ChildBrowserCommand.h" />
+        <header-file src="src/ios/ChildBrowserViewController.h" />
+        <header-file src="src/ios/TargetDirTest.h" target-dir="targetDir"/>
+
+        <source-file src="src/ios/ChildBrowserCommand.m" />
+        <source-file src="src/ios/ChildBrowserViewController.m" />
+        <source-file src="src/ios/preserveDirs/PreserveDirsTest.m" preserve-dirs="true" />
+        <header-file src="src/ios/TargetDirTest.m" target-dir="targetDir"/>
+
+        <!-- framework for testing (not actual dependency of ChildBrowser -->
+        <framework src="libsqlite3.dylib" />
+        <framework src="social.framework" weak="true" />
+        <framework src="music.framework" weak="rabbit" />
+    </platform>
+    <!-- wp7 -->
+    <platform name="wp7">
+        <resource-file src="src\wp7\Images\appbar.back.rest.png" />
+        <config-file target="config.xml" parent="/widget/plugins">
+            <plugin name="ChildBrowser"
+                value="ChildBrowser"/>
+        </config-file>
+
+        <source-file src="src\wp7\ChildBrowserCommand.cs"
+                     target-dir="Plugins\" />
+
+        <!-- modify the project file to include the added files -->
+        <config-file target=".csproj" parent=".">  
+        </config-file> 
+
+    </platform>
+
+    <!-- wp8 -->
+    <platform name="wp8">
+        <resource-file src="src\wp7\Images\appbar.back.rest.png" />
+        <config-file target="config.xml" parent="/widget/plugins">
+            <plugin name="ChildBrowser"
+                value="ChildBrowser"/>
+        </config-file>
+
+        <source-file src="src\wp7\ChildBrowserCommand.cs"
+                     target-dir="Plugins\" />
+
+        <!-- modify the project file to include the added files -->
+        <config-file target=".csproj" parent=".">  
+        </config-file> 
+
+    </platform>
+</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
new file mode 100644
index 0000000..5263b0c
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
@@ -0,0 +1,19 @@
+/*
+ *
+ * Copyright 2013 Anis Kadri
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js
new file mode 100644
index 0000000..5263b0c
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js
@@ -0,0 +1,19 @@
+/*
+ *
+ * Copyright 2013 Anis Kadri
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
@@ -0,0 +1 @@
+foo

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
new file mode 100644
index 0000000..6de7b8c
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
@@ -0,0 +1 @@
+This is a test file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml b/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml
new file mode 100644
index 0000000..d8f5619
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    id="ca.filmaj.AndroidPlugin"
+    version="4.2.0">
+
+    <name>Android Plugin</name>
+
+    <asset src="www/android.js" target="android.js" />
+    <platform name="android">
+    </platform>
+</plugin>
+
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/Android.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/Android.java b/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/Android.java
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java b/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java
new file mode 100644
index 0000000..c3af060
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java
@@ -0,0 +1,6 @@
+import com.yourapp.R;
+
+import android.app.*;
+
+public class SomethingWithR {
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/android/www/android.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/www/android.js b/cordova-lib/spec-cordova/fixtures/plugins/android/www/android.js
new file mode 100644
index 0000000..e69de29

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

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml b/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml
new file mode 100644
index 0000000..774eda1
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    id="com.phonegap.plugins.childbrowser"
+    version="3.0.0">
+
+    <name>Test Plugin</name>
+
+    <asset src="www/test.js" target="test.js" />
+    <platform name="ios">
+        <plugins-plist key="TestPlugin" string="Test" />
+    </platform>
+</plugin>
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/plugins/test/www/test.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/test/www/test.js b/cordova-lib/spec-cordova/fixtures/plugins/test/www/test.js
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml b/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml
new file mode 100644
index 0000000..0c52803
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Copyright 2013 Anis Kadri
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
+      package="com.alunny.childapp" android:versionName="1.1" android:versionCode="5">
+    <supports-screens
+    	android:largeScreens="true"
+    	android:normalScreens="true"
+    	android:smallScreens="true"
+    	android:xlargeScreens="true"
+    	android:resizeable="true"
+    	android:anyDensity="true"
+    	/>
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />   
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />   
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+
+    <uses-feature android:name="android.hardware.camera" />
+    <uses-feature android:name="android.hardware.camera.autofocus" />
+
+    <application android:icon="@drawable/icon" android:label="@string/app_name"
+    	android:debuggable="true">
+		<activity android:name="ChildApp" android:label="@string/app_name" 
+				  android:configChanges="orientation|keyboardHidden">
+			<intent-filter>
+				<action android:name="android.intent.action.MAIN" />
+				<category android:name="android.intent.category.LAUNCHER" />
+			</intent-filter>
+        </activity>
+        <activity android:name="com.phonegap.DroidGap" android:label="@string/app_name" 
+            	  android:configChanges="orientation|keyboardHidden">
+        	<intent-filter>
+        	</intent-filter>
+        </activity>
+    </application>
+
+	<uses-sdk android:minSdkVersion="5" />
+</manifest> 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/projects/android/assets/www/.gitkeep
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/assets/www/.gitkeep b/cordova-lib/spec-cordova/fixtures/projects/android/assets/www/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml b/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml
new file mode 100644
index 0000000..d37aba5
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-->
+<cordova>
+    <!--
+    access elements control the Android whitelist.
+    Domains are assumed blocked unless set otherwise
+     -->
+
+    <access origin="http://127.0.0.1*"/> <!-- allow local pages -->
+
+    <!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
+    <!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
+    <!-- <access origin=".*"/> Allow all domains, suggested development use only -->
+
+    <log level="DEBUG"/>
+    <preference name="useBrowserHistory" value="false" />
+<plugins>
+    <plugin name="App" value="org.apache.cordova.App"/>
+    <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
+    <plugin name="Device" value="org.apache.cordova.Device"/>
+    <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
+    <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
+    <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
+    <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
+    <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
+    <plugin name="File" value="org.apache.cordova.FileUtils"/>
+    <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
+    <plugin name="Notification" value="org.apache.cordova.Notification"/>
+    <plugin name="Storage" value="org.apache.cordova.Storage"/>
+    <plugin name="Temperature" value="org.apache.cordova.TempListener"/>
+    <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
+    <plugin name="Capture" value="org.apache.cordova.Capture"/>
+    <plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
+    <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
+</plugins>
+</cordova>
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/projects/android/src/.gitkeep
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/src/.gitkeep b/cordova-lib/spec-cordova/fixtures/projects/android/src/.gitkeep
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml b/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml
new file mode 100644
index 0000000..57cadf6
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+<widget>
+    <access origin="*"/>
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml b/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml
new file mode 100644
index 0000000..7c4ef3d
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns     = "http://www.w3.org/ns/widgets"
+        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
+        id        = "io.cordova.hellocordova"
+        version   = "0.0.1">
+    <name>Hello Cordova</name>
+
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+
+    <author href="http://cordova.io" email="dev@cordova.apache.org">
+        Apache Cordova Team
+    </author>
+
+    <access origin="*" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/helper.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/helper.js b/cordova-lib/spec-cordova/helper.js
new file mode 100644
index 0000000..351e6e4
--- /dev/null
+++ b/cordova-lib/spec-cordova/helper.js
@@ -0,0 +1,19 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/helpers.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/helpers.js b/cordova-lib/spec-cordova/helpers.js
new file mode 100644
index 0000000..3236516
--- /dev/null
+++ b/cordova-lib/spec-cordova/helpers.js
@@ -0,0 +1,46 @@
+
+var path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    os = require('os');
+
+module.exports.tmpDir = function(subdir) {
+    var dir = path.join(os.tmpdir(), 'e2e-test');
+    if (subdir) {
+        dir = path.join(dir, subdir);
+    }
+    shell.mkdir('-p', dir);
+    return dir;
+};
+
+// Returns the platform that should be used for testing on this host platform.
+/*
+var host = os.platform();
+if (host.match(/win/)) {
+    module.exports.testPlatform = 'wp8';
+} else if (host.match(/darwin/)) {
+    module.exports.testPlatform = 'ios';
+} else {
+    module.exports.testPlatform = 'android';
+}
+*/
+
+// Just use Android everywhere; we're mocking out any calls to the `android` binary.
+module.exports.testPlatform = 'android';
+
+// Add the toExist matcher.
+beforeEach(function() {
+    this.addMatchers({
+        'toExist': function() {
+            var notText = this.isNot ? ' not' : '';
+            var self = this;
+
+            this.message = function() {
+                return 'Expected file ' + self.actual + notText + ' to exist.';
+            };
+
+            return fs.existsSync(this.actual);
+        }
+    });
+});
+


[06/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/cordova.js b/spec/fixtures/platforms/android/assets/www/cordova.js
deleted file mode 100644
index 07e3feb..0000000
--- a/spec/fixtures/platforms/android/assets/www/cordova.js
+++ /dev/null
@@ -1,1712 +0,0 @@
-// Platform: android
-// 3.1.0
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
-     http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-;(function() {
-var CORDOVA_JS_BUILD_LABEL = '3.1.0';
-// file: lib/scripts/require.js
-
-var require,
-    define;
-
-(function () {
-    var modules = {},
-    // Stack of moduleIds currently being built.
-        requireStack = [],
-    // Map of module ID -> index into requireStack of modules currently being built.
-        inProgressModules = {},
-        SEPERATOR = ".";
-
-
-
-    function build(module) {
-        var factory = module.factory,
-            localRequire = function (id) {
-                var resultantId = id;
-                //Its a relative path, so lop off the last portion and add the id (minus "./")
-                if (id.charAt(0) === ".") {
-                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
-                }
-                return require(resultantId);
-            };
-        module.exports = {};
-        delete module.factory;
-        factory(localRequire, module.exports, module);
-        return module.exports;
-    }
-
-    require = function (id) {
-        if (!modules[id]) {
-            throw "module " + id + " not found";
-        } else if (id in inProgressModules) {
-            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
-            throw "Cycle in require graph: " + cycle;
-        }
-        if (modules[id].factory) {
-            try {
-                inProgressModules[id] = requireStack.length;
-                requireStack.push(id);
-                return build(modules[id]);
-            } finally {
-                delete inProgressModules[id];
-                requireStack.pop();
-            }
-        }
-        return modules[id].exports;
-    };
-
-    define = function (id, factory) {
-        if (modules[id]) {
-            throw "module " + id + " already defined";
-        }
-
-        modules[id] = {
-            id: id,
-            factory: factory
-        };
-    };
-
-    define.remove = function (id) {
-        delete modules[id];
-    };
-
-    define.moduleMap = modules;
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
-    module.exports.require = require;
-    module.exports.define = define;
-}
-
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-
-
-var channel = require('cordova/channel');
-var platform = require('cordova/platform');
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
-    windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof documentEventHandlers[e] != 'undefined') {
-        documentEventHandlers[e].subscribe(handler);
-    } else {
-        m_document_addEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof windowEventHandlers[e] != 'undefined') {
-        windowEventHandlers[e].subscribe(handler);
-    } else {
-        m_window_addEventListener.call(window, evt, handler, capture);
-    }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof documentEventHandlers[e] != "undefined") {
-        documentEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_document_removeEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof windowEventHandlers[e] != "undefined") {
-        windowEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_window_removeEventListener.call(window, evt, handler, capture);
-    }
-};
-
-function createEvent(type, data) {
-    var event = document.createEvent('Events');
-    event.initEvent(type, false, false);
-    if (data) {
-        for (var i in data) {
-            if (data.hasOwnProperty(i)) {
-                event[i] = data[i];
-            }
-        }
-    }
-    return event;
-}
-
-
-var cordova = {
-    define:define,
-    require:require,
-    version:CORDOVA_JS_BUILD_LABEL,
-    platformId:platform.id,
-    /**
-     * Methods to add/remove your own addEventListener hijacking on document + window.
-     */
-    addWindowEventHandler:function(event) {
-        return (windowEventHandlers[event] = channel.create(event));
-    },
-    addStickyDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.createSticky(event));
-    },
-    addDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.create(event));
-    },
-    removeWindowEventHandler:function(event) {
-        delete windowEventHandlers[event];
-    },
-    removeDocumentEventHandler:function(event) {
-        delete documentEventHandlers[event];
-    },
-    /**
-     * Retrieve original event handlers that were replaced by Cordova
-     *
-     * @return object
-     */
-    getOriginalHandlers: function() {
-        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
-        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
-    },
-    /**
-     * Method to fire event from native code
-     * bNoDetach is required for events which cause an exception which needs to be caught in native code
-     */
-    fireDocumentEvent: function(type, data, bNoDetach) {
-        var evt = createEvent(type, data);
-        if (typeof documentEventHandlers[type] != 'undefined') {
-            if( bNoDetach ) {
-                documentEventHandlers[type].fire(evt);
-            }
-            else {
-                setTimeout(function() {
-                    // Fire deviceready on listeners that were registered before cordova.js was loaded.
-                    if (type == 'deviceready') {
-                        document.dispatchEvent(evt);
-                    }
-                    documentEventHandlers[type].fire(evt);
-                }, 0);
-            }
-        } else {
-            document.dispatchEvent(evt);
-        }
-    },
-    fireWindowEvent: function(type, data) {
-        var evt = createEvent(type,data);
-        if (typeof windowEventHandlers[type] != 'undefined') {
-            setTimeout(function() {
-                windowEventHandlers[type].fire(evt);
-            }, 0);
-        } else {
-            window.dispatchEvent(evt);
-        }
-    },
-
-    /**
-     * Plugin callback mechanism.
-     */
-    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
-    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
-    callbackId: Math.floor(Math.random() * 2000000000),
-    callbacks:  {},
-    callbackStatus: {
-        NO_RESULT: 0,
-        OK: 1,
-        CLASS_NOT_FOUND_EXCEPTION: 2,
-        ILLEGAL_ACCESS_EXCEPTION: 3,
-        INSTANTIATION_EXCEPTION: 4,
-        MALFORMED_URL_EXCEPTION: 5,
-        IO_EXCEPTION: 6,
-        INVALID_ACTION: 7,
-        JSON_EXCEPTION: 8,
-        ERROR: 9
-    },
-
-    /**
-     * Called by native code when returning successful result from an action.
-     */
-    callbackSuccess: function(callbackId, args) {
-        try {
-            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning error result from an action.
-     */
-    callbackError: function(callbackId, args) {
-        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
-        // Derive success from status.
-        try {
-            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning the result from an action.
-     */
-    callbackFromNative: function(callbackId, success, status, args, keepCallback) {
-        var callback = cordova.callbacks[callbackId];
-        if (callback) {
-            if (success && status == cordova.callbackStatus.OK) {
-                callback.success && callback.success.apply(null, args);
-            } else if (!success) {
-                callback.fail && callback.fail.apply(null, args);
-            }
-
-            // Clear callback if not expecting any more results
-            if (!keepCallback) {
-                delete cordova.callbacks[callbackId];
-            }
-        }
-    },
-    addConstructor: function(func) {
-        channel.onCordovaReady.subscribe(function() {
-            try {
-                func();
-            } catch(e) {
-                console.log("Failed to run constructor: " + e);
-            }
-        });
-    }
-};
-
-
-module.exports = cordova;
-
-});
-
-// file: lib/android/android/nativeapiprovider.js
-define("cordova/android/nativeapiprovider", function(require, exports, module) {
-
-/**
- * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
- */
-
-var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
-var currentApi = nativeApi;
-
-module.exports = {
-    get: function() { return currentApi; },
-    setPreferPrompt: function(value) {
-        currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
-    },
-    // Used only by tests.
-    set: function(value) {
-        currentApi = value;
-    }
-};
-
-});
-
-// file: lib/android/android/promptbasednativeapi.js
-define("cordova/android/promptbasednativeapi", function(require, exports, module) {
-
-/**
- * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
- * This is used only on the 2.3 simulator, where addJavascriptInterface() is broken.
- */
-
-module.exports = {
-    exec: function(service, action, callbackId, argsJson) {
-        return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId]));
-    },
-    setNativeToJsBridgeMode: function(value) {
-        prompt(value, 'gap_bridge_mode:');
-    },
-    retrieveJsMessages: function(fromOnlineEvent) {
-        return prompt(+fromOnlineEvent, 'gap_poll:');
-    }
-};
-
-});
-
-// file: lib/common/argscheck.js
-define("cordova/argscheck", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var moduleExports = module.exports;
-
-var typeMap = {
-    'A': 'Array',
-    'D': 'Date',
-    'N': 'Number',
-    'S': 'String',
-    'F': 'Function',
-    'O': 'Object'
-};
-
-function extractParamName(callee, argIndex) {
-    return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
-}
-
-function checkArgs(spec, functionName, args, opt_callee) {
-    if (!moduleExports.enableChecks) {
-        return;
-    }
-    var errMsg = null;
-    var typeName;
-    for (var i = 0; i < spec.length; ++i) {
-        var c = spec.charAt(i),
-            cUpper = c.toUpperCase(),
-            arg = args[i];
-        // Asterix means allow anything.
-        if (c == '*') {
-            continue;
-        }
-        typeName = utils.typeName(arg);
-        if ((arg === null || arg === undefined) && c == cUpper) {
-            continue;
-        }
-        if (typeName != typeMap[cUpper]) {
-            errMsg = 'Expected ' + typeMap[cUpper];
-            break;
-        }
-    }
-    if (errMsg) {
-        errMsg += ', but got ' + typeName + '.';
-        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
-        // Don't log when running unit tests.
-        if (typeof jasmine == 'undefined') {
-            console.error(errMsg);
-        }
-        throw TypeError(errMsg);
-    }
-}
-
-function getValue(value, defaultValue) {
-    return value === undefined ? defaultValue : value;
-}
-
-moduleExports.checkArgs = checkArgs;
-moduleExports.getValue = getValue;
-moduleExports.enableChecks = true;
-
-
-});
-
-// file: lib/common/base64.js
-define("cordova/base64", function(require, exports, module) {
-
-var base64 = exports;
-
-base64.fromArrayBuffer = function(arrayBuffer) {
-    var array = new Uint8Array(arrayBuffer);
-    return uint8ToBase64(array);
-};
-
-//------------------------------------------------------------------------------
-
-/* This code is based on the performance tests at http://jsperf.com/b64tests
- * This 12-bit-at-a-time algorithm was the best performing version on all
- * platforms tested.
- */
-
-var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-var b64_12bit;
-
-var b64_12bitTable = function() {
-    b64_12bit = [];
-    for (var i=0; i<64; i++) {
-        for (var j=0; j<64; j++) {
-            b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];
-        }
-    }
-    b64_12bitTable = function() { return b64_12bit; };
-    return b64_12bit;
-};
-
-function uint8ToBase64(rawData) {
-    var numBytes = rawData.byteLength;
-    var output="";
-    var segment;
-    var table = b64_12bitTable();
-    for (var i=0;i<numBytes-2;i+=3) {
-        segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];
-        output += table[segment >> 12];
-        output += table[segment & 0xfff];
-    }
-    if (numBytes - i == 2) {
-        segment = (rawData[i] << 16) + (rawData[i+1] << 8);
-        output += table[segment >> 12];
-        output += b64_6bit[(segment & 0xfff) >> 6];
-        output += '=';
-    } else if (numBytes - i == 1) {
-        segment = (rawData[i] << 16);
-        output += table[segment >> 12];
-        output += '==';
-    }
-    return output;
-}
-
-});
-
-// file: lib/common/builder.js
-define("cordova/builder", function(require, exports, module) {
-
-var utils = require('cordova/utils');
-
-function each(objects, func, context) {
-    for (var prop in objects) {
-        if (objects.hasOwnProperty(prop)) {
-            func.apply(context, [objects[prop], prop]);
-        }
-    }
-}
-
-function clobber(obj, key, value) {
-    exports.replaceHookForTesting(obj, key);
-    obj[key] = value;
-    // Getters can only be overridden by getters.
-    if (obj[key] !== value) {
-        utils.defineGetter(obj, key, function() {
-            return value;
-        });
-    }
-}
-
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
-    if (message) {
-        utils.defineGetter(obj, key, function() {
-            console.log(message);
-            delete obj[key];
-            clobber(obj, key, value);
-            return value;
-        });
-    } else {
-        clobber(obj, key, value);
-    }
-}
-
-function include(parent, objects, clobber, merge) {
-    each(objects, function (obj, key) {
-        try {
-            var result = obj.path ? require(obj.path) : {};
-
-            if (clobber) {
-                // Clobber if it doesn't exist.
-                if (typeof parent[key] === 'undefined') {
-                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                } else if (typeof obj.path !== 'undefined') {
-                    // If merging, merge properties onto parent, otherwise, clobber.
-                    if (merge) {
-                        recursiveMerge(parent[key], result);
-                    } else {
-                        assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                    }
-                }
-                result = parent[key];
-            } else {
-                // Overwrite if not currently defined.
-                if (typeof parent[key] == 'undefined') {
-                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                } else {
-                    // Set result to what already exists, so we can build children into it if they exist.
-                    result = parent[key];
-                }
-            }
-
-            if (obj.children) {
-                include(result, obj.children, clobber, merge);
-            }
-        } catch(e) {
-            utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
-        }
-    });
-}
-
-/**
- * Merge properties from one object onto another recursively.  Properties from
- * the src object will overwrite existing target property.
- *
- * @param target Object to merge properties into.
- * @param src Object to merge properties from.
- */
-function recursiveMerge(target, src) {
-    for (var prop in src) {
-        if (src.hasOwnProperty(prop)) {
-            if (target.prototype && target.prototype.constructor === target) {
-                // If the target object is a constructor override off prototype.
-                clobber(target.prototype, prop, src[prop]);
-            } else {
-                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
-                    recursiveMerge(target[prop], src[prop]);
-                } else {
-                    clobber(target, prop, src[prop]);
-                }
-            }
-        }
-    }
-}
-
-exports.buildIntoButDoNotClobber = function(objects, target) {
-    include(target, objects, false, false);
-};
-exports.buildIntoAndClobber = function(objects, target) {
-    include(target, objects, true, false);
-};
-exports.buildIntoAndMerge = function(objects, target) {
-    include(target, objects, true, true);
-};
-exports.recursiveMerge = recursiveMerge;
-exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
-
-});
-
-// file: lib/common/channel.js
-define("cordova/channel", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    nextGuid = 1;
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization, as well as for custom events thereafter.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
- * onNativeReady*              Internal event that indicates the Cordova native side is ready.
- * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
- * onDeviceReady*              User event fired to indicate that Cordova is ready
- * onResume                    User event fired to indicate a start/resume lifecycle event
- * onPause                     User event fired to indicate a pause lifecycle event
- * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
- * All listeners that subscribe after the event is fired will be executed right away.
- *
- * The only Cordova events that user code should register for are:
- *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
- *      pause                 App has moved to background
- *      resume                App has returned to foreground
- *
- * Listeners can be registered as:
- *      document.addEventListener("deviceready", myDeviceReadyListener, false);
- *      document.addEventListener("resume", myResumeListener, false);
- *      document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- *      window.onload
- *      window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type  String the channel name
- */
-var Channel = function(type, sticky) {
-    this.type = type;
-    // Map of guid -> function.
-    this.handlers = {};
-    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
-    this.state = sticky ? 1 : 0;
-    // Used in sticky mode to remember args passed to fire().
-    this.fireArgs = null;
-    // Used by onHasSubscribersChange to know if there are any listeners.
-    this.numHandlers = 0;
-    // Function that is called when the first listener is subscribed, or when
-    // the last listener is unsubscribed.
-    this.onHasSubscribersChange = null;
-},
-    channel = {
-        /**
-         * Calls the provided function only after all of the channels specified
-         * have been fired. All channels must be sticky channels.
-         */
-        join: function(h, c) {
-            var len = c.length,
-                i = len,
-                f = function() {
-                    if (!(--i)) h();
-                };
-            for (var j=0; j<len; j++) {
-                if (c[j].state === 0) {
-                    throw Error('Can only use join with sticky channels.');
-                }
-                c[j].subscribe(f);
-            }
-            if (!len) h();
-        },
-        create: function(type) {
-            return channel[type] = new Channel(type, false);
-        },
-        createSticky: function(type) {
-            return channel[type] = new Channel(type, true);
-        },
-
-        /**
-         * cordova Channels that must fire before "deviceready" is fired.
-         */
-        deviceReadyChannelsArray: [],
-        deviceReadyChannelsMap: {},
-
-        /**
-         * Indicate that a feature needs to be initialized before it is ready to be used.
-         * This holds up Cordova's "deviceready" event until the feature has been initialized
-         * and Cordova.initComplete(feature) is called.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        waitForInitialization: function(feature) {
-            if (feature) {
-                var c = channel[feature] || this.createSticky(feature);
-                this.deviceReadyChannelsMap[feature] = c;
-                this.deviceReadyChannelsArray.push(c);
-            }
-        },
-
-        /**
-         * Indicate that initialization code has completed and the feature is ready to be used.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        initializationComplete: function(feature) {
-            var c = this.deviceReadyChannelsMap[feature];
-            if (c) {
-                c.fire();
-            }
-        }
-    };
-
-function forceFunction(f) {
-    if (typeof f != 'function') throw "Function required as first argument!";
-}
-
-/**
- * Subscribes the given function to the channel. Any time that
- * Channel.fire is called so too will the function.
- * Optionally specify an execution context for the function
- * and a guid that can be used to stop subscribing to the channel.
- * Returns the guid.
- */
-Channel.prototype.subscribe = function(f, c) {
-    // need a function to call
-    forceFunction(f);
-    if (this.state == 2) {
-        f.apply(c || this, this.fireArgs);
-        return;
-    }
-
-    var func = f,
-        guid = f.observer_guid;
-    if (typeof c == "object") { func = utils.close(c, f); }
-
-    if (!guid) {
-        // first time any channel has seen this subscriber
-        guid = '' + nextGuid++;
-    }
-    func.observer_guid = guid;
-    f.observer_guid = guid;
-
-    // Don't add the same handler more than once.
-    if (!this.handlers[guid]) {
-        this.handlers[guid] = func;
-        this.numHandlers++;
-        if (this.numHandlers == 1) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Unsubscribes the function with the given guid from the channel.
- */
-Channel.prototype.unsubscribe = function(f) {
-    // need a function to unsubscribe
-    forceFunction(f);
-
-    var guid = f.observer_guid,
-        handler = this.handlers[guid];
-    if (handler) {
-        delete this.handlers[guid];
-        this.numHandlers--;
-        if (this.numHandlers === 0) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Calls all functions subscribed to this channel.
- */
-Channel.prototype.fire = function(e) {
-    var fail = false,
-        fireArgs = Array.prototype.slice.call(arguments);
-    // Apply stickiness.
-    if (this.state == 1) {
-        this.state = 2;
-        this.fireArgs = fireArgs;
-    }
-    if (this.numHandlers) {
-        // Copy the values first so that it is safe to modify it from within
-        // callbacks.
-        var toCall = [];
-        for (var item in this.handlers) {
-            toCall.push(this.handlers[item]);
-        }
-        for (var i = 0; i < toCall.length; ++i) {
-            toCall[i].apply(this, fireArgs);
-        }
-        if (this.state == 2 && this.numHandlers) {
-            this.numHandlers = 0;
-            this.handlers = {};
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-
-// defining them here so they are ready super fast!
-// DOM event that is received when the web page is loaded and parsed.
-channel.createSticky('onDOMContentLoaded');
-
-// Event to indicate the Cordova native side is ready.
-channel.createSticky('onNativeReady');
-
-// Event to indicate that all Cordova JavaScript objects have been created
-// and it's time to run plugin constructors.
-channel.createSticky('onCordovaReady');
-
-// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-channel.createSticky('onPluginsReady');
-
-// Event to indicate that Cordova is ready
-channel.createSticky('onDeviceReady');
-
-// Event to indicate a resume lifecycle event
-channel.create('onResume');
-
-// Event to indicate a pause lifecycle event
-channel.create('onPause');
-
-// Event to indicate a destroy lifecycle event
-channel.createSticky('onDestroy');
-
-// Channels that must fire before "deviceready" is fired.
-channel.waitForInitialization('onCordovaReady');
-channel.waitForInitialization('onDOMContentLoaded');
-
-module.exports = channel;
-
-});
-
-// file: lib/android/exec.js
-define("cordova/exec", function(require, exports, module) {
-
-/**
- * Execute a cordova command.  It is up to the native side whether this action
- * is synchronous or asynchronous.  The native side can return:
- *      Synchronous: PluginResult object as a JSON string
- *      Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success    The success callback
- * @param {Function} fail       The fail callback
- * @param {String} service      The name of the service to use
- * @param {String} action       Action to be run in cordova
- * @param {String[]} [args]     Zero or more arguments to pass to the method
- */
-var cordova = require('cordova'),
-    nativeApiProvider = require('cordova/android/nativeapiprovider'),
-    utils = require('cordova/utils'),
-    base64 = require('cordova/base64'),
-    jsToNativeModes = {
-        PROMPT: 0,
-        JS_OBJECT: 1,
-        // This mode is currently for benchmarking purposes only. It must be enabled
-        // on the native side through the ENABLE_LOCATION_CHANGE_EXEC_MODE
-        // constant within CordovaWebViewClient.java before it will work.
-        LOCATION_CHANGE: 2
-    },
-    nativeToJsModes = {
-        // Polls for messages using the JS->Native bridge.
-        POLLING: 0,
-        // For LOAD_URL to be viable, it would need to have a work-around for
-        // the bug where the soft-keyboard gets dismissed when a message is sent.
-        LOAD_URL: 1,
-        // For the ONLINE_EVENT to be viable, it would need to intercept all event
-        // listeners (both through addEventListener and window.ononline) as well
-        // as set the navigator property itself.
-        ONLINE_EVENT: 2,
-        // Uses reflection to access private APIs of the WebView that can send JS
-        // to be executed.
-        // Requires Android 3.2.4 or above.
-        PRIVATE_API: 3
-    },
-    jsToNativeBridgeMode,  // Set lazily.
-    nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
-    pollEnabled = false,
-    messagesFromNative = [];
-
-function androidExec(success, fail, service, action, args) {
-    // Set default bridge modes if they have not already been set.
-    // By default, we use the failsafe, since addJavascriptInterface breaks too often
-    if (jsToNativeBridgeMode === undefined) {
-        androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
-    }
-
-    // Process any ArrayBuffers in the args into a string.
-    for (var i = 0; i < args.length; i++) {
-        if (utils.typeName(args[i]) == 'ArrayBuffer') {
-            args[i] = base64.fromArrayBuffer(args[i]);
-        }
-    }
-
-    var callbackId = service + cordova.callbackId++,
-        argsJson = JSON.stringify(args);
-
-    if (success || fail) {
-        cordova.callbacks[callbackId] = {success:success, fail:fail};
-    }
-
-    if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) {
-        window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;
-    } else {
-        var messages = nativeApiProvider.get().exec(service, action, callbackId, argsJson);
-        // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
-        // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2.  See CB-2666.
-        if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && messages === "@Null arguments.") {
-            androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
-            androidExec(success, fail, service, action, args);
-            androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
-            return;
-        } else {
-            androidExec.processMessages(messages);
-        }
-    }
-}
-
-function pollOnceFromOnlineEvent() {
-    pollOnce(true);
-}
-
-function pollOnce(opt_fromOnlineEvent) {
-    var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent);
-    androidExec.processMessages(msg);
-}
-
-function pollingTimerFunc() {
-    if (pollEnabled) {
-        pollOnce();
-        setTimeout(pollingTimerFunc, 50);
-    }
-}
-
-function hookOnlineApis() {
-    function proxyEvent(e) {
-        cordova.fireWindowEvent(e.type);
-    }
-    // The network module takes care of firing online and offline events.
-    // It currently fires them only on document though, so we bridge them
-    // to window here (while first listening for exec()-releated online/offline
-    // events).
-    window.addEventListener('online', pollOnceFromOnlineEvent, false);
-    window.addEventListener('offline', pollOnceFromOnlineEvent, false);
-    cordova.addWindowEventHandler('online');
-    cordova.addWindowEventHandler('offline');
-    document.addEventListener('online', proxyEvent, false);
-    document.addEventListener('offline', proxyEvent, false);
-}
-
-hookOnlineApis();
-
-androidExec.jsToNativeModes = jsToNativeModes;
-androidExec.nativeToJsModes = nativeToJsModes;
-
-androidExec.setJsToNativeBridgeMode = function(mode) {
-    if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
-        console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
-        mode = jsToNativeModes.PROMPT;
-    }
-    nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
-    jsToNativeBridgeMode = mode;
-};
-
-androidExec.setNativeToJsBridgeMode = function(mode) {
-    if (mode == nativeToJsBridgeMode) {
-        return;
-    }
-    if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
-        pollEnabled = false;
-    }
-
-    nativeToJsBridgeMode = mode;
-    // Tell the native side to switch modes.
-    nativeApiProvider.get().setNativeToJsBridgeMode(mode);
-
-    if (mode == nativeToJsModes.POLLING) {
-        pollEnabled = true;
-        setTimeout(pollingTimerFunc, 1);
-    }
-};
-
-// Processes a single message, as encoded by NativeToJsMessageQueue.java.
-function processMessage(message) {
-    try {
-        var firstChar = message.charAt(0);
-        if (firstChar == 'J') {
-            eval(message.slice(1));
-        } else if (firstChar == 'S' || firstChar == 'F') {
-            var success = firstChar == 'S';
-            var keepCallback = message.charAt(1) == '1';
-            var spaceIdx = message.indexOf(' ', 2);
-            var status = +message.slice(2, spaceIdx);
-            var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
-            var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
-            var payloadKind = message.charAt(nextSpaceIdx + 1);
-            var payload;
-            if (payloadKind == 's') {
-                payload = message.slice(nextSpaceIdx + 2);
-            } else if (payloadKind == 't') {
-                payload = true;
-            } else if (payloadKind == 'f') {
-                payload = false;
-            } else if (payloadKind == 'N') {
-                payload = null;
-            } else if (payloadKind == 'n') {
-                payload = +message.slice(nextSpaceIdx + 2);
-            } else if (payloadKind == 'A') {
-                var data = message.slice(nextSpaceIdx + 2);
-                var bytes = window.atob(data);
-                var arraybuffer = new Uint8Array(bytes.length);
-                for (var i = 0; i < bytes.length; i++) {
-                    arraybuffer[i] = bytes.charCodeAt(i);
-                }
-                payload = arraybuffer.buffer;
-            } else if (payloadKind == 'S') {
-                payload = window.atob(message.slice(nextSpaceIdx + 2));
-            } else {
-                payload = JSON.parse(message.slice(nextSpaceIdx + 1));
-            }
-            cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
-        } else {
-            console.log("processMessage failed: invalid message:" + message);
-        }
-    } catch (e) {
-        console.log("processMessage failed: Message: " + message);
-        console.log("processMessage failed: Error: " + e);
-        console.log("processMessage failed: Stack: " + e.stack);
-    }
-}
-
-// This is called from the NativeToJsMessageQueue.java.
-androidExec.processMessages = function(messages) {
-    if (messages) {
-        messagesFromNative.push(messages);
-        // Check for the reentrant case, and enqueue the message if that's the case.
-        if (messagesFromNative.length > 1) {
-            return;
-        }
-        while (messagesFromNative.length) {
-            // Don't unshift until the end so that reentrancy can be detected.
-            messages = messagesFromNative[0];
-            // The Java side can send a * message to indicate that it
-            // still has messages waiting to be retrieved.
-            if (messages == '*') {
-                messagesFromNative.shift();
-                window.setTimeout(pollOnce, 0);
-                return;
-            }
-
-            var spaceIdx = messages.indexOf(' ');
-            var msgLen = +messages.slice(0, spaceIdx);
-            var message = messages.substr(spaceIdx + 1, msgLen);
-            messages = messages.slice(spaceIdx + msgLen + 1);
-            processMessage(message);
-            if (messages) {
-                messagesFromNative[0] = messages;
-            } else {
-                messagesFromNative.shift();
-            }
-        }
-    }
-};
-
-module.exports = androidExec;
-
-});
-
-// file: lib/common/init.js
-define("cordova/init", function(require, exports, module) {
-
-var channel = require('cordova/channel');
-var cordova = require('cordova');
-var modulemapper = require('cordova/modulemapper');
-var platform = require('cordova/platform');
-var pluginloader = require('cordova/pluginloader');
-
-var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
-
-function logUnfiredChannels(arr) {
-    for (var i = 0; i < arr.length; ++i) {
-        if (arr[i].state != 2) {
-            console.log('Channel not fired: ' + arr[i].type);
-        }
-    }
-}
-
-window.setTimeout(function() {
-    if (channel.onDeviceReady.state != 2) {
-        console.log('deviceready has not fired after 5 seconds.');
-        logUnfiredChannels(platformInitChannelsArray);
-        logUnfiredChannels(channel.deviceReadyChannelsArray);
-    }
-}, 5000);
-
-// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
-// We replace it so that properties that can't be clobbered can instead be overridden.
-function replaceNavigator(origNavigator) {
-    var CordovaNavigator = function() {};
-    CordovaNavigator.prototype = origNavigator;
-    var newNavigator = new CordovaNavigator();
-    // This work-around really only applies to new APIs that are newer than Function.bind.
-    // Without it, APIs such as getGamepads() break.
-    if (CordovaNavigator.bind) {
-        for (var key in origNavigator) {
-            if (typeof origNavigator[key] == 'function') {
-                newNavigator[key] = origNavigator[key].bind(origNavigator);
-            }
-        }
-    }
-    return newNavigator;
-}
-if (window.navigator) {
-    window.navigator = replaceNavigator(window.navigator);
-}
-
-if (!window.console) {
-    window.console = {
-        log: function(){}
-    };
-}
-if (!window.console.warn) {
-    window.console.warn = function(msg) {
-        this.log("warn: " + msg);
-    };
-}
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
-
-// Listen for DOMContentLoaded and notify our channel subscribers.
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
-    channel.onDOMContentLoaded.fire();
-} else {
-    document.addEventListener('DOMContentLoaded', function() {
-        channel.onDOMContentLoaded.fire();
-    }, false);
-}
-
-// _nativeReady is global variable that the native side can set
-// to signify that the native code is ready. It is a global since
-// it may be called before any cordova JS is ready.
-if (window._nativeReady) {
-    channel.onNativeReady.fire();
-}
-
-modulemapper.clobbers('cordova', 'cordova');
-modulemapper.clobbers('cordova/exec', 'cordova.exec');
-modulemapper.clobbers('cordova/exec', 'Cordova.exec');
-
-// Call the platform-specific initialization.
-platform.bootstrap && platform.bootstrap();
-
-pluginloader.load(function() {
-    channel.onPluginsReady.fire();
-});
-
-/**
- * Create all cordova objects once native side is ready.
- */
-channel.join(function() {
-    modulemapper.mapModules(window);
-
-    platform.initialize && platform.initialize();
-
-    // Fire event to notify that all objects are created
-    channel.onCordovaReady.fire();
-
-    // Fire onDeviceReady event once page has fully loaded, all
-    // constructors have run and cordova info has been received from native
-    // side.
-    channel.join(function() {
-        require('cordova').fireDocumentEvent('deviceready');
-    }, channel.deviceReadyChannelsArray);
-
-}, platformInitChannelsArray);
-
-
-});
-
-// file: lib/common/modulemapper.js
-define("cordova/modulemapper", function(require, exports, module) {
-
-var builder = require('cordova/builder'),
-    moduleMap = define.moduleMap,
-    symbolList,
-    deprecationMap;
-
-exports.reset = function() {
-    symbolList = [];
-    deprecationMap = {};
-};
-
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
-    if (!(moduleName in moduleMap)) {
-        throw new Error('Module ' + moduleName + ' does not exist.');
-    }
-    symbolList.push(strategy, moduleName, symbolPath);
-    if (opt_deprecationMessage) {
-        deprecationMap[symbolPath] = opt_deprecationMessage;
-    }
-}
-
-// Note: Android 2.3 does have Function.bind().
-exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.runs = function(moduleName) {
-    addEntry('r', moduleName, null);
-};
-
-function prepareNamespace(symbolPath, context) {
-    if (!symbolPath) {
-        return context;
-    }
-    var parts = symbolPath.split('.');
-    var cur = context;
-    for (var i = 0, part; part = parts[i]; ++i) {
-        cur = cur[part] = cur[part] || {};
-    }
-    return cur;
-}
-
-exports.mapModules = function(context) {
-    var origSymbols = {};
-    context.CDV_origSymbols = origSymbols;
-    for (var i = 0, len = symbolList.length; i < len; i += 3) {
-        var strategy = symbolList[i];
-        var moduleName = symbolList[i + 1];
-        var module = require(moduleName);
-        // <runs/>
-        if (strategy == 'r') {
-            continue;
-        }
-        var symbolPath = symbolList[i + 2];
-        var lastDot = symbolPath.lastIndexOf('.');
-        var namespace = symbolPath.substr(0, lastDot);
-        var lastName = symbolPath.substr(lastDot + 1);
-
-        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
-        var parentObj = prepareNamespace(namespace, context);
-        var target = parentObj[lastName];
-
-        if (strategy == 'm' && target) {
-            builder.recursiveMerge(target, module);
-        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
-            if (!(symbolPath in origSymbols)) {
-                origSymbols[symbolPath] = target;
-            }
-            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
-        }
-    }
-};
-
-exports.getOriginalSymbol = function(context, symbolPath) {
-    var origSymbols = context.CDV_origSymbols;
-    if (origSymbols && (symbolPath in origSymbols)) {
-        return origSymbols[symbolPath];
-    }
-    var parts = symbolPath.split('.');
-    var obj = context;
-    for (var i = 0; i < parts.length; ++i) {
-        obj = obj && obj[parts[i]];
-    }
-    return obj;
-};
-
-exports.reset();
-
-
-});
-
-// file: lib/android/platform.js
-define("cordova/platform", function(require, exports, module) {
-
-module.exports = {
-    id: 'android',
-    bootstrap: function() {
-        var channel = require('cordova/channel'),
-            cordova = require('cordova'),
-            exec = require('cordova/exec'),
-            modulemapper = require('cordova/modulemapper');
-
-        // Tell the native code that a page change has occurred.
-        exec(null, null, 'PluginManager', 'startup', []);
-        // Tell the JS that the native side is ready.
-        channel.onNativeReady.fire();
-
-        // TODO: Extract this as a proper plugin.
-        modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
-
-        // Inject a listener for the backbutton on the document.
-        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
-        backButtonChannel.onHasSubscribersChange = function() {
-            // If we just attached the first handler or detached the last handler,
-            // let native know we need to override the back button.
-            exec(null, null, "App", "overrideBackbutton", [this.numHandlers == 1]);
-        };
-
-        // Add hardware MENU and SEARCH button handlers
-        cordova.addDocumentEventHandler('menubutton');
-        cordova.addDocumentEventHandler('searchbutton');
-
-        // Let native code know we are all done on the JS side.
-        // Native code will then un-hide the WebView.
-        channel.onCordovaReady.subscribe(function() {
-            exec(null, null, "App", "show", []);
-        });
-    }
-};
-
-});
-
-// file: lib/android/plugin/android/app.js
-define("cordova/plugin/android/app", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-module.exports = {
-    /**
-    * Clear the resource cache.
-    */
-    clearCache:function() {
-        exec(null, null, "App", "clearCache", []);
-    },
-
-    /**
-    * Load the url into the webview or into new browser instance.
-    *
-    * @param url           The URL to load
-    * @param props         Properties that can be passed in to the activity:
-    *      wait: int                           => wait msec before loading URL
-    *      loadingDialog: "Title,Message"      => display a native loading dialog
-    *      loadUrlTimeoutValue: int            => time in msec to wait before triggering a timeout error
-    *      clearHistory: boolean              => clear webview history (default=false)
-    *      openExternal: boolean              => open in a new browser (default=false)
-    *
-    * Example:
-    *      navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
-    */
-    loadUrl:function(url, props) {
-        exec(null, null, "App", "loadUrl", [url, props]);
-    },
-
-    /**
-    * Cancel loadUrl that is waiting to be loaded.
-    */
-    cancelLoadUrl:function() {
-        exec(null, null, "App", "cancelLoadUrl", []);
-    },
-
-    /**
-    * Clear web history in this web view.
-    * Instead of BACK button loading the previous web page, it will exit the app.
-    */
-    clearHistory:function() {
-        exec(null, null, "App", "clearHistory", []);
-    },
-
-    /**
-    * Go to previous page displayed.
-    * This is the same as pressing the backbutton on Android device.
-    */
-    backHistory:function() {
-        exec(null, null, "App", "backHistory", []);
-    },
-
-    /**
-    * Override the default behavior of the Android back button.
-    * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
-    *
-    * Note: The user should not have to call this method.  Instead, when the user
-    *       registers for the "backbutton" event, this is automatically done.
-    *
-    * @param override        T=override, F=cancel override
-    */
-    overrideBackbutton:function(override) {
-        exec(null, null, "App", "overrideBackbutton", [override]);
-    },
-
-    /**
-    * Exit and terminate the application.
-    */
-    exitApp:function() {
-        return exec(null, null, "App", "exitApp", []);
-    }
-};
-
-});
-
-// file: lib/common/pluginloader.js
-define("cordova/pluginloader", function(require, exports, module) {
-
-var modulemapper = require('cordova/modulemapper');
-
-// Helper function to inject a <script> tag.
-function injectScript(url, onload, onerror) {
-    var script = document.createElement("script");
-    // onload fires even when script fails loads with an error.
-    script.onload = onload;
-    script.onerror = onerror || onload;
-    script.src = url;
-    document.head.appendChild(script);
-}
-
-function onScriptLoadingComplete(moduleList, finishPluginLoading) {
-    // Loop through all the plugins and then through their clobbers and merges.
-    for (var i = 0, module; module = moduleList[i]; i++) {
-        if (module) {
-            try {
-                if (module.clobbers && module.clobbers.length) {
-                    for (var j = 0; j < module.clobbers.length; j++) {
-                        modulemapper.clobbers(module.id, module.clobbers[j]);
-                    }
-                }
-
-                if (module.merges && module.merges.length) {
-                    for (var k = 0; k < module.merges.length; k++) {
-                        modulemapper.merges(module.id, module.merges[k]);
-                    }
-                }
-
-                // Finally, if runs is truthy we want to simply require() the module.
-                // This can be skipped if it had any merges or clobbers, though,
-                // since the mapper will already have required the module.
-                if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
-                    modulemapper.runs(module.id);
-                }
-            }
-            catch(err) {
-                // error with module, most likely clobbers, should we continue?
-            }
-        }
-    }
-
-    finishPluginLoading();
-}
-
-// Handler for the cordova_plugins.js content.
-// See plugman's plugin_loader.js for the details of this object.
-// This function is only called if the really is a plugins array that isn't empty.
-// Otherwise the onerror response handler will just call finishPluginLoading().
-function handlePluginsObject(path, moduleList, finishPluginLoading) {
-    // Now inject the scripts.
-    var scriptCounter = moduleList.length;
-
-    if (!scriptCounter) {
-        finishPluginLoading();
-        return;
-    }
-    function scriptLoadedCallback() {
-        if (!--scriptCounter) {
-            onScriptLoadingComplete(moduleList, finishPluginLoading);
-        }
-    }
-
-    for (var i = 0; i < moduleList.length; i++) {
-        injectScript(path + moduleList[i].file, scriptLoadedCallback);
-    }
-}
-
-function injectPluginScript(pathPrefix, finishPluginLoading) {
-    injectScript(pathPrefix + 'cordova_plugins.js', function(){
-        try {
-            var moduleList = require("cordova/plugin_list");
-            handlePluginsObject(pathPrefix, moduleList, finishPluginLoading);
-        } catch (e) {
-            // Error loading cordova_plugins.js, file not found or something
-            // this is an acceptable error, pre-3.0.0, so we just move on.
-            finishPluginLoading();
-        }
-    }, finishPluginLoading); // also, add script load error handler for file not found
-}
-
-function findCordovaPath() {
-    var path = null;
-    var scripts = document.getElementsByTagName('script');
-    var term = 'cordova.js';
-    for (var n = scripts.length-1; n>-1; n--) {
-        var src = scripts[n].src;
-        if (src.indexOf(term) == (src.length - term.length)) {
-            path = src.substring(0, src.length - term.length);
-            break;
-        }
-    }
-    return path;
-}
-
-// Tries to load all plugins' js-modules.
-// This is an async process, but onDeviceReady is blocked on onPluginsReady.
-// onPluginsReady is fired when there are no plugins to load, or they are all done.
-exports.load = function(callback) {
-    var pathPrefix = findCordovaPath();
-    if (pathPrefix === null) {
-        console.log('Could not find cordova.js script tag. Plugin loading may fail.');
-        pathPrefix = '';
-    }
-    injectPluginScript(pathPrefix, callback);
-};
-
-
-});
-
-// file: lib/common/urlutil.js
-define("cordova/urlutil", function(require, exports, module) {
-
-var urlutil = exports;
-var anchorEl = document.createElement('a');
-
-/**
- * For already absolute URLs, returns what is passed in.
- * For relative URLs, converts them to absolute ones.
- */
-urlutil.makeAbsolute = function(url) {
-  anchorEl.href = url;
-  return anchorEl.href;
-};
-
-});
-
-// file: lib/common/utils.js
-define("cordova/utils", function(require, exports, module) {
-
-var utils = exports;
-
-/**
- * Defines a property getter / setter for obj[key].
- */
-utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
-    if (Object.defineProperty) {
-        var desc = {
-            get: getFunc,
-            configurable: true
-        };
-        if (opt_setFunc) {
-            desc.set = opt_setFunc;
-        }
-        Object.defineProperty(obj, key, desc);
-    } else {
-        obj.__defineGetter__(key, getFunc);
-        if (opt_setFunc) {
-            obj.__defineSetter__(key, opt_setFunc);
-        }
-    }
-};
-
-/**
- * Defines a property getter for obj[key].
- */
-utils.defineGetter = utils.defineGetterSetter;
-
-utils.arrayIndexOf = function(a, item) {
-    if (a.indexOf) {
-        return a.indexOf(item);
-    }
-    var len = a.length;
-    for (var i = 0; i < len; ++i) {
-        if (a[i] == item) {
-            return i;
-        }
-    }
-    return -1;
-};
-
-/**
- * Returns whether the item was found in the array.
- */
-utils.arrayRemove = function(a, item) {
-    var index = utils.arrayIndexOf(a, item);
-    if (index != -1) {
-        a.splice(index, 1);
-    }
-    return index != -1;
-};
-
-utils.typeName = function(val) {
-    return Object.prototype.toString.call(val).slice(8, -1);
-};
-
-/**
- * Returns an indication of whether the argument is an array or not
- */
-utils.isArray = function(a) {
-    return utils.typeName(a) == 'Array';
-};
-
-/**
- * Returns an indication of whether the argument is a Date or not
- */
-utils.isDate = function(d) {
-    return utils.typeName(d) == 'Date';
-};
-
-/**
- * Does a deep clone of the object.
- */
-utils.clone = function(obj) {
-    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
-        return obj;
-    }
-
-    var retVal, i;
-
-    if(utils.isArray(obj)){
-        retVal = [];
-        for(i = 0; i < obj.length; ++i){
-            retVal.push(utils.clone(obj[i]));
-        }
-        return retVal;
-    }
-
-    retVal = {};
-    for(i in obj){
-        if(!(i in retVal) || retVal[i] != obj[i]) {
-            retVal[i] = utils.clone(obj[i]);
-        }
-    }
-    return retVal;
-};
-
-/**
- * Returns a wrapped version of the function
- */
-utils.close = function(context, func, params) {
-    if (typeof params == 'undefined') {
-        return function() {
-            return func.apply(context, arguments);
-        };
-    } else {
-        return function() {
-            return func.apply(context, params);
-        };
-    }
-};
-
-/**
- * Create a UUID
- */
-utils.createUUID = function() {
-    return UUIDcreatePart(4) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(6);
-};
-
-/**
- * Extends a child object from a parent object using classical inheritance
- * pattern.
- */
-utils.extend = (function() {
-    // proxy used to establish prototype chain
-    var F = function() {};
-    // extend Child from Parent
-    return function(Child, Parent) {
-        F.prototype = Parent.prototype;
-        Child.prototype = new F();
-        Child.__super__ = Parent.prototype;
-        Child.prototype.constructor = Child;
-    };
-}());
-
-/**
- * Alerts a message in any available way: alert or console.log.
- */
-utils.alert = function(msg) {
-    if (window.alert) {
-        window.alert(msg);
-    } else if (console && console.log) {
-        console.log(msg);
-    }
-};
-
-
-//------------------------------------------------------------------------------
-function UUIDcreatePart(length) {
-    var uuidpart = "";
-    for (var i=0; i<length; i++) {
-        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
-        if (uuidchar.length == 1) {
-            uuidchar = "0" + uuidchar;
-        }
-        uuidpart += uuidchar;
-    }
-    return uuidpart;
-}
-
-
-});
-
-window.cordova = require('cordova');
-// file: lib/scripts/bootstrap.js
-
-require('cordova/init');
-
-})();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/cordova_plugins.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/cordova_plugins.js b/spec/fixtures/platforms/android/assets/www/cordova_plugins.js
deleted file mode 100644
index b58b5dd..0000000
--- a/spec/fixtures/platforms/android/assets/www/cordova_plugins.js
+++ /dev/null
@@ -1,3 +0,0 @@
-cordova.define('cordova/plugin_list', function(require, exports, module) {
-module.exports = []
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/css/index.css
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/css/index.css b/spec/fixtures/platforms/android/assets/www/css/index.css
deleted file mode 100644
index 51daa79..0000000
--- a/spec/fixtures/platforms/android/assets/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-* {
-    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
-}
-
-body {
-    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
-    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
-    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
-    background-color:#E4E4E4;
-    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-gradient(
-        linear,
-        left top,
-        left bottom,
-        color-stop(0, #A7A7A7),
-        color-stop(0.51, #E4E4E4)
-    );
-    background-attachment:fixed;
-    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
-    font-size:12px;
-    height:100%;
-    margin:0px;
-    padding:0px;
-    text-transform:uppercase;
-    width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
-    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
-    position:absolute;             /* position in the center of the screen */
-    left:50%;
-    top:50%;
-    height:50px;                   /* text area height */
-    width:225px;                   /* text area width */
-    text-align:center;
-    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
-    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
-                                   /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
-    .app {
-        background-position:left center;
-        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
-        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
-                                      /* offset horizontal: half of image width and text area width */
-    }
-}
-
-h1 {
-    font-size:24px;
-    font-weight:normal;
-    margin:0px;
-    overflow:visible;
-    padding:0px;
-    text-align:center;
-}
-
-.event {
-    border-radius:4px;
-    -webkit-border-radius:4px;
-    color:#FFFFFF;
-    font-size:12px;
-    margin:0px 30px;
-    padding:2px 0px;
-}
-
-.event.listening {
-    background-color:#333333;
-    display:block;
-}
-
-.event.received {
-    background-color:#4B946A;
-    display:none;
-}
-
-@keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-@-webkit-keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-.blink {
-    animation:fade 3000ms infinite;
-    -webkit-animation:fade 3000ms infinite;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/img/logo.png
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/img/logo.png b/spec/fixtures/platforms/android/assets/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
Binary files a/spec/fixtures/platforms/android/assets/www/img/logo.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/index.html
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/index.html b/spec/fixtures/platforms/android/assets/www/index.html
deleted file mode 100644
index bde5741..0000000
--- a/spec/fixtures/platforms/android/assets/www/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <meta name="format-detection" content="telephone=no" />
-        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
-        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
-        <link rel="stylesheet" type="text/css" href="css/index.css" />
-        <title>Hello World</title>
-    </head>
-    <body>
-        <div class="app">
-            <h1>Apache Cordova</h1>
-            <div id="deviceready" class="blink">
-                <p class="event listening">Connecting to Device</p>
-                <p class="event received">Device is Ready</p>
-            </div>
-        </div>
-        <script type="text/javascript" src="cordova.js"></script>
-        <script type="text/javascript" src="js/index.js"></script>
-        <script type="text/javascript">
-            app.initialize();
-        </script>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/js/index.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/js/index.js b/spec/fixtures/platforms/android/assets/www/js/index.js
deleted file mode 100644
index 31d9064..0000000
--- a/spec/fixtures/platforms/android/assets/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-var app = {
-    // Application Constructor
-    initialize: function() {
-        this.bindEvents();
-    },
-    // Bind Event Listeners
-    //
-    // Bind any events that are required on startup. Common events are:
-    // 'load', 'deviceready', 'offline', and 'online'.
-    bindEvents: function() {
-        document.addEventListener('deviceready', this.onDeviceReady, false);
-    },
-    // deviceready Event Handler
-    //
-    // The scope of 'this' is the event. In order to call the 'receivedEvent'
-    // function, we must explicity call 'app.receivedEvent(...);'
-    onDeviceReady: function() {
-        app.receivedEvent('deviceready');
-    },
-    // Update DOM on a Received Event
-    receivedEvent: function(id) {
-        var parentElement = document.getElementById(id);
-        var listeningElement = parentElement.querySelector('.listening');
-        var receivedElement = parentElement.querySelector('.received');
-
-        listeningElement.setAttribute('style', 'display:none;');
-        receivedElement.setAttribute('style', 'display:block;');
-
-        console.log('Received Event: ' + id);
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/spec.html
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/spec.html b/spec/fixtures/platforms/android/assets/www/spec.html
deleted file mode 100644
index 71f00de..0000000
--- a/spec/fixtures/platforms/android/assets/www/spec.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <title>Jasmine Spec Runner</title>
-
-        <!-- jasmine source -->
-        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
-        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
-
-        <!-- include source files here... -->
-        <script type="text/javascript" src="js/index.js"></script>
-
-        <!-- include spec files here... -->
-        <script type="text/javascript" src="spec/helper.js"></script>
-        <script type="text/javascript" src="spec/index.js"></script>
-
-        <script type="text/javascript">
-            (function() {
-                var jasmineEnv = jasmine.getEnv();
-                jasmineEnv.updateInterval = 1000;
-
-                var htmlReporter = new jasmine.HtmlReporter();
-
-                jasmineEnv.addReporter(htmlReporter);
-
-                jasmineEnv.specFilter = function(spec) {
-                    return htmlReporter.specFilter(spec);
-                };
-
-                var currentWindowOnload = window.onload;
-
-                window.onload = function() {
-                    if (currentWindowOnload) {
-                        currentWindowOnload();
-                    }
-                    execJasmine();
-                };
-
-                function execJasmine() {
-                    jasmineEnv.execute();
-                }
-            })();
-        </script>
-    </head>
-    <body>
-        <div id="stage" style="display:none;"></div>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/build.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/build.xml b/spec/fixtures/platforms/android/build.xml
deleted file mode 100644
index 9674edf..0000000
--- a/spec/fixtures/platforms/android/build.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="TestBase" default="help">
-
-    <!-- The local.properties file is created and updated by the 'android' tool.
-         It contains the path to the SDK. It should *NOT* be checked into
-         Version Control Systems. -->
-    <property file="local.properties" />
-
-    <!-- The ant.properties file can be created by you. It is only edited by the
-         'android' tool to add properties to it.
-         This is the place to change some Ant specific build properties.
-         Here are some properties you may want to change/update:
-
-         source.dir
-             The name of the source directory. Default is 'src'.
-         out.dir
-             The name of the output directory. Default is 'bin'.
-
-         For other overridable properties, look at the beginning of the rules
-         files in the SDK, at tools/ant/build.xml
-
-         Properties related to the SDK location or the project target should
-         be updated using the 'android' tool with the 'update' action.
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems.
-
-         -->
-    <property file="ant.properties" />
-
-    <!-- if sdk.dir was not set from one of the property file, then
-         get it from the ANDROID_HOME env var.
-         This must be done before we load project.properties since
-         the proguard config can use sdk.dir -->
-    <property environment="env" />
-    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
-        <isset property="env.ANDROID_HOME" />
-    </condition>
-
-    <!-- The project.properties file is created and updated by the 'android'
-         tool, as well as ADT.
-
-         This contains project specific properties such as project target, and library
-         dependencies. Lower level build properties are stored in ant.properties
-         (or in .classpath for Eclipse projects).
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems. -->
-    <loadproperties srcFile="project.properties" />
-
-    <!-- quick check on sdk.dir -->
-    <fail
-            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
-            unless="sdk.dir"
-    />
-
-    <!--
-        Import per project custom build rules if present at the root of the project.
-        This is the place to put custom intermediary targets such as:
-            -pre-build
-            -pre-compile
-            -post-compile (This is typically used for code obfuscation.
-                           Compiled code location: ${out.classes.absolute.dir}
-                           If this is not done in place, override ${out.dex.input.absolute.dir})
-            -post-package
-            -post-build
-            -pre-clean
-    -->
-    <import file="custom_rules.xml" optional="true" />
-
-    <!-- Import the actual build file.
-
-         To customize existing targets, there are two options:
-         - Customize only one target:
-             - copy/paste the target into this file, *before* the
-               <import> task.
-             - customize it to your needs.
-         - Customize the whole content of build.xml
-             - copy/paste the content of the rules files (minus the top node)
-               into this file, replacing the <import> task.
-             - customize to your needs.
-
-         ***********************
-         ****** IMPORTANT ******
-         ***********************
-         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
-         in order to avoid having your file be overridden by tools such as "android update project"
-    -->
-    <!-- version-tag: 1 -->
-    <import file="${sdk.dir}/tools/ant/build.xml" />
-
-</project>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/build
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/build b/spec/fixtures/platforms/android/cordova/build
deleted file mode 100755
index 7028eb8..0000000
--- a/spec/fixtures/platforms/android/cordova/build
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var build = require('./lib/build'),
-    reqs  = require('./lib/check_reqs'),
-    args  = process.argv;
-
-// Support basic help commands
-if(args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
-                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
-    build.help();
-} else if(reqs.run()) {
-    build.run(args[2]);
-    process.exit(0);
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/check_reqs
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/check_reqs b/spec/fixtures/platforms/android/cordova/check_reqs
deleted file mode 100755
index 4a8abee..0000000
--- a/spec/fixtures/platforms/android/cordova/check_reqs
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var check_reqs = require('./lib/check_reqs');
-
-if(!check_reqs.run()) {
-      process.exit(2);
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/clean
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/clean b/spec/fixtures/platforms/android/cordova/clean
deleted file mode 100755
index 70c4ca8..0000000
--- a/spec/fixtures/platforms/android/cordova/clean
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var clean = require('./lib/clean'),
-    reqs  = require('./lib/check_reqs'),
-    args  = process.argv;
-
-// Usage support for when args are given
-if(args.length > 2) {
-    clean.help();
-} else if(reqs.run()) {
-    clean.run();
-    process.exit(0);
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/defaults.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/defaults.xml b/spec/fixtures/platforms/android/cordova/defaults.xml
deleted file mode 100644
index 24e5725..0000000
--- a/spec/fixtures/platforms/android/cordova/defaults.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        id        = "io.cordova.helloCordova"
-        version   = "2.0.0">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <access origin="*"/>
-
-    <!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
-    <content src="index.html" />
-
-    <preference name="loglevel" value="DEBUG" />
-    <!--
-      <preference name="splashscreen" value="resourceName" />
-      <preference name="backgroundColor" value="0xFFF" />
-      <preference name="loadUrlTimeoutValue" value="20000" />
-      <preference name="InAppBrowserStorageEnabled" value="true" />
-      <preference name="disallowOverscroll" value="true" />
-    -->
-    <!-- This is required for native Android hooks -->
-    <feature name="App">
-        <param name="android-package" value="org.apache.cordova.App" />
-    </feature>
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/appinfo.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/appinfo.js b/spec/fixtures/platforms/android/cordova/lib/appinfo.js
deleted file mode 100755
index 1f8ebe2..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/appinfo.js
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var path = require('path');
-var fs = require('fs');
-var cachedAppInfo = null;
-
-function readAppInfoFromManifest() {
-    var manifestPath = path.join(__dirname, '..', '..', 'AndroidManifest.xml');
-    var manifestData = fs.readFileSync(manifestPath, {encoding:'utf8'});
-    var packageName = /\bpackage\s*=\s*"(.+?)"/.exec(manifestData);
-    if (!packageName) throw new Error('Could not find package name within ' + manifestPath);
-    var activityTag = /<activity\b[\s\S]*<\/activity>/.exec(manifestData);
-    if (!activityTag) throw new Error('Could not find <activity> within ' + manifestPath);
-    var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag);
-    if (!activityName) throw new Error('Could not find android:name within ' + manifestPath);
-
-    return packageName[1] + '/.' + activityName[1];
-}
-
-exports.getActivityName = function() {
-    return cachedAppInfo = cachedAppInfo || readAppInfoFromManifest();
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/build.js b/spec/fixtures/platforms/android/cordova/lib/build.js
deleted file mode 100755
index 7bc33ca..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/build.js
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell   = require('shelljs'),
-    clean   = require('./clean'),
-    path    = require('path'),
-    fs      = require('fs'),
-    ROOT    = path.join(__dirname, '..', '..');
-
-/*
- * Builds the project with ant.
- */
-module.exports.run = function(build_type) {
-    //default build type
-    build_type = typeof build_type !== 'undefined' ? build_type : "--debug";
-    var cmd;
-    switch(build_type) {
-        case '--debug' :
-            clean.run();
-            cmd = 'ant debug -f ' + path.join(ROOT, 'build.xml');
-            break;
-        case '--release' :
-            clean.run();
-            cmd = 'ant release -f ' + path.join(ROOT, 'build.xml');
-            break;
-        case '--nobuild' :
-            console.log('Skipping build...');
-            break;
-        default :
-           console.error('Build option \'' + build_type + '\' not recognized.');
-           process.exit(2);
-           break;
-    }
-    if(cmd) {
-        var result = shell.exec(cmd, {silent:false, async:false});
-        if(result.code > 0) {
-            console.error('ERROR: Failed to build android project.');
-            console.error(result.output);
-            process.exit(2);
-        }
-    }
-}
-
-/*
- * Gets the path to the apk file, if not such file exists then
- * the script will error out. (should we error or just return undefined?)
- */
-module.exports.get_apk = function() {
-    if(fs.existsSync(path.join(ROOT, 'bin'))) {
-        var bin_files = fs.readdirSync(path.join(ROOT, 'bin'));
-        for (file in bin_files) {
-            if(path.extname(bin_files[file]) == '.apk') {
-                return path.join(ROOT, 'bin', bin_files[file]);
-            }
-        }
-        console.error('ERROR : No .apk found in \'bin\' folder');
-        process.exit(2);
-    } else {
-        console.error('ERROR : unable to find project bin folder, could not locate .apk');
-        process.exit(2);
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'build')) + ' [build_type]');
-    console.log('Build Types : ');
-    console.log('    \'--debug\': Default build, will build project in using ant debug');
-    console.log('    \'--release\': will build project using ant release');
-    console.log('    \'--nobuild\': will skip build process (can be used with run command)');
-    process.exit(0);
-}


[24/24] git commit: Fix require paths to use cordova-lib

Posted by ka...@apache.org.
Fix require paths to use cordova-lib


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

Branch: refs/heads/cordova-lib
Commit: 1b3b1f03a1a94283540d94dd7e790c9b0625ef3a
Parents: 89db695
Author: Mark Koudritsky <ka...@gmail.com>
Authored: Tue Apr 29 22:14:58 2014 -0400
Committer: Mark Koudritsky <ka...@gmail.com>
Committed: Thu May 1 11:22:50 2014 -0400

----------------------------------------------------------------------
 cordova.js          |   5 +
 npm-shrinkwrap.json | 812 -----------------------------------------------
 spec/cli.spec.js    |   5 +-
 spec/help.spec.js   |   6 +-
 src/cli.js          |  14 +-
 src/help.js         |   5 +-
 6 files changed, 23 insertions(+), 824 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1b3b1f03/cordova.js
----------------------------------------------------------------------
diff --git a/cordova.js b/cordova.js
new file mode 100644
index 0000000..17e2f5c
--- /dev/null
+++ b/cordova.js
@@ -0,0 +1,5 @@
+// All cordova js API moved to cordova-lib . This is a temporary shim for
+// dowstream packages that use cordova-cli for the API.
+
+var cordova_lib = require('cordova-lib');
+module.exports = cordova_lib.cordova;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1b3b1f03/npm-shrinkwrap.json
----------------------------------------------------------------------
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
deleted file mode 100644
index 3547b50..0000000
--- a/npm-shrinkwrap.json
+++ /dev/null
@@ -1,812 +0,0 @@
-{
-  "name": "cordova",
-  "version": "3.4.1-0.1.0",
-  "dependencies": {
-    "elementtree": {
-      "version": "0.1.5",
-      "from": "elementtree@0.1.5",
-      "dependencies": {
-        "sax": {
-          "version": "0.3.5",
-          "from": "sax@0.3.5"
-        }
-      }
-    },
-    "mime": {
-      "version": "1.2.11",
-      "from": "mime@1.2.11"
-    },
-    "npmconf": {
-      "version": "0.1.13",
-      "from": "npmconf@0.1.13",
-      "dependencies": {
-        "config-chain": {
-          "version": "1.1.8",
-          "from": "config-chain@1.1.8",
-          "dependencies": {
-            "proto-list": {
-              "version": "1.2.2",
-              "from": "proto-list@1.2.2"
-            }
-          }
-        },
-        "inherits": {
-          "version": "2.0.1",
-          "from": "inherits@2.0.1"
-        },
-        "once": {
-          "version": "1.3.0",
-          "from": "once@1.3.0"
-        },
-        "mkdirp": {
-          "version": "0.3.5",
-          "from": "mkdirp@0.3.5"
-        },
-        "osenv": {
-          "version": "0.0.3",
-          "from": "osenv@0.0.3"
-        },
-        "nopt": {
-          "version": "2.2.0",
-          "from": "nopt@2.2.0",
-          "dependencies": {
-            "abbrev": {
-              "version": "1.0.4",
-              "from": "abbrev@1.0.4"
-            }
-          }
-        },
-        "ini": {
-          "version": "1.1.0",
-          "from": "ini@1.1.0"
-        }
-      }
-    },
-    "optimist": {
-      "version": "0.6.0",
-      "from": "optimist@0.6.0",
-      "dependencies": {
-        "wordwrap": {
-          "version": "0.0.2",
-          "from": "wordwrap@0.0.2"
-        },
-        "minimist": {
-          "version": "0.0.8",
-          "from": "minimist@0.0.8"
-        }
-      }
-    },
-    "plist-with-patches": {
-      "version": "0.5.1",
-      "from": "plist-with-patches@0.5.1",
-      "dependencies": {
-        "xmlbuilder": {
-          "version": "0.4.3",
-          "from": "xmlbuilder@0.4.3"
-        },
-        "xmldom": {
-          "version": "0.1.19",
-          "from": "xmldom@0.1.19"
-        }
-      }
-    },
-    "plugman": {
-      "version": "0.21.0",
-      "from": "plugman@0.21.0",
-      "resolved": "https://registry.npmjs.org/plugman/-/plugman-0.21.0.tgz",
-      "dependencies": {
-        "nopt": {
-          "version": "1.0.10",
-          "from": "nopt@1.0.10",
-          "dependencies": {
-            "abbrev": {
-              "version": "1.0.4",
-              "from": "abbrev@1.0.4"
-            }
-          }
-        },
-        "glob": {
-          "version": "3.2.9",
-          "from": "glob@3.2.9",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.9.tgz",
-          "dependencies": {
-            "minimatch": {
-              "version": "0.2.14",
-              "from": "minimatch@0.2.14",
-              "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
-              "dependencies": {
-                "lru-cache": {
-                  "version": "2.5.0",
-                  "from": "lru-cache@2.5.0"
-                },
-                "sigmund": {
-                  "version": "1.0.0",
-                  "from": "sigmund@1.0.0"
-                }
-              }
-            },
-            "inherits": {
-              "version": "2.0.1",
-              "from": "inherits@2.0.1"
-            }
-          }
-        },
-        "bplist-parser": {
-          "version": "0.0.5",
-          "from": "bplist-parser@0.0.5"
-        },
-        "dep-graph": {
-          "version": "1.1.0",
-          "from": "dep-graph@1.1.0",
-          "dependencies": {
-            "underscore": {
-              "version": "1.2.1",
-              "from": "underscore@1.2.1",
-              "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.2.1.tgz"
-            }
-          }
-        },
-        "npm": {
-          "version": "1.3.4",
-          "from": "npm@1.3.4",
-          "dependencies": {
-            "semver": {
-              "version": "2.0.8",
-              "from": "semver@latest"
-            },
-            "ini": {
-              "version": "1.1.0",
-              "from": "ini@latest"
-            },
-            "slide": {
-              "version": "1.1.4",
-              "from": "slide@latest"
-            },
-            "abbrev": {
-              "version": "1.0.4",
-              "from": "abbrev@latest"
-            },
-            "graceful-fs": {
-              "version": "2.0.0",
-              "from": "graceful-fs@2"
-            },
-            "minimatch": {
-              "version": "0.2.12",
-              "from": "minimatch@latest",
-              "dependencies": {
-                "sigmund": {
-                  "version": "1.0.0",
-                  "from": "sigmund@~1.0.0",
-                  "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz"
-                }
-              }
-            },
-            "nopt": {
-              "version": "2.1.1",
-              "from": "nopt@latest"
-            },
-            "rimraf": {
-              "version": "2.2.0",
-              "from": "rimraf@2.2"
-            },
-            "request": {
-              "version": "2.21.0",
-              "from": "request@latest",
-              "dependencies": {
-                "qs": {
-                  "version": "0.6.5",
-                  "from": "qs@~0.6.0"
-                },
-                "json-stringify-safe": {
-                  "version": "4.0.0",
-                  "from": "json-stringify-safe@~4.0.0"
-                },
-                "forever-agent": {
-                  "version": "0.5.0",
-                  "from": "forever-agent@~0.5.0"
-                },
-                "tunnel-agent": {
-                  "version": "0.3.0",
-                  "from": "tunnel-agent@~0.3.0"
-                },
-                "http-signature": {
-                  "version": "0.9.11",
-                  "from": "http-signature@~0.9.11",
-                  "dependencies": {
-                    "assert-plus": {
-                      "version": "0.1.2",
-                      "from": "assert-plus@0.1.2"
-                    },
-                    "asn1": {
-                      "version": "0.1.11",
-                      "from": "asn1@0.1.11"
-                    },
-                    "ctype": {
-                      "version": "0.5.2",
-                      "from": "ctype@0.5.2"
-                    }
-                  }
-                },
-                "hawk": {
-                  "version": "0.13.1",
-                  "from": "hawk@~0.13.0",
-                  "dependencies": {
-                    "hoek": {
-                      "version": "0.8.5",
-                      "from": "hoek@0.8.x"
-                    },
-                    "boom": {
-                      "version": "0.4.2",
-                      "from": "boom@0.4.x",
-                      "dependencies": {
-                        "hoek": {
-                          "version": "0.9.1",
-                          "from": "hoek@0.9.x",
-                          "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
-                        }
-                      }
-                    },
-                    "cryptiles": {
-                      "version": "0.2.1",
-                      "from": "cryptiles@0.2.x"
-                    },
-                    "sntp": {
-                      "version": "0.2.4",
-                      "from": "sntp@0.2.x",
-                      "dependencies": {
-                        "hoek": {
-                          "version": "0.9.1",
-                          "from": "hoek@0.9.x",
-                          "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
-                        }
-                      }
-                    }
-                  }
-                },
-                "aws-sign": {
-                  "version": "0.3.0",
-                  "from": "aws-sign@~0.3.0"
-                },
-                "oauth-sign": {
-                  "version": "0.3.0",
-                  "from": "oauth-sign@~0.3.0"
-                },
-                "cookie-jar": {
-                  "version": "0.3.0",
-                  "from": "cookie-jar@~0.3.0"
-                },
-                "node-uuid": {
-                  "version": "1.4.0",
-                  "from": "node-uuid@~1.4.0"
-                },
-                "mime": {
-                  "version": "1.2.9",
-                  "from": "mime@~1.2.9"
-                },
-                "form-data": {
-                  "version": "0.0.8",
-                  "from": "form-data@0.0.8",
-                  "dependencies": {
-                    "combined-stream": {
-                      "version": "0.0.4",
-                      "from": "combined-stream@~0.0.4",
-                      "dependencies": {
-                        "delayed-stream": {
-                          "version": "0.0.5",
-                          "from": "delayed-stream@0.0.5"
-                        }
-                      }
-                    },
-                    "async": {
-                      "version": "0.2.9",
-                      "from": "async@~0.2.7"
-                    }
-                  }
-                }
-              }
-            },
-            "which": {
-              "version": "1.0.5",
-              "from": "which@1"
-            },
-            "tar": {
-              "version": "0.1.17",
-              "from": "tar@0.1.17",
-              "resolved": "https://registry.npmjs.org/tar/-/tar-0.1.17.tgz"
-            },
-            "fstream": {
-              "version": "0.1.23",
-              "from": "fstream@latest"
-            },
-            "block-stream": {
-              "version": "0.0.6",
-              "from": "block-stream@*"
-            },
-            "inherits": {
-              "version": "1.0.0",
-              "from": "git://github.com/isaacs/inherits"
-            },
-            "mkdirp": {
-              "version": "0.3.5",
-              "from": "mkdirp@0.3.5",
-              "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
-            },
-            "read": {
-              "version": "1.0.4",
-              "from": "read@~1.0.3",
-              "dependencies": {
-                "mute-stream": {
-                  "version": "0.0.3",
-                  "from": "mute-stream@~0.0.2"
-                }
-              }
-            },
-            "lru-cache": {
-              "version": "2.3.0",
-              "from": "lru-cache@latest"
-            },
-            "node-gyp": {
-              "version": "0.10.6",
-              "from": "node-gyp@latest"
-            },
-            "fstream-npm": {
-              "version": "0.1.4",
-              "from": "fstream-npm@latest",
-              "dependencies": {
-                "fstream-ignore": {
-                  "version": "0.0.6",
-                  "from": "fstream-ignore@~0.0.5"
-                }
-              }
-            },
-            "uid-number": {
-              "version": "0.0.3",
-              "from": "../uid-number"
-            },
-            "archy": {
-              "version": "0.0.2",
-              "from": "archy@0.0.2"
-            },
-            "chownr": {
-              "version": "0.0.1",
-              "from": "../chownr"
-            },
-            "npmlog": {
-              "version": "0.0.4",
-              "from": "npmlog@latest"
-            },
-            "ansi": {
-              "version": "0.1.2",
-              "from": "ansi@~0.1.2"
-            },
-            "npm-registry-client": {
-              "version": "0.2.27",
-              "from": "npm-registry-client@latest",
-              "dependencies": {
-                "couch-login": {
-                  "version": "0.1.17",
-                  "from": "couch-login@~0.1.15"
-                }
-              }
-            },
-            "read-package-json": {
-              "version": "1.1.0",
-              "from": "read-package-json@1",
-              "dependencies": {
-                "normalize-package-data": {
-                  "version": "0.2.0",
-                  "from": "normalize-package-data@~0.2",
-                  "dependencies": {
-                    "github-url-from-git": {
-                      "version": "1.1.1",
-                      "from": "github-url-from-git@~1.1.1"
-                    }
-                  }
-                }
-              }
-            },
-            "read-installed": {
-              "version": "0.2.2",
-              "from": "read-installed@latest"
-            },
-            "glob": {
-              "version": "3.2.3",
-              "from": "glob@latest",
-              "dependencies": {
-                "inherits": {
-                  "version": "2.0.0",
-                  "from": "inherits@2"
-                }
-              }
-            },
-            "init-package-json": {
-              "version": "0.0.10",
-              "from": "init-package-json@latest",
-              "dependencies": {
-                "promzard": {
-                  "version": "0.2.0",
-                  "from": "promzard@~0.2.0"
-                }
-              }
-            },
-            "osenv": {
-              "version": "0.0.3",
-              "from": "osenv@latest"
-            },
-            "lockfile": {
-              "version": "0.4.0",
-              "from": "lockfile@latest"
-            },
-            "retry": {
-              "version": "0.6.0",
-              "from": "retry"
-            },
-            "once": {
-              "version": "1.1.1",
-              "from": "once"
-            },
-            "npmconf": {
-              "version": "0.1.1",
-              "from": "npmconf@latest",
-              "dependencies": {
-                "config-chain": {
-                  "version": "1.1.7",
-                  "from": "config-chain@~1.1.1",
-                  "dependencies": {
-                    "proto-list": {
-                      "version": "1.2.2",
-                      "from": "proto-list@~1.2.1"
-                    }
-                  }
-                }
-              }
-            },
-            "opener": {
-              "version": "1.3.0",
-              "from": "opener@latest"
-            },
-            "chmodr": {
-              "version": "0.1.0",
-              "from": "chmodr@latest"
-            },
-            "cmd-shim": {
-              "version": "1.1.0",
-              "from": "cmd-shim@"
-            },
-            "sha": {
-              "version": "1.0.1",
-              "from": "sha@~1.0.1"
-            },
-            "editor": {
-              "version": "0.0.4",
-              "from": "editor@"
-            },
-            "child-process-close": {
-              "version": "0.1.1",
-              "from": "child-process-close@",
-              "resolved": "https://registry.npmjs.org/child-process-close/-/child-process-close-0.1.1.tgz"
-            },
-            "npm-user-validate": {
-              "version": "0.0.3",
-              "from": "npm-user-validate@0.0.3",
-              "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-0.0.3.tgz"
-            }
-          }
-        },
-        "rc": {
-          "version": "0.3.0",
-          "from": "rc@0.3.0",
-          "dependencies": {
-            "optimist": {
-              "version": "0.3.7",
-              "from": "optimist@0.3.7",
-              "dependencies": {
-                "wordwrap": {
-                  "version": "0.0.2",
-                  "from": "wordwrap@0.0.2"
-                }
-              }
-            },
-            "deep-extend": {
-              "version": "0.2.8",
-              "from": "deep-extend@0.2.8"
-            },
-            "ini": {
-              "version": "1.1.0",
-              "from": "ini@1.1.0"
-            }
-          }
-        },
-        "request": {
-          "version": "2.22.0",
-          "from": "request@2.22.0",
-          "resolved": "https://registry.npmjs.org/request/-/request-2.22.0.tgz",
-          "dependencies": {
-            "qs": {
-              "version": "0.6.6",
-              "from": "qs@0.6.6"
-            },
-            "json-stringify-safe": {
-              "version": "4.0.0",
-              "from": "json-stringify-safe@4.0.0"
-            },
-            "forever-agent": {
-              "version": "0.5.2",
-              "from": "forever-agent@0.5.2"
-            },
-            "tunnel-agent": {
-              "version": "0.3.0",
-              "from": "tunnel-agent@0.3.0"
-            },
-            "http-signature": {
-              "version": "0.10.0",
-              "from": "http-signature@0.10.0",
-              "dependencies": {
-                "assert-plus": {
-                  "version": "0.1.2",
-                  "from": "assert-plus@0.1.2"
-                },
-                "asn1": {
-                  "version": "0.1.11",
-                  "from": "asn1@0.1.11"
-                },
-                "ctype": {
-                  "version": "0.5.2",
-                  "from": "ctype@0.5.2",
-                  "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz"
-                }
-              }
-            },
-            "hawk": {
-              "version": "0.13.1",
-              "from": "hawk@0.13.1",
-              "dependencies": {
-                "hoek": {
-                  "version": "0.8.5",
-                  "from": "hoek@0.8.5"
-                },
-                "boom": {
-                  "version": "0.4.2",
-                  "from": "boom@0.4.2",
-                  "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz",
-                  "dependencies": {
-                    "hoek": {
-                      "version": "0.9.1",
-                      "from": "hoek@0.9.1",
-                      "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
-                    }
-                  }
-                },
-                "cryptiles": {
-                  "version": "0.2.2",
-                  "from": "cryptiles@0.2.2"
-                },
-                "sntp": {
-                  "version": "0.2.4",
-                  "from": "sntp@0.2.4",
-                  "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz",
-                  "dependencies": {
-                    "hoek": {
-                      "version": "0.9.1",
-                      "from": "hoek@0.9.1",
-                      "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
-                    }
-                  }
-                }
-              }
-            },
-            "aws-sign": {
-              "version": "0.3.0",
-              "from": "aws-sign@0.3.0"
-            },
-            "oauth-sign": {
-              "version": "0.3.0",
-              "from": "oauth-sign@0.3.0"
-            },
-            "cookie-jar": {
-              "version": "0.3.0",
-              "from": "cookie-jar@0.3.0"
-            },
-            "node-uuid": {
-              "version": "1.4.1",
-              "from": "node-uuid@1.4.1"
-            },
-            "form-data": {
-              "version": "0.0.8",
-              "from": "form-data@0.0.8",
-              "dependencies": {
-                "combined-stream": {
-                  "version": "0.0.4",
-                  "from": "combined-stream@0.0.4",
-                  "dependencies": {
-                    "delayed-stream": {
-                      "version": "0.0.5",
-                      "from": "delayed-stream@0.0.5"
-                    }
-                  }
-                },
-                "async": {
-                  "version": "0.2.10",
-                  "from": "async@0.2.10",
-                  "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
-                }
-              }
-            }
-          }
-        }
-      }
-    },
-    "q": {
-      "version": "0.9.7",
-      "from": "q@0.9.7"
-    },
-    "request": {
-      "version": "2.21.0",
-      "from": "request@2.21.0",
-      "dependencies": {
-        "qs": {
-          "version": "0.6.6",
-          "from": "qs@0.6.6"
-        },
-        "json-stringify-safe": {
-          "version": "4.0.0",
-          "from": "json-stringify-safe@4.0.0"
-        },
-        "forever-agent": {
-          "version": "0.5.2",
-          "from": "forever-agent@0.5.2"
-        },
-        "tunnel-agent": {
-          "version": "0.3.0",
-          "from": "tunnel-agent@0.3.0"
-        },
-        "http-signature": {
-          "version": "0.9.11",
-          "from": "http-signature@0.9.11",
-          "dependencies": {
-            "assert-plus": {
-              "version": "0.1.2",
-              "from": "assert-plus@0.1.2"
-            },
-            "asn1": {
-              "version": "0.1.11",
-              "from": "asn1@0.1.11"
-            },
-            "ctype": {
-              "version": "0.5.2",
-              "from": "ctype@0.5.2"
-            }
-          }
-        },
-        "hawk": {
-          "version": "0.13.1",
-          "from": "hawk@0.13.1",
-          "dependencies": {
-            "hoek": {
-              "version": "0.8.5",
-              "from": "hoek@0.8.5"
-            },
-            "boom": {
-              "version": "0.4.2",
-              "from": "boom@0.4.2",
-              "dependencies": {
-                "hoek": {
-                  "version": "0.9.1",
-                  "from": "hoek@0.9.1"
-                }
-              }
-            },
-            "cryptiles": {
-              "version": "0.2.2",
-              "from": "cryptiles@0.2.2"
-            },
-            "sntp": {
-              "version": "0.2.4",
-              "from": "sntp@0.2.4",
-              "dependencies": {
-                "hoek": {
-                  "version": "0.9.1",
-                  "from": "hoek@0.9.1"
-                }
-              }
-            }
-          }
-        },
-        "aws-sign": {
-          "version": "0.3.0",
-          "from": "aws-sign@0.3.0"
-        },
-        "oauth-sign": {
-          "version": "0.3.0",
-          "from": "oauth-sign@0.3.0"
-        },
-        "cookie-jar": {
-          "version": "0.3.0",
-          "from": "cookie-jar@0.3.0"
-        },
-        "node-uuid": {
-          "version": "1.4.1",
-          "from": "node-uuid@1.4.1"
-        },
-        "form-data": {
-          "version": "0.0.8",
-          "from": "form-data@0.0.8",
-          "dependencies": {
-            "combined-stream": {
-              "version": "0.0.4",
-              "from": "combined-stream@0.0.4",
-              "dependencies": {
-                "delayed-stream": {
-                  "version": "0.0.5",
-                  "from": "delayed-stream@0.0.5"
-                }
-              }
-            },
-            "async": {
-              "version": "0.2.10",
-              "from": "async@0.2.10"
-            }
-          }
-        }
-      }
-    },
-    "semver": {
-      "version": "2.0.11",
-      "from": "semver@2.0.11"
-    },
-    "shelljs": {
-      "version": "0.1.4",
-      "from": "shelljs@0.1.4"
-    },
-    "tar": {
-      "version": "0.1.19",
-      "from": "tar@0.1.19",
-      "dependencies": {
-        "inherits": {
-          "version": "2.0.1",
-          "from": "inherits@2.0.1"
-        },
-        "block-stream": {
-          "version": "0.0.7",
-          "from": "block-stream@0.0.7"
-        },
-        "fstream": {
-          "version": "0.1.25",
-          "from": "fstream@0.1.25",
-          "dependencies": {
-            "rimraf": {
-              "version": "2.2.6",
-              "from": "rimraf@2.2.6"
-            },
-            "mkdirp": {
-              "version": "0.3.5",
-              "from": "mkdirp@0.3.5"
-            },
-            "graceful-fs": {
-              "version": "2.0.2",
-              "from": "graceful-fs@2.0.2"
-            }
-          }
-        }
-      }
-    },
-    "underscore": {
-      "version": "1.4.4",
-      "from": "underscore@1.4.4"
-    },
-    "xcode": {
-      "version": "0.6.6",
-      "from": "xcode@0.6.6",
-      "dependencies": {
-        "pegjs": {
-          "version": "0.6.2",
-          "from": "pegjs@0.6.2"
-        },
-        "node-uuid": {
-          "version": "1.3.3",
-          "from": "node-uuid@1.3.3"
-        }
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1b3b1f03/spec/cli.spec.js
----------------------------------------------------------------------
diff --git a/spec/cli.spec.js b/spec/cli.spec.js
index c09042d..ec10815 100644
--- a/spec/cli.spec.js
+++ b/spec/cli.spec.js
@@ -19,8 +19,9 @@
 
 var CLI = require("../src/cli"),
     Q = require('q'),
-    plugman = require('plugman'),
-    cordova = require("../cordova");
+    cordova_lib = require('cordova-lib'),
+    plugman = cordova_lib.plugman,
+    cordova = cordova_lib.cordova;
 
 describe("cordova cli", function () {
     beforeEach(function () {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1b3b1f03/spec/help.spec.js
----------------------------------------------------------------------
diff --git a/spec/help.spec.js b/spec/help.spec.js
index 1cff29d..4ee0883 100644
--- a/spec/help.spec.js
+++ b/spec/help.spec.js
@@ -16,7 +16,9 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova');
+var cordova_lib = require('cordova-lib'),
+    cordova = cordova_lib.cordova,
+    help = require('../src/help');
 
 describe('help command', function() {
     it('should emit a results event with help contents', function(done) {
@@ -27,6 +29,6 @@ describe('help command', function() {
             expect(h).toMatch(/synopsis/gi);
             done();
         });
-        cordova.help();
+        help();
     });
 });

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1b3b1f03/src/cli.js
----------------------------------------------------------------------
diff --git a/src/cli.js b/src/cli.js
index 4c81892..a44673d 100644
--- a/src/cli.js
+++ b/src/cli.js
@@ -18,8 +18,8 @@
 */
 
 var path = require('path'),
-    CordovaError = require('./CordovaError'),
     optimist, // required in try-catch below to print a nice error message if it's not installed.
+    help = require('./help'),
     _;
 
 module.exports = function CLI(inputArgs) {
@@ -31,7 +31,10 @@ module.exports = function CLI(inputArgs) {
                       path.dirname(__dirname));
         process.exit(2);
     }
-    var cordova   = require('../cordova');
+    var cordova_lib = require('cordova-lib'),
+        CordovaError = cordova_lib.CordovaError,
+        cordova = cordova_lib.cordova,
+        plugman = cordova_lib.plugman;
 
     // If no inputArgs given, use process.argv.
     var tokens;
@@ -80,7 +83,6 @@ module.exports = function CLI(inputArgs) {
     if (!opts.silent) {
         cordova.on('log', console.log);
         cordova.on('warn', console.warn);
-        var plugman = require('plugman');
         plugman.on('log', console.log);
         plugman.on('results', console.log);
         plugman.on('warn', console.warn);
@@ -93,7 +95,7 @@ module.exports = function CLI(inputArgs) {
     if (opts.verbose) {
         // Add handlers for verbose logging.
         cordova.on('verbose', console.log);
-        require('plugman').on('verbose', console.log);
+        plugman.on('verbose', console.log);
 
         //Remove the corresponding token
         if(args.d && args.verbose) {
@@ -107,7 +109,7 @@ module.exports = function CLI(inputArgs) {
 
     var cmd = tokens && tokens.length ? tokens.splice(0,1) : undefined;
     if (cmd === undefined) {
-        return cordova.help();
+        return help();
     }
 
     if (!cordova.hasOwnProperty(cmd)) {
@@ -116,7 +118,7 @@ module.exports = function CLI(inputArgs) {
 
     if (cmd == 'emulate' || cmd == 'build' || cmd == 'prepare' || cmd == 'compile' || cmd == 'run') {
         // Filter all non-platforms into options
-        var platforms = require("../platforms");
+        var platforms = cordova_lib.cordova_platforms;
         tokens.forEach(function(option, index) {
             if (platforms.hasOwnProperty(option)) {
                 opts.platforms.push(option);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1b3b1f03/src/help.js
----------------------------------------------------------------------
diff --git a/src/help.js b/src/help.js
index f0bcb1a..45d400c 100644
--- a/src/help.js
+++ b/src/help.js
@@ -17,12 +17,13 @@
     under the License.
 */
 var fs = require('fs'),
-    events = require('./events'),
+    cordova_lib = require('cordova-lib'),
+    cordova = cordova_lib.cordova,
     Q = require('q'),
     path = require('path');
 
 module.exports = function help () {
     var raw = fs.readFileSync(path.join(__dirname, '..', 'doc', 'help.txt')).toString('utf8');
-    events.emit('results', raw);
+    cordova.emit('results', raw);
     return Q();
 };


[05/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/check_reqs.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/check_reqs.js b/spec/fixtures/platforms/android/cordova/lib/check_reqs.js
deleted file mode 100755
index c064499..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/check_reqs.js
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    fs    = require('fs'),
-    ROOT  = path.join(__dirname, '..', '..');
-
-// Get valid target from framework/project.properties
-module.exports.get_target = function() {
-    if(fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
-        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties'));
-        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
-    } else if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
-        // if no target found, we're probably in a project and project.properties is in ROOT.
-        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
-        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
-    }
-}
-
-module.exports.check_ant = function() {
-    var test = shell.exec('ant -version', {silent:true, async:false});
-    if(test.code > 0) {
-        console.error('ERROR : executing command \'ant\', make sure you have ant installed and added to your path.');
-        return false;
-    }
-    return true;
-}
-
-module.exports.check_java = function() {
-    if(process.env.JAVA_HOME) {
-        var test = shell.exec('java', {silent:true, async:false});
-        if(test.code > 0) {
-            console.error('ERROR : executing command \'java\', make sure you java environment is set up. Including your JDK and JRE.');
-            return false;
-        }
-        return true;
-    } else {
-        console.error('ERROR : Make sure JAVA_HOME is set, as well as paths to your JDK and JRE for java.');
-        return false;
-    }
-}
-
-module.exports.check_android = function() {
-    var valid_target = this.get_target();
-    var targets = shell.exec('android list targets', {silent:true, async:false});
-
-    if(targets.code > 0 && targets.output.match(/command\snot\sfound/)) {
-        console.error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.');
-        return false;
-    } else if(!targets.output.match(valid_target)) {
-        console.error('Please install Android target ' + valid_target.split('-')[1] + ' (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools.');
-        return false;
-    }
-    return true;
-}
-
-module.exports.run = function() {
-    return this.check_ant() && this.check_java && this.check_android();
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/clean.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/clean.js b/spec/fixtures/platforms/android/cordova/lib/clean.js
deleted file mode 100755
index 8f14015..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/clean.js
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    ROOT = path.join(__dirname, '..', '..');
-
-/*
- * Cleans the project using ant
- */
-module.exports.run = function() {
-    var cmd = 'ant clean -f ' + path.join(ROOT, 'build.xml');
-    var result = shell.exec(cmd, {silent:false, async:false});
-    if (result.code > 0) {
-        console.error('ERROR: Failed to clean android project.');
-        console.error(result.output);
-        process.exit(2);
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'clean')));
-    console.log('Cleans the project directory.');
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/device.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/device.js b/spec/fixtures/platforms/android/cordova/lib/device.js
deleted file mode 100755
index 363dc2b..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/device.js
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    build = require('./build'),
-    appinfo = require('./appinfo'),
-    exec  = require('child_process').exec,
-    ROOT = path.join(__dirname, '..', '..');
-
-/**
- * Returns a list of the device ID's found
- */
-module.exports.list = function() {
-    var cmd = 'adb devices';
-    var result = shell.exec(cmd, {silent:true, async:false});
-    if (result.code > 0) {
-        console.error('Failed to execute android command \'' + cmd + '\'.');
-        process.exit(2);
-    } else {
-        var response = result.output.split('\n');
-        var device_list = [];
-        for (var i = 1; i < response.length; i++) {
-            if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
-                device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
-            }
-        }
-        return device_list;
-    }
-}
-
-/*
- * Installs a previously built application on the device
- * and launches it.
- */
-module.exports.install = function(target) {
-    var device_list = this.list();
-    if (device_list.length > 0) {
-        // default device
-        target = typeof target !== 'undefined' ? target : device_list[0];
-        if (device_list.indexOf(target) > -1) {
-            var apk_path = build.get_apk();
-            var launchName = appinfo.getActivityName();
-            console.log('Installing app on device...');
-            cmd = 'adb -s ' + target + ' install -r ' + apk_path;
-            var install = shell.exec(cmd, {silent:false, async:false});
-            if (install.error || install.output.match(/Failure/)) {
-                console.error('ERROR : Failed to install apk to device : ');
-                console.error(install.output);
-                process.exit(2);
-            }
-
-            //unlock screen
-            cmd = 'adb -s ' + target + ' shell input keyevent 82';
-            shell.exec(cmd, {silent:true, async:false});
-
-            // launch the application
-            console.log('Launching application...');
-            cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
-            var launch = shell.exec(cmd, {silent:true, async:false});
-            if(launch.code > 0) {
-                console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
-                console.error(launch.output);
-                process.exit(2);
-            } else {
-                console.log('LAUNCH SUCCESS');
-            }
-        } else {
-            console.error('ERROR : Unable to find target \'' + target + '\'.');
-            console.error('Failed to deploy to device.');
-            process.exit(2);
-        }
-    } else {
-        console.error('ERROR : Failed to deploy to device, no devices found.');
-        process.exit(2);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/emulator.js b/spec/fixtures/platforms/android/cordova/lib/emulator.js
deleted file mode 100755
index cc658a9..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/emulator.js
+++ /dev/null
@@ -1,337 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    appinfo = require('./appinfo'),
-    build = require('./build'),
-    ROOT  = path.join(__dirname, '..', '..'),
-    new_emulator = 'cordova_emulator';
-
-/**
- * Returns a list of emulator images in the form of objects
- * {
-       name   : <emulator_name>,
-       path   : <path_to_emulator_image>,
-       target : <api_target>,
-       abi    : <cpu>,
-       skin   : <skin>
-   }
- */
-module.exports.list_images = function() {
-    var cmd = 'android list avds';
-    var result = shell.exec(cmd, {silent:true, async:false});
-    if (result.code > 0) {
-        console.error('Failed to execute android command \'' + cmd + '\'.');
-        process.exit(2);
-    } else {
-        var response = result.output.split('\n');
-        var emulator_list = [];
-        for (var i = 1; i < response.length; i++) {
-            // To return more detailed information use img_obj
-            var img_obj = {};
-            if (response[i].match(/Name:\s/)) {
-                img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
-                if (response[i + 1].match(/Path:\s/)) {
-                    i++;
-                    img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
-                }
-                if (response[i + 1].match(/\(API\slevel\s/)) {
-                    i++;
-                    img_obj['target'] = response[i].replace('\r', '');
-                }
-                if (response[i + 1].match(/ABI:\s/)) {
-                    i++;
-                    img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
-                }
-                if (response[i + 1].match(/Skin:\s/)) {
-                    i++;
-                    img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
-                }
-
-                emulator_list.push(img_obj);
-            }
-            /* To just return a list of names use this
-            if (response[i].match(/Name:\s/)) {
-                emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
-            }*/
-
-        }
-        return emulator_list;
-    }
-}
-
-/**
- * Will return the closest avd to the projects target
- * or undefined if no avds exist.
- */
-module.exports.best_image = function() {
-    var project_target = this.get_target().replace('android-', '');
-    var images = this.list_images();
-    var closest = 9999;
-    var best = images[0];
-    for (i in images) {
-        var target = images[i].target;
-        if(target) {
-            var num = target.split('(API level ')[1].replace(')', '');
-            if (num == project_target) {
-                return images[i];
-            } else if (project_target - num < closest && project_target > num) {
-                var closest = project_target - num;
-                best = images[i];
-            }
-        }
-    }
-    return best;
-}
-
-module.exports.list_started = function() {
-    var cmd = 'adb devices';
-    var result = shell.exec(cmd, {silent:true, async:false});
-    if (result.code > 0) {
-        console.error('Failed to execute android command \'' + cmd + '\'.');
-        process.exit(2);
-    } else {
-        var response = result.output.split('\n');
-        var started_emulator_list = [];
-        for (var i = 1; i < response.length; i++) {
-            if (response[i].match(/device/) && response[i].match(/emulator/)) {
-                started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
-            }
-        }
-        return started_emulator_list;
-    }
-}
-
-module.exports.get_target = function() {
-    var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
-    return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
-}
-
-module.exports.list_targets = function() {
-    var target_out = shell.exec('android list targets', {silent:true, async:false}).output.split('\n');
-    var targets = [];
-    for (var i = target_out.length; i >= 0; i--) {
-        if(target_out[i].match(/id:/)) {
-            targets.push(targets[i].split(' ')[1]);
-        }
-    }
-    return targets;
-}
-
-/*
- * Starts an emulator with the given ID,
- * and returns the started ID of that emulator.
- * If no ID is given it will used the first image availible,
- * if no image is availible it will error out (maybe create one?).
- */
-module.exports.start = function(emulator_ID) {
-    var started_emulators = this.list_started();
-    var num_started = started_emulators.length;
-    if (typeof emulator_ID === 'undefined') {
-        var emulator_list = this.list_images();
-        if (emulator_list.length > 0) {
-            emulator_ID = this.best_image().name;
-            console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID);
-        } else {
-            console.error('ERROR : No emulator images (avds) found, if you would like to create an');
-            console.error(' avd follow the instructions provided here : ');
-            console.error(' http://developer.android.com/tools/devices/index.html')
-            console.error(' Or run \'android create avd --name <name> --target <targetID>\' ');
-            console.error(' in on the command line.');
-            process.exit(2);
-            /*console.log('WARNING : no emulators availible, creating \'' + new_emulator + '\'.');
-            this.create_image(new_emulator, this.get_target());
-            emulator_ID = new_emulator;*/
-        }
-    }
-
-    var pipe_null = (process.platform == 'win32' || process.platform == 'win64'? '> NUL' : '> /dev/null');
-    var cmd = 'emulator -avd ' + emulator_ID + ' ' + pipe_null + ' &';
-    if(process.platform == 'win32' || process.platform == 'win64') {
-        cmd = '%comspec% /c start cmd /c ' + cmd;
-    }
-    var result = shell.exec(cmd, {silent:true, async:false}, function(code, output) {
-        if (code > 0) {
-            console.error('Failed to execute android command \'' + cmd + '\'.');
-            console.error(output);
-            process.exit(2);
-        }
-    });
-
-    // wait for emulator to start
-    console.log('Waiting for emulator...');
-    var new_started = this.wait_for_emulator(num_started);
-    var emulator_id;
-    if (new_started.length > 1) {
-        for (i in new_started) {
-            console.log(new_started[i]);
-            console.log(started_emulators.indexOf(new_started[i]));
-            if (started_emulators.indexOf(new_started[i]) < 0) {
-                emulator_id = new_started[i];
-            }
-        }
-    } else {
-        emulator_id = new_started[0];
-    }
-    if (!emulator_id) {
-        console.error('ERROR :  Failed to start emulator, could not find new emulator');
-        process.exit(2);
-    }
-
-    //wait for emulator to boot up
-    process.stdout.write('Booting up emulator (this may take a while)...');
-    this.wait_for_boot(emulator_id);
-    console.log('BOOT COMPLETE');
-
-    //unlock screen
-    cmd = 'adb -s ' + emulator_id + ' shell input keyevent 82';
-    shell.exec(cmd, {silent:false, async:false});
-
-    //return the new emulator id for the started emulators
-    return emulator_id;
-}
-
-/*
- * Waits for the new emulator to apear on the started-emulator list.
- */
-module.exports.wait_for_emulator = function(num_running) {
-    var new_started = this.list_started();
-    if (new_started.length > num_running) {
-        return new_started;
-    } else {
-        this.sleep(1);
-        return this.wait_for_emulator(num_running);
-    }
-}
-
-/*
- * Waits for the boot animation property of the emulator to switch to 'stopped'
- */
-module.exports.wait_for_boot = function(emulator_id) {
-    var cmd;
-    // ShellJS opens a lot of file handles, and the default on OS X is too small.
-    // TODO : This is not working, need to find a better way to increese the ulimit.
-    if(process.platform == 'win32' || process.platform == 'win64') {
-        cmd = 'adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
-    } else {
-        cmd = 'ulimit -S -n 4096; adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
-    }
-    var boot_anim = shell.exec(cmd, {silent:true, async:false});
-    if (boot_anim.output.match(/stopped/)) {
-        return;
-    } else {
-        process.stdout.write('.');
-        this.sleep(3);
-        return this.wait_for_boot(emulator_id);
-    }
-}
-
-/*
- * TODO : find a better way to wait for the emulator (maybe using async methods?)
- */
-module.exports.sleep = function(time_sec) {
-    if (process.platform == 'win32' || process.platform == 'win64') {
-        shell.exec('ping 127.0.0.1 -n ' + time_sec, {silent:true, async:false});
-    } else {
-        shell.exec('sleep ' + time_sec, {silent:true, async:false});
-    }
-}
-
-/*
- * Create avd
- * TODO : Enter the stdin input required to complete the creation of an avd.
- */
-module.exports.create_image = function(name, target) {
-    console.log('Creating avd named ' + name);
-    if (target) {
-        var cmd = 'android create avd --name ' + name + ' --target ' + target;
-        var create = shell.exec(cmd, {sient:false, async:false});
-        if (create.error) {
-            console.error('ERROR : Failed to create emulator image : ');
-            console.error(' Do you have the latest android targets including ' + target + '?');
-            console.error(create.output);
-            process.exit(2);
-        }
-    } else {
-        console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
-        var cmd = 'android create avd --name ' + name + ' --target ' + this.list_targets()[0];
-        var create = shell.exec(cmd, {sient:false, async:false});
-        if (create.error) {
-            console.error('ERROR : Failed to create emulator image : ');
-            console.error(create.output);
-            process.exit(2);
-        }
-        console.error('ERROR : Unable to create an avd emulator, no targets found.');
-        console.error('Please insure you have targets availible by runing the "android" command').
-        process.exit(2);
-    }
-}
-
-/*
- * Installs a previously built application on the emulator and launches it.
- * If no target is specified, then it picks one.
- * If no started emulators are found, error out.
- */
-module.exports.install = function(target) {
-    var emulator_list = this.list_started();
-    if (emulator_list.length < 1) {
-        console.error('ERROR : No started emulators found, please start an emultor before deploying your project.');
-        process.exit(2);
-        /*console.log('WARNING : No started emulators found, attemting to start an avd...');
-        this.start(this.best_image().name);*/
-    }
-    // default emulator
-    target = typeof target !== 'undefined' ? target : emulator_list[0];
-    if (emulator_list.indexOf(target) > -1) {
-        console.log('Installing app on emulator...');
-        var apk_path = build.get_apk();
-        var cmd = 'adb -s ' + target + ' install -r ' + apk_path;
-        var install = shell.exec(cmd, {sient:false, async:false});
-        if (install.error || install.output.match(/Failure/)) {
-            console.error('ERROR : Failed to install apk to emulator : ');
-            console.error(install.output);
-            process.exit(2);
-        }
-
-        //unlock screen
-        cmd = 'adb -s ' + target + ' shell input keyevent 82';
-        shell.exec(cmd, {silent:true, async:false});
-
-        // launch the application
-        console.log('Launching application...');
-        var launchName = appinfo.getActivityName();
-        cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
-        console.log(cmd);
-        var launch = shell.exec(cmd, {silent:false, async:false});
-        if(launch.code > 0) {
-            console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
-            console.error(launch.output);
-            process.exit(2);
-        } else {
-            console.log('LAUNCH SUCCESS');
-        }
-    } else {
-        console.error('ERROR : Unable to find target \'' + target + '\'.');
-        console.error('Failed to deploy to emulator.');
-        process.exit(2);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/install-device
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/install-device b/spec/fixtures/platforms/android/cordova/lib/install-device
deleted file mode 100755
index 679efbf..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/install-device
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var device = require('./device'),
-    args   = process.argv;
-
-if(args.length > 2) {
-    var install_target;
-    if (args[2].substring(0, 9) == '--target=') {
-        install_target = args[2].substring(9, args[2].length);
-        device.install(install_target);
-        process.exit(0);
-     } else {
-        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
-        process.exit(2);
-     }
-} else {
-    device.install();
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/install-emulator
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/install-emulator b/spec/fixtures/platforms/android/cordova/lib/install-emulator
deleted file mode 100755
index c006eb2..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/install-emulator
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulator = require('./emulator'),
-    args     = process.argv;
-
-if(args.length > 2) {
-    var install_target;
-    if (args[2].substring(0, 9) == '--target=') {
-        install_target = args[2].substring(9, args[2].length);
-        emulator.install(install_target);
-        process.exit(0);
-     } else {
-        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
-        process.exit(2);
-     }
-} else {
-    emulator.install();
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/list-devices
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/list-devices b/spec/fixtures/platforms/android/cordova/lib/list-devices
deleted file mode 100755
index 3ef4efa..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/list-devices
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var devices = require('./device');
-
-// Usage support for when args are given
-var device_list = devices.list();
-for(device in device_list) {
-    console.log(device_list[device]);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/list-emulator-images
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/list-emulator-images b/spec/fixtures/platforms/android/cordova/lib/list-emulator-images
deleted file mode 100755
index 3230537..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/list-emulator-images
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulators = require('./emulator');
-
-// Usage support for when args are given
-var emulator_list = emulators.list_images();
-for(emulator in emulator_list) {
-    console.log(emulator_list[emulator].name);
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/list-started-emulators
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/list-started-emulators b/spec/fixtures/platforms/android/cordova/lib/list-started-emulators
deleted file mode 100755
index 525a64c..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/list-started-emulators
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulators = require('./emulator');
-
-// Usage support for when args are given
-var emulator_list = emulators.list_started();
-for(emulator in emulator_list) {
-    console.log(emulator_list[emulator]);
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/log.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/log.js b/spec/fixtures/platforms/android/cordova/lib/log.js
deleted file mode 100755
index b85cf60..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/log.js
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    ROOT = path.join(__dirname, '..', '..');
-
-/*
- * Starts running logcat in the shell.
- */
-module.exports.run = function() {
-    var cmd = 'adb logcat | grep -v nativeGetEnabledTags';
-    var result = shell.exec(cmd, {silent:false, async:false});
-    if (result.code > 0) {
-        console.error('ERROR: Failed to run logcat command.');
-        console.error(result.output);
-        process.exit(2);
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'log')));
-    console.log('Gives the logcat output on the command line.');
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/run.js b/spec/fixtures/platforms/android/cordova/lib/run.js
deleted file mode 100755
index 787d123..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/run.js
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var path  = require('path'),
-    build = require('./build'),
-    emulator = require('./emulator'),
-    device   = require('./device'),
-    ROOT = path.join(__dirname, '..', '..');
-
-/*
- * Runs the application on a device if availible.
- * If not device is found, it will use a started emulator.
- * If no started emulators are found it will attempt to start an avd.
- * If no avds are found it will error out.
- */
- module.exports.run = function(args) {
-    var build_type;
-    var install_target;
-
-    for (var i=2; i<args.length; i++) {
-        if (args[i] == '--debug') {
-            build_type = '--debug';
-        } else if (args[i] == '--release') {
-            build_type = '--release';
-        } else if (args[i] == '--nobuild') {
-            build_type = '--nobuild';
-        } else if (args[i] == '--device') {
-            install_target = '--device';
-        } else if (args[i] == '--emulator') {
-            install_target = '--emulator';
-        } else if (args[i].substring(0, 9) == '--target=') {
-            install_target = args[i].substring(9, args[i].length);
-        } else {
-            console.error('ERROR : Run option \'' + args[i] + '\' not recognized.');
-            process.exit(2);
-        }
-    }
-    build.run(build_type);
-    if (install_target == '--device') {
-        device.install();
-    } else if (install_target == '--emulator') {
-        if (emulator.list_started() == 0) {
-            emulator.start();
-        }
-        emulator.install();
-    } else if (install_target) {
-        var devices = device.list();
-        var started_emulators = emulator.list_started();
-        var avds = emulator.list_images();
-        if (devices.indexOf(install_target) > -1) {
-            device.install(install_target);
-        } else if (started_emulators.indexOf(install_target) > -1) {
-            emulator.install(install_target);
-        } else {
-            // if target emulator isn't started, then start it.
-            var emulator_ID;
-            for(avd in avds) {
-                if(avds[avd].name == install_target) {
-                    emulator_ID = emulator.start(install_target);
-                    emulator.install(emulator_ID);
-                    break;
-                }
-            }
-            if(!emulator_ID) {
-                console.error('ERROR : Target \'' + install_target + '\' not found, unalbe to run project');
-                process.exit(2);
-            }
-        }
-    } else {
-        // no target given, deploy to device if availible, otherwise use the emulator.
-        var device_list = device.list();
-        if (device_list.length > 0) {
-            console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.');
-            device.install(device_list[0])
-        } else {
-            var emulator_list = emulator.list_started();
-            if (emulator_list.length > 0) {
-                console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.');
-                emulator.install(emulator_list[0]);
-            } else {
-                console.log('WARNING : No started emulators found, starting an emulator.');
-                var best_avd = emulator.best_image();
-                if(best_avd) {
-                    var emulator_ID = emulator.start(best_avd.name);
-                    console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.');
-                    emulator.install(emulator_ID);
-                } else {
-                    emulator.start();
-                }
-            }
-        }
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'run')) + ' [options]');
-    console.log('Build options :');
-    console.log('    --debug : Builds project in debug mode');
-    console.log('    --release : Builds project in release mode');
-    console.log('    --nobuild : Runs the currently built project without recompiling');
-    console.log('Deploy options :');
-    console.log('    --device : Will deploy the built project to a device');
-    console.log('    --emulator : Will deploy the built project to an emulator if one exists');
-    console.log('    --target=<target_id> : Installs to the target with the specified id.');
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/lib/start-emulator
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/lib/start-emulator b/spec/fixtures/platforms/android/cordova/lib/start-emulator
deleted file mode 100755
index 5d6c4dd..0000000
--- a/spec/fixtures/platforms/android/cordova/lib/start-emulator
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulator = require('./emulator'),
-      args   = process.argv;
-
-if(args.length > 2) {
-    var install_target;
-    if (args[2].substring(0, 9) == '--target=') {
-        install_target = args[2].substring(9, args[2].length);
-        emulator.start(install_target);
-        process.exit(0);
-     } else {
-        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
-        process.exit(2);
-     }
-} else {
-    emulator.start();
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/log
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/log b/spec/fixtures/platforms/android/cordova/log
deleted file mode 100755
index 087325f..0000000
--- a/spec/fixtures/platforms/android/cordova/log
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var log  = require('./lib/log'),
-    reqs = require('./lib/check_reqs'),
-    args = process.argv;
-
-// Usage support for when args are given
-if(args.length > 2) {
-    log.help();
-} else if(reqs.run()) {
-    log.run();
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/run
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/run b/spec/fixtures/platforms/android/cordova/run
deleted file mode 100755
index 57d7345..0000000
--- a/spec/fixtures/platforms/android/cordova/run
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var run  = require('./lib/run'),
-    reqs = require('./lib/check_reqs'),
-    args = process.argv;
-
-// Support basic help commands
-if (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
-                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
-    run.help();
-} else if(reqs.run()) {
-    run.run(args);
-    process.exit(0);
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/cordova/version
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/cordova/version b/spec/fixtures/platforms/android/cordova/version
deleted file mode 100755
index de1a76d..0000000
--- a/spec/fixtures/platforms/android/cordova/version
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-// Coho updates this line:
-var VERSION = "3.1.0";
-
-console.log(VERSION);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/local.properties
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/local.properties b/spec/fixtures/platforms/android/local.properties
deleted file mode 100644
index d3f5072..0000000
--- a/spec/fixtures/platforms/android/local.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must *NOT* be checked into Version Control Systems,
-# as it contains information specific to your local configuration.
-
-# location of the SDK. This is only used by Ant
-# For customization when using a Version Control System, please read the
-# header note.
-sdk.dir=/Users/braden/cordova/android/android-sdk-macosx

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/proguard-project.txt
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/proguard-project.txt b/spec/fixtures/platforms/android/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/spec/fixtures/platforms/android/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/project.properties
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/project.properties b/spec/fixtures/platforms/android/project.properties
deleted file mode 100644
index a3ee5ab..0000000
--- a/spec/fixtures/platforms/android/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-17

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/res/drawable-hdpi/icon.png
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/res/drawable-hdpi/icon.png b/spec/fixtures/platforms/android/res/drawable-hdpi/icon.png
deleted file mode 100644
index 4d27634..0000000
Binary files a/spec/fixtures/platforms/android/res/drawable-hdpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/res/drawable-ldpi/icon.png
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/res/drawable-ldpi/icon.png b/spec/fixtures/platforms/android/res/drawable-ldpi/icon.png
deleted file mode 100644
index cd5032a..0000000
Binary files a/spec/fixtures/platforms/android/res/drawable-ldpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/res/drawable-mdpi/icon.png
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/res/drawable-mdpi/icon.png b/spec/fixtures/platforms/android/res/drawable-mdpi/icon.png
deleted file mode 100644
index e79c606..0000000
Binary files a/spec/fixtures/platforms/android/res/drawable-mdpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/res/drawable-xhdpi/icon.png
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/res/drawable-xhdpi/icon.png b/spec/fixtures/platforms/android/res/drawable-xhdpi/icon.png
deleted file mode 100644
index ec7ffbf..0000000
Binary files a/spec/fixtures/platforms/android/res/drawable-xhdpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/res/drawable/icon.png
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/res/drawable/icon.png b/spec/fixtures/platforms/android/res/drawable/icon.png
deleted file mode 100644
index ec7ffbf..0000000
Binary files a/spec/fixtures/platforms/android/res/drawable/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/res/values/strings.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/res/values/strings.xml b/spec/fixtures/platforms/android/res/values/strings.xml
deleted file mode 100644
index 1e706b3..0000000
--- a/spec/fixtures/platforms/android/res/values/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<resources>
-    <string name="app_name">TestBase</string>
-</resources>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/res/xml/config.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/res/xml/config.xml b/spec/fixtures/platforms/android/res/xml/config.xml
deleted file mode 100644
index 17ca237..0000000
--- a/spec/fixtures/platforms/android/res/xml/config.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <name>Hello Cordova</name>
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-    <access origin="*" />
-    <preference name="loglevel" value="DEBUG" />
-    <feature name="App">
-        <param name="android-package" value="org.apache.cordova.App" />
-    </feature>
-    <author email="dev@cordova.apache.org" href="http://cordova.io">
-        Apache Cordova Team
-    </author>
-    <content src="index.html" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/src/org/testing/TestBase.java
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/src/org/testing/TestBase.java b/spec/fixtures/platforms/android/src/org/testing/TestBase.java
deleted file mode 100644
index 928e074..0000000
--- a/spec/fixtures/platforms/android/src/org/testing/TestBase.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
- */
-
-package org.testing;
-
-import android.os.Bundle;
-import org.apache.cordova.*;
-
-public class TestBase extends CordovaActivity 
-{
-    @Override
-    public void onCreate(Bundle savedInstanceState)
-    {
-        super.onCreate(savedInstanceState);
-        super.init();
-        // Set by <content src="index.html" /> in config.xml
-        super.loadUrl(Config.getStartUrl());
-        //super.loadUrl("file:///android_asset/www/index.html")
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/ChildBrowser/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/ChildBrowser/plugin.xml b/spec/fixtures/plugins/ChildBrowser/plugin.xml
deleted file mode 100644
index 512c02f..0000000
--- a/spec/fixtures/plugins/ChildBrowser/plugin.xml
+++ /dev/null
@@ -1,142 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright 2013 Anis Kadri
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-
--->
-
-<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    id="com.phonegap.plugins.childbrowser"
-    version="0.6.0">
-
-    <name>Child Browser</name>
-
-    <asset src="www/childbrowser" target="childbrowser" />
-    <asset src="www/childbrowser_file.html" target="childbrowser_file.html" />
-
-    <js-module src="www/childbrowser.js" name="ChildBrowser">
-        <clobbers target="childbrowser" />
-    </js-module>
-
-    <config-file target="config.xml" parent="/*">
-        <access origin="build.phonegap.com" />
-        <access origin="s3.amazonaws.com" />
-    </config-file>
-    
-    <info>No matter what platform you are installing to, this notice is very important.</info>
-
-    <!-- android -->
-    <platform name="android">
-        <config-file target="AndroidManifest.xml" parent="/manifest/application">
-            <activity android:name="com.phonegap.plugins.childBrowser.ChildBrowser"
-                      android:label="@string/app_name">
-                <intent-filter>
-                </intent-filter>
-            </activity>
-        </config-file>
-
-        <!-- CDV < 2.0 -->
-        <config-file target="res/xml/plugins.xml" parent="/plugins">
-            <plugin name="ChildBrowser"
-                value="com.phonegap.plugins.childBrowser.ChildBrowser"/>
-        </config-file>
-
-        <!-- CDV 2.0+ (for now) -->
-        <config-file target="res/xml/config.xml" parent="/cordova/plugins">
-            <plugin name="ChildBrowser"
-                value="com.phonegap.plugins.childBrowser.ChildBrowser"/>
-        </config-file>
-
-        <source-file src="src/android/ChildBrowser.java"
-                target-dir="src/com/phonegap/plugins/childBrowser" />
-        <info>Please make sure you read this because it is very important to complete the installation of your plugin.</info>
-    </platform>
-
-    <!-- ios -->
-    <platform name="ios">
-        <plugins-plist key="com.phonegap.plugins.childbrowser"
-            string="ChildBrowserCommand" />
-
-        <config-file target="config.xml" parent="/widget/plugins">
-            <plugin name="ChildBrowser"
-                value="ChildBrowserCommand" />
-        </config-file>
-
-        <resource-file src="src/ios/ChildBrowser.bundle" />
-        <resource-file src="src/ios/ChildBrowserViewController.xib" />
-
-        <config-file target="*-Info.plist" parent="AppId">
-            <string>$APP_ID</string>
-        </config-file>
-        
-        <config-file target="*-Info.plist" parent="CFBundleURLTypes">
-            <array>
-              <dict>
-                <key>PackageName</key>
-                <string>$PACKAGE_NAME</string>
-              </dict>
-            </array>
-        </config-file>
-
-        <header-file src="src/ios/ChildBrowserCommand.h" />
-        <header-file src="src/ios/ChildBrowserViewController.h" />
-        <header-file src="src/ios/TargetDirTest.h" target-dir="targetDir"/>
-
-        <source-file src="src/ios/ChildBrowserCommand.m" />
-        <source-file src="src/ios/ChildBrowserViewController.m" />
-        <source-file src="src/ios/preserveDirs/PreserveDirsTest.m" preserve-dirs="true" />
-        <header-file src="src/ios/TargetDirTest.m" target-dir="targetDir"/>
-
-        <!-- framework for testing (not actual dependency of ChildBrowser -->
-        <framework src="libsqlite3.dylib" />
-        <framework src="social.framework" weak="true" />
-        <framework src="music.framework" weak="rabbit" />
-    </platform>
-    <!-- wp7 -->
-    <platform name="wp7">
-        <resource-file src="src\wp7\Images\appbar.back.rest.png" />
-        <config-file target="config.xml" parent="/widget/plugins">
-            <plugin name="ChildBrowser"
-                value="ChildBrowser"/>
-        </config-file>
-
-        <source-file src="src\wp7\ChildBrowserCommand.cs"
-                     target-dir="Plugins\" />
-
-        <!-- modify the project file to include the added files -->
-        <config-file target=".csproj" parent=".">  
-        </config-file> 
-
-    </platform>
-
-    <!-- wp8 -->
-    <platform name="wp8">
-        <resource-file src="src\wp7\Images\appbar.back.rest.png" />
-        <config-file target="config.xml" parent="/widget/plugins">
-            <plugin name="ChildBrowser"
-                value="ChildBrowser"/>
-        </config-file>
-
-        <source-file src="src\wp7\ChildBrowserCommand.cs"
-                     target-dir="Plugins\" />
-
-        <!-- modify the project file to include the added files -->
-        <config-file target=".csproj" parent=".">  
-        </config-file> 
-
-    </platform>
-</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java b/spec/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
deleted file mode 100644
index 5263b0c..0000000
--- a/spec/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *
- * Copyright 2013 Anis Kadri
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/ChildBrowser/www/childbrowser.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/ChildBrowser/www/childbrowser.js b/spec/fixtures/plugins/ChildBrowser/www/childbrowser.js
deleted file mode 100644
index 5263b0c..0000000
--- a/spec/fixtures/plugins/ChildBrowser/www/childbrowser.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *
- * Copyright 2013 Anis Kadri
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg b/spec/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
deleted file mode 100644
index 257cc56..0000000
--- a/spec/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
+++ /dev/null
@@ -1 +0,0 @@
-foo

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/ChildBrowser/www/childbrowser_file.html b/spec/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
deleted file mode 100644
index 6de7b8c..0000000
--- a/spec/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
+++ /dev/null
@@ -1 +0,0 @@
-This is a test file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/android/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/android/plugin.xml b/spec/fixtures/plugins/android/plugin.xml
deleted file mode 100644
index d8f5619..0000000
--- a/spec/fixtures/plugins/android/plugin.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    id="ca.filmaj.AndroidPlugin"
-    version="4.2.0">
-
-    <name>Android Plugin</name>
-
-    <asset src="www/android.js" target="android.js" />
-    <platform name="android">
-    </platform>
-</plugin>
-
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/android/src/android/Android.java
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/android/src/android/Android.java b/spec/fixtures/plugins/android/src/android/Android.java
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/android/src/android/SomethingWithR.java
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/android/src/android/SomethingWithR.java b/spec/fixtures/plugins/android/src/android/SomethingWithR.java
deleted file mode 100644
index c3af060..0000000
--- a/spec/fixtures/plugins/android/src/android/SomethingWithR.java
+++ /dev/null
@@ -1,6 +0,0 @@
-import com.yourapp.R;
-
-import android.app.*;
-
-public class SomethingWithR {
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/android/www/android.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/android/www/android.js b/spec/fixtures/plugins/android/www/android.js
deleted file mode 100644
index e69de29..0000000

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

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/test/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/test/plugin.xml b/spec/fixtures/plugins/test/plugin.xml
deleted file mode 100644
index 774eda1..0000000
--- a/spec/fixtures/plugins/test/plugin.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    id="com.phonegap.plugins.childbrowser"
-    version="3.0.0">
-
-    <name>Test Plugin</name>
-
-    <asset src="www/test.js" target="test.js" />
-    <platform name="ios">
-        <plugins-plist key="TestPlugin" string="Test" />
-    </platform>
-</plugin>
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/plugins/test/www/test.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/plugins/test/www/test.js b/spec/fixtures/plugins/test/www/test.js
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/projects/android/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/projects/android/AndroidManifest.xml b/spec/fixtures/projects/android/AndroidManifest.xml
deleted file mode 100644
index 0c52803..0000000
--- a/spec/fixtures/projects/android/AndroidManifest.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
- Copyright 2013 Anis Kadri
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
-      package="com.alunny.childapp" android:versionName="1.1" android:versionCode="5">
-    <supports-screens
-    	android:largeScreens="true"
-    	android:normalScreens="true"
-    	android:smallScreens="true"
-    	android:xlargeScreens="true"
-    	android:resizeable="true"
-    	android:anyDensity="true"
-    	/>
-
-    <uses-permission android:name="android.permission.CAMERA" />
-    <uses-permission android:name="android.permission.VIBRATE" />
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.RECEIVE_SMS" />
-    <uses-permission android:name="android.permission.RECORD_AUDIO" />
-    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
-    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />   
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />   
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-
-    <uses-feature android:name="android.hardware.camera" />
-    <uses-feature android:name="android.hardware.camera.autofocus" />
-
-    <application android:icon="@drawable/icon" android:label="@string/app_name"
-    	android:debuggable="true">
-		<activity android:name="ChildApp" android:label="@string/app_name" 
-				  android:configChanges="orientation|keyboardHidden">
-			<intent-filter>
-				<action android:name="android.intent.action.MAIN" />
-				<category android:name="android.intent.category.LAUNCHER" />
-			</intent-filter>
-        </activity>
-        <activity android:name="com.phonegap.DroidGap" android:label="@string/app_name" 
-            	  android:configChanges="orientation|keyboardHidden">
-        	<intent-filter>
-        	</intent-filter>
-        </activity>
-    </application>
-
-	<uses-sdk android:minSdkVersion="5" />
-</manifest> 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/projects/android/assets/www/.gitkeep
----------------------------------------------------------------------
diff --git a/spec/fixtures/projects/android/assets/www/.gitkeep b/spec/fixtures/projects/android/assets/www/.gitkeep
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/projects/android/res/xml/config.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/projects/android/res/xml/config.xml b/spec/fixtures/projects/android/res/xml/config.xml
deleted file mode 100644
index d37aba5..0000000
--- a/spec/fixtures/projects/android/res/xml/config.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
--->
-<cordova>
-    <!--
-    access elements control the Android whitelist.
-    Domains are assumed blocked unless set otherwise
-     -->
-
-    <access origin="http://127.0.0.1*"/> <!-- allow local pages -->
-
-    <!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
-    <!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
-    <!-- <access origin=".*"/> Allow all domains, suggested development use only -->
-
-    <log level="DEBUG"/>
-    <preference name="useBrowserHistory" value="false" />
-<plugins>
-    <plugin name="App" value="org.apache.cordova.App"/>
-    <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
-    <plugin name="Device" value="org.apache.cordova.Device"/>
-    <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
-    <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
-    <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
-    <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
-    <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
-    <plugin name="File" value="org.apache.cordova.FileUtils"/>
-    <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
-    <plugin name="Notification" value="org.apache.cordova.Notification"/>
-    <plugin name="Storage" value="org.apache.cordova.Storage"/>
-    <plugin name="Temperature" value="org.apache.cordova.TempListener"/>
-    <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
-    <plugin name="Capture" value="org.apache.cordova.Capture"/>
-    <plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
-    <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
-</plugins>
-</cordova>
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/projects/android/src/.gitkeep
----------------------------------------------------------------------
diff --git a/spec/fixtures/projects/android/src/.gitkeep b/spec/fixtures/projects/android/src/.gitkeep
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/projects/windows/bom_test.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/projects/windows/bom_test.xml b/spec/fixtures/projects/windows/bom_test.xml
deleted file mode 100644
index 57cadf6..0000000
--- a/spec/fixtures/projects/windows/bom_test.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-# http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
--->
-<widget>
-    <access origin="*"/>
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/templates/no_content_config.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/templates/no_content_config.xml b/spec/fixtures/templates/no_content_config.xml
deleted file mode 100644
index 7c4ef3d..0000000
--- a/spec/fixtures/templates/no_content_config.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
-        id        = "io.cordova.hellocordova"
-        version   = "0.0.1">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/helper.js
----------------------------------------------------------------------
diff --git a/spec/helper.js b/spec/helper.js
deleted file mode 100644
index 351e6e4..0000000
--- a/spec/helper.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/helpers.js
----------------------------------------------------------------------
diff --git a/spec/helpers.js b/spec/helpers.js
deleted file mode 100644
index 3236516..0000000
--- a/spec/helpers.js
+++ /dev/null
@@ -1,46 +0,0 @@
-
-var path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    os = require('os');
-
-module.exports.tmpDir = function(subdir) {
-    var dir = path.join(os.tmpdir(), 'e2e-test');
-    if (subdir) {
-        dir = path.join(dir, subdir);
-    }
-    shell.mkdir('-p', dir);
-    return dir;
-};
-
-// Returns the platform that should be used for testing on this host platform.
-/*
-var host = os.platform();
-if (host.match(/win/)) {
-    module.exports.testPlatform = 'wp8';
-} else if (host.match(/darwin/)) {
-    module.exports.testPlatform = 'ios';
-} else {
-    module.exports.testPlatform = 'android';
-}
-*/
-
-// Just use Android everywhere; we're mocking out any calls to the `android` binary.
-module.exports.testPlatform = 'android';
-
-// Add the toExist matcher.
-beforeEach(function() {
-    this.addMatchers({
-        'toExist': function() {
-            var notText = this.isNot ? ' not' : '';
-            var self = this;
-
-            this.message = function() {
-                return 'Expected file ' + self.actual + notText + ' to exist.';
-            };
-
-            return fs.existsSync(this.actual);
-        }
-    });
-});
-


[18/24] Remove all cordova-lib files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/plugin.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/plugin.spec.js b/cordova-lib/spec-cordova/plugin.spec.js
deleted file mode 100644
index 2ad7b08..0000000
--- a/cordova-lib/spec-cordova/plugin.spec.js
+++ /dev/null
@@ -1,68 +0,0 @@
-
-var helpers = require('./helpers'),
-    path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    Q = require('q'),
-    events = require('../src/events'),
-    cordova = require('../cordova');
-
-var tmpDir = helpers.tmpDir('plugin_test');
-var project = path.join(tmpDir, 'project');
-var pluginsDir = path.join(__dirname, 'fixtures', 'plugins');
-var pluginId = 'org.apache.cordova.fakeplugin1';
-
-describe('plugin end-to-end', function() {
-    var results;
-
-    beforeEach(function() {
-        shell.rm('-rf', project);
-    });
-    afterEach(function() {
-        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
-        shell.rm('-rf', tmpDir);
-    });
-
-    // The flow tested is: ls, add, ls, rm, ls.
-    // Plugin dependencies are not tested as that should be corvered in plugman tests.
-    // TODO (kamrik): Test the 'plugin search' command.
-    it('should successfully run', function(done) {
-        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
-        // Using /* doesn't work because of hidden files.
-        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
-        shell.mv(path.join(tmpDir, 'base'), project);
-        // Copy some platform to avoid working on a project with no platforms.
-        shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform), path.join(project, 'platforms'));
-        process.chdir(project);
-
-        events.on('results', function(res) { results = res; });
-
-        // Check there are no plugins yet.
-        cordova.raw.plugin('list').then(function() {
-            expect(results).toMatch(/No plugins added/gi);
-        }).then(function() {
-            // Add a fake plugin from fixtures.
-            return cordova.raw.plugin('add', path.join(pluginsDir, 'fake1'));
-        }).then(function() {
-           expect(path.join(project, 'plugins', pluginId, 'plugin.xml')).toExist();
-        }).then(function() {
-            return cordova.raw.plugin('ls');
-        }).then(function() {
-            expect(results).toContain(pluginId);
-            expect(results.length).toEqual(1);
-        }).then(function() {
-            // And now remove it.
-            return cordova.raw.plugin('rm', pluginId);
-        }).then(function() {
-            // The whole dir should be gone.
-            expect(path.join(project, 'plugins', pluginId)).not.toExist();
-        }).then(function() {
-            return cordova.raw.plugin('ls');
-        }).then(function() {
-            expect(results).toMatch(/No plugins added/gi);
-        }).fail(function(err) {
-            console.log(err);
-            expect(err).toBeUndefined();
-        }).fin(done);
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/plugin_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/plugin_parser.spec.js b/cordova-lib/spec-cordova/plugin_parser.spec.js
deleted file mode 100644
index 9a63154..0000000
--- a/cordova-lib/spec-cordova/plugin_parser.spec.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    path = require('path'),
-    fs = require('fs'),
-    plugin_parser = require('../src/plugin_parser'),
-    et = require('elementtree'),
-    xml = path.join(__dirname, 'fixtures', 'plugins', 'test', 'plugin.xml');
-
-var xml_contents = fs.readFileSync(xml, 'utf-8');
-
-describe('plugin.xml parser', function () {
-    var readfile;
-    beforeEach(function() {
-        readfile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
-    });
-
-    it('should read a proper plugin.xml file', function() {
-        var cfg;
-        expect(function () {
-            cfg = new plugin_parser(xml);
-        }).not.toThrow();
-        expect(cfg).toBeDefined();
-        expect(cfg.doc).toBeDefined();
-    });
-    it('should be able to figure out which platforms the plugin supports', function() {
-        var cfg = new plugin_parser(xml);
-        expect(cfg.platforms.length).toBe(1);
-        expect(cfg.platforms.indexOf('ios') > -1).toBe(true);
-    });
-});
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/prepare.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/prepare.spec.js b/cordova-lib/spec-cordova/prepare.spec.js
deleted file mode 100644
index eac225d..0000000
--- a/cordova-lib/spec-cordova/prepare.spec.js
+++ /dev/null
@@ -1,290 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    shell = require('shelljs'),
-    plugman = require('plugman'),
-    path = require('path'),
-    fs = require('fs'),
-    util = require('../src/util'),
-    prepare = require('../src/prepare'),
-    lazy_load = require('../src/lazy_load'),
-    ConfigParser = require('../src/ConfigParser'),
-    platforms = require('../platforms'),
-    hooker = require('../src/hooker'),
-    xmlHelpers = require('../src/xml-helpers'),
-    fixtures = path.join(__dirname, 'fixtures'),
-    et = require('elementtree'),
-    Q = require('q'),
-    hooks = path.join(fixtures, 'hooks');
-
-var project_dir = '/some/path';
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-var supported_platforms_paths = supported_platforms.map(function(p) { return path.join(project_dir, 'platforms', p, 'www'); });
-
-var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
-    '<widget xmlns     = "http://www.w3.org/ns/widgets"\n' +
-    '        xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
-    '        id        = "io.cordova.hellocordova"\n' +
-    '        version   = "0.0.1">\n' +
-    '    <name>Hello Cordova</name>\n' +
-    '    <description>\n' +
-    '        A sample Apache Cordova application that responds to the deviceready event.\n' +
-    '    </description>\n' +
-    '    <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
-    '        Apache Cordova Team\n' +
-    '    </author>\n' +
-    '    <content src="index.html" />\n' +
-    '    <access origin="*" />\n' +
-    '    <preference name="fullscreen" value="true" />\n' +
-    '    <preference name="webviewbounce" value="true" />\n' +
-    '</widget>\n';
-
-describe('prepare command', function() {
-    var is_cordova,
-        cd_project_root,
-        list_platforms,
-        fire,
-        parsers = {},
-        plugman_prepare,
-        find_plugins,
-        plugman_get_json,
-        cp,
-        mkdir,
-        load;
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        supported_platforms.forEach(function(p) {
-            parsers[p] = jasmine.createSpy(p + ' update_project').andReturn(Q());
-            spyOn(platforms[p], 'parser').andReturn({
-                update_project:parsers[p],
-                update_www: jasmine.createSpy(p + ' update_www'),
-                cordovajs_path: function(libDir) { return 'path/to/cordova.js/in/.cordova/lib';},
-                www_dir:function() { return path.join(project_dir, 'platforms', p, 'www'); },
-                config_xml: function () { return path.join(project_dir, "platforms", p, "www", "config.xml");}
-            });
-        });
-        plugman_prepare = spyOn(plugman, 'prepare').andReturn(Q());
-        find_plugins = spyOn(util, 'findPlugins').andReturn([]);
-        plugman_get_json = spyOn(plugman.config_changes, 'get_platform_json').andReturn({
-            prepare_queue:{installed:[], uninstalled:[]},
-            config_munge:{},
-            installed_plugins:{},
-            dependent_plugins:{}
-        });
-        load = spyOn(lazy_load, 'based_on_config').andReturn(Q());
-        cp = spyOn(shell, 'cp').andReturn(true);
-        mkdir = spyOn(shell, 'mkdir');
-        spyOn(prepare, '_mergeXml');
-        spyOn(ConfigParser.prototype, 'write');
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function() {
-            return new et.ElementTree(et.XML(TEST_XML));
-        });
-    });
-
-    describe('failure', function() {
-        it('should not run outside of a cordova-based project by calling util.isCordova', function(done) {
-            is_cordova.andReturn(false);
-            Q().then(prepare).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect('' + err).toContain('Current working directory is not a Cordova-based project.');
-            }).fin(done);
-        });
-        it('should not run inside a cordova-based project with no platforms', function(done) {
-            list_platforms.andReturn([]);
-            Q().then(prepare).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect('' + err).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            }).fin(done);
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project by calling util.isCordova', function(done) {
-            prepare().then(function() {
-                expect(is_cordova).toHaveBeenCalled();
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should invoke each platform\'s parser\'s update_project method', function(done) {
-            prepare().then(function() {
-                supported_platforms.forEach(function(p) {
-                    expect(parsers[p]).toHaveBeenCalled();
-                });
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should invoke lazy_load for each platform to make sure platform libraries are loaded', function(done) {
-            prepare().then(function() {
-                supported_platforms.forEach(function(p) {
-                    expect(load).toHaveBeenCalledWith(project_dir, p);
-                });
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        describe('plugman integration', function() {
-            it('should invoke plugman.prepare after update_project', function(done) {
-                prepare().then(function() {
-                    var plugins_dir = path.join(project_dir, 'plugins');
-                    supported_platforms.forEach(function(p) {
-                        var platform_path = path.join(project_dir, 'platforms', p);
-                        expect(plugman_prepare).toHaveBeenCalledWith(platform_path, (p=='blackberry'?'blackberry10':p), plugins_dir);
-                    });
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module, and pass in platforms and paths as data object', function(done) {
-                prepare().then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_prepare', {verbose: false, platforms:supported_platforms, options: [], paths:supported_platforms_paths});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-            it('should fire after hooks through the hooker module, and pass in platforms and paths as data object', function(done) {
-                prepare('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_prepare', {verbose: false, platforms:['android'], options: [], paths:[path.join(project_dir, 'platforms', 'android', 'www')]});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-
-        describe('with no platforms added', function() {
-            beforeEach(function() {
-                list_platforms.andReturn([]);
-            });
-            it('should not fire the hooker', function(done) {
-                Q().then(prepare).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(err).toEqual(jasmine.any(Error));
-                    expect(fire).not.toHaveBeenCalledWith('before_prepare');
-                    expect(fire).not.toHaveBeenCalledWith('after_prepare');
-                }).fin(done);
-            });
-        });
-    });
-});
-
-describe('prepare._mergeXml', function () {
-    var dstXml;
-    beforeEach(function() {
-        dstXml = et.XML(TEST_XML);
-    });
-    it("should merge attributes and text of the root element without clobbering", function () {
-        var testXml = et.XML("<widget foo='bar' id='NOTANID'>TEXT</widget>");
-        prepare._mergeXml(testXml, dstXml);
-        expect(dstXml.attrib.foo).toEqual("bar");
-        expect(dstXml.attrib.id).not.toEqual("NOTANID");
-        expect(dstXml.text).not.toEqual("TEXT");
-    });
-
-    it("should merge attributes and text of the root element with clobbering", function () {
-        var testXml = et.XML("<widget foo='bar' id='NOTANID'>TEXT</widget>");
-        prepare._mergeXml(testXml, dstXml, "foo", true);
-        expect(dstXml.attrib.foo).toEqual("bar");
-        expect(dstXml.attrib.id).toEqual("NOTANID");
-        expect(dstXml.text).toEqual("TEXT");
-    });
-
-    it("should not merge platform tags with the wrong platform", function () {
-        var testXml = et.XML("<widget><platform name='bar'><testElement testAttrib='value'>testTEXT</testElement></platform></widget>"),
-            origCfg = et.tostring(dstXml);
-
-        prepare._mergeXml(testXml, dstXml, "foo", true);
-        expect(et.tostring(dstXml)).toEqual(origCfg);
-    });
-
-    it("should merge platform tags with the correct platform", function () {
-        var testXml = et.XML("<widget><platform name='bar'><testElement testAttrib='value'>testTEXT</testElement></platform></widget>"),
-            origCfg = et.tostring(dstXml);
-
-        prepare._mergeXml(testXml, dstXml, "bar", true);
-        expect(et.tostring(dstXml)).not.toEqual(origCfg);
-        var testElement = dstXml.find("testElement");
-        expect(testElement).toBeDefined();
-        expect(testElement.attrib.testAttrib).toEqual("value");
-        expect(testElement.text).toEqual("testTEXT");
-    });
-
-    it("should merge singelton children without clobber", function () {
-        var testXml = et.XML("<widget><author testAttrib='value' href='http://www.nowhere.com'>SUPER_AUTHOR</author></widget>");
-
-        prepare._mergeXml(testXml, dstXml);
-        var testElements = dstXml.findall("author");
-        expect(testElements).toBeDefined();
-        expect(testElements.length).toEqual(1);
-        expect(testElements[0].attrib.testAttrib).toEqual("value");
-        expect(testElements[0].attrib.href).toEqual("http://cordova.io");
-        expect(testElements[0].attrib.email).toEqual("dev@cordova.apache.org");
-        expect(testElements[0].text).toContain("Apache Cordova Team");
-    });
-
-    it("should clobber singelton children with clobber", function () {
-        var testXml = et.XML("<widget><author testAttrib='value' href='http://www.nowhere.com'>SUPER_AUTHOR</author></widget>");
-
-        prepare._mergeXml(testXml, dstXml, '', true);
-        var testElements = dstXml.findall("author");
-        expect(testElements).toBeDefined();
-        expect(testElements.length).toEqual(1);
-        expect(testElements[0].attrib.testAttrib).toEqual("value");
-        expect(testElements[0].attrib.href).toEqual("http://www.nowhere.com");
-        expect(testElements[0].attrib.email).toEqual("dev@cordova.apache.org");
-        expect(testElements[0].text).toEqual("SUPER_AUTHOR");
-    });
-
-    it("should append non singelton children", function () {
-        var testXml = et.XML("<widget><preference num='1'/> <preference num='2'/></widget>");
-
-        prepare._mergeXml(testXml, dstXml, '', true);
-        var testElements = dstXml.findall("preference");
-        expect(testElements.length).toEqual(4);
-    });
-
-    it("should handle namespaced elements", function () {
-        var testXml = et.XML("<widget><foo:bar testAttrib='value'>testText</foo:bar></widget>");
-
-        prepare._mergeXml(testXml, dstXml, 'foo', true);
-        var testElement = dstXml.find("foo:bar");
-        expect(testElement).toBeDefined();
-        expect(testElement.attrib.testAttrib).toEqual("value");
-        expect(testElement.text).toEqual("testText");
-    });
-
-    it("should not append duplicate non singelton children", function () {
-        var testXml = et.XML("<widget><preference name='fullscreen' value='true'/></widget>");
-
-        prepare._mergeXml(testXml, dstXml, '', true);
-        var testElements = dstXml.findall("preference");
-        expect(testElements.length).toEqual(2);
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/run.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/run.spec.js b/cordova-lib/spec-cordova/run.spec.js
deleted file mode 100644
index bfaf3f8..0000000
--- a/cordova-lib/spec-cordova/run.spec.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    superspawn = require('../src/superspawn'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    Q = require('q'),
-    util = require('../src/util');
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-describe('run command', function() {
-    var is_cordova, cd_project_root, list_platforms, fire;
-    var project_dir = '/some/path';
-    var prepare_spy;
-
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
-        spyOn(superspawn, 'spawn').andReturn(Q);
-    });
-    describe('failure', function() {
-        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function(done) {
-            list_platforms.andReturn([]);
-            Q().then(cordova.raw.run).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            }).fin(done);
-        });
-        it('should not run outside of a Cordova-based project', function(done) {
-            var msg = 'Dummy message about not being in a cordova dir.';
-            cd_project_root.andThrow(new Error(msg));
-            is_cordova.andReturn(false);
-            Q().then(cordova.raw.run).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual(msg);
-            }).fin(done);
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the run script', function(done) {
-            cordova.raw.run(['android','ios']).then(function() {
-                expect(prepare_spy).toHaveBeenCalledWith(['android', 'ios']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), [], jasmine.any(Object));
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), [], jasmine.any(Object));
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should pass down parameters', function(done) {
-            cordova.raw.run({platforms: ['blackberry10'], options:['--password', '1q1q']}).then(function() {
-                expect(prepare_spy).toHaveBeenCalledWith(['blackberry10']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'run'), ['--password', '1q1q'], jasmine.any(Object));
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.run(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_run', {verbose: false, platforms:['android', 'ios'], options: []});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.run('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_run', {verbose: false, platforms:['android'], options: []});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.run).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(fire).not.toHaveBeenCalled();
-                    expect(err.message).toEqual('No platforms added to this project. Please use `cordova platform add <platform>`.');
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/serve.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/serve.spec.js b/cordova-lib/spec-cordova/serve.spec.js
deleted file mode 100644
index 75eec4f..0000000
--- a/cordova-lib/spec-cordova/serve.spec.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    util = require('../src/util'),
-    hooker = require('../src/hooker'),
-    tempDir = path.join(__dirname, '..', 'temp'),
-    http = require('http'),
-    android_parser = require('../src/metadata/android_parser'),
-    ios_parser = require('../src/metadata/ios_parser'),
-    blackberry_parser = require('../src/metadata/blackberry10_parser'),
-    wp7_parser        = require('../src/metadata/wp7_parser'),
-    wp8_parser        = require('../src/metadata/wp8_parser');
-
-var cwd = process.cwd();
-
-xdescribe('serve command', function() {
-    beforeEach(function() {
-        // Make a temp directory
-        shell.rm('-rf', tempDir);
-        shell.mkdir('-p', tempDir);
-    });
-    it('should not run outside of a Cordova-based project', function() {
-        this.after(function() {
-            process.chdir(cwd);
-        });
-
-        process.chdir(tempDir);
-
-        expect(function() {
-            cordova.serve('android');
-        }).toThrow();
-    });
-
-
-    describe('`serve`', function() {
-        var payloads = {
-            android: 'This is the Android test file.',
-            ios: 'This is the iOS test file.'
-        };
-
-        beforeEach(function() {
-            cordova.raw.create(tempDir);
-            process.chdir(tempDir);
-            cordova.raw.platform('add', 'android');
-            cordova.raw.platform('add', 'ios');
-
-            // Write testing HTML files into the directory.
-            fs.writeFileSync(path.join(tempDir, 'platforms', 'android', 'assets', 'www', 'test.html'), payloads.android);
-            fs.writeFileSync(path.join(tempDir, 'platforms', 'ios', 'www', 'test.html'), payloads.ios);
-        });
-
-        afterEach(function() {
-            process.chdir(cwd);
-        });
-
-        function test_serve(platform, path, expectedContents, port) {
-            return function() {
-                var ret;
-                runs(function() {
-                    ret = port ? cordova.serve(platform, port) : cordova.serve(platform);
-                });
-
-                waitsFor(function() {
-                    return ret.server;
-                }, 'the server should start', 1000);
-
-                var done, errorCB;
-                runs(function() {
-                    expect(ret.server).toBeDefined();
-                    errorCB = jasmine.createSpy();
-                    http.get({
-                        host: 'localhost',
-                        port: port || 8000,
-                        path: path
-                    }).on('response', function(res) {
-                        var response = '';
-                        res.on('data', function(data) {
-                            response += data;
-                        });
-                        res.on('end', function() {
-                            expect(res.statusCode).toEqual(200);
-                            expect(response).toEqual(expectedContents);
-                            done = true;
-                        });
-                    }).on('error', errorCB);
-                });
-
-                waitsFor(function() {
-                    return done;
-                }, 'the HTTP request should complete', 1000);
-
-                runs(function() {
-                    expect(done).toBeTruthy();
-                    expect(errorCB).not.toHaveBeenCalled();
-
-                    ret.server.close();
-                });
-            };
-        };
-
-        it('should serve from top-level www if the file exists there', function() {
-            var payload = 'This is test file.';
-            fs.writeFileSync(path.join(util.projectWww(tempDir), 'test.html'), payload);
-            test_serve('android', '/test.html', payload)();
-        });
-
-        it('should fall back to assets/www on Android', test_serve('android', '/test.html', payloads.android));
-        it('should fall back to www on iOS', test_serve('ios', '/test.html', payloads.ios));
-
-        it('should honour a custom port setting', test_serve('android', '/test.html', payloads.android, 9001));
-    });
-});
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/test-config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/test-config.xml b/cordova-lib/spec-cordova/test-config.xml
deleted file mode 100644
index 5e01e48..0000000
--- a/cordova-lib/spec-cordova/test-config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
-        id        = "io.cordova.hellocordova"
-        version   = "0.0.1">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <content src="index.html" />
-
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-    <icon id="icon" src="icon.png" />
-    <icon id="logo" src="logo.png" width="255" height="255" />
-    <platform name="android">
-        <icon src="logo-android.png" width="255" height="255" density="mdpi" />
-    </platform>    
-</widget>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/util.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/util.spec.js b/cordova-lib/spec-cordova/util.spec.js
deleted file mode 100644
index cb24f53..0000000
--- a/cordova-lib/spec-cordova/util.spec.js
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    shell = require('shelljs'),
-    path = require('path'),
-    fs = require('fs'),
-    util = require('../src/util'),
-    temp = path.join(__dirname, '..', 'temp'),
-    fixtures = path.join(__dirname, 'fixtures');
-
-var cwd = process.cwd();
-var home = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
-var origPWD = process.env['PWD'];
-
-describe('util module', function() {
-    describe('isCordova method', function() {
-        afterEach(function() {
-            process.env['PWD'] = origPWD;
-            process.chdir(cwd);
-        });
-        it('should return false if it hits the home directory', function() {
-            var somedir = path.join(home, 'somedir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir(somedir);
-            expect(util.isCordova(somedir)).toEqual(false);
-        });
-        it('should return false if it cannot find a .cordova directory up the directory tree', function() {
-            var somedir = path.join(home, '..');
-            expect(util.isCordova(somedir)).toEqual(false);
-        });
-        it('should return the first directory it finds with a .cordova folder in it', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
-            expect(util.isCordova(somedir)).toEqual(somedir);
-        });
-        it('should ignore PWD when its undefined', function() {
-            delete process.env['PWD'];
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www'));
-            shell.mkdir('-p', path.join(somedir, 'config.xml'));
-            process.chdir(anotherdir);
-            expect(util.isCordova()).toEqual(somedir);
-        });
-        it('should use PWD when available', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
-            process.env['PWD'] = anotherdir;
-            process.chdir(path.sep);
-            expect(util.isCordova()).toEqual(somedir);
-        });
-        it('should use cwd as a fallback when PWD is not a cordova dir', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
-            process.env['PWD'] = path.sep;
-            process.chdir(anotherdir);
-            expect(util.isCordova()).toEqual(somedir);
-        });
-        it('should ignore platform www/config.xml', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(anotherdir, 'www', 'config.xml'));
-            shell.mkdir('-p', path.join(somedir, 'www'));
-            shell.mkdir('-p', path.join(somedir, 'config.xml'));
-            expect(util.isCordova(anotherdir)).toEqual(somedir);
-        });
-    });
-    describe('deleteSvnFolders method', function() {
-        afterEach(function() {
-            shell.rm('-rf', temp);
-        });
-        it('should delete .svn folders in any subdirectory of specified dir', function() {
-            var one = path.join(temp, 'one');
-            var two = path.join(temp, 'two');
-            var one_svn = path.join(one, '.svn');
-            var two_svn = path.join(two, '.svn');
-            shell.mkdir('-p', one_svn);
-            shell.mkdir('-p', two_svn);
-            util.deleteSvnFolders(temp);
-            expect(fs.existsSync(one_svn)).toEqual(false);
-            expect(fs.existsSync(two_svn)).toEqual(false);
-        });
-    });
-    describe('listPlatforms method', function() {
-        afterEach(function() {
-            shell.rm('-rf', temp);
-        });
-        it('should only return supported platform directories present in a cordova project dir', function() {
-            var platforms = path.join(temp, 'platforms');
-            var android = path.join(platforms, 'android');
-            var ios = path.join(platforms, 'ios');
-            var wp7 = path.join(platforms, 'wp7');
-            var atari = path.join(platforms, 'atari');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', wp7);
-            shell.mkdir('-p', atari);
-            var res = util.listPlatforms(temp);
-            expect(res.length).toEqual(3);
-            expect(res.indexOf('atari')).toEqual(-1);
-        });
-    });
-    describe('findPlugins method', function() {
-        afterEach(function() {
-            shell.rm('-rf', temp);
-        });
-        it('should only return plugin directories present in a cordova project dir', function() {
-            var plugins = path.join(temp, 'plugins');
-            var android = path.join(plugins, 'android');
-            var ios = path.join(plugins, 'ios');
-            var wp7 = path.join(plugins, 'wp7');
-            var atari = path.join(plugins, 'atari');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', wp7);
-            shell.mkdir('-p', atari);
-            var res = util.findPlugins(plugins);
-            expect(res.length).toEqual(4);
-        });
-        it('should not return ".svn" directories', function() {
-            var plugins = path.join(temp, 'plugins');
-            var android = path.join(plugins, 'android');
-            var ios = path.join(plugins, 'ios');
-            var svn = path.join(plugins, '.svn');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', svn);
-            var res = util.findPlugins(plugins);
-            expect(res.length).toEqual(2);
-            expect(res.indexOf('.svn')).toEqual(-1);
-        });
-        it('should not return "CVS" directories', function() {
-            var plugins = path.join(temp, 'plugins');
-            var android = path.join(plugins, 'android');
-            var ios = path.join(plugins, 'ios');
-            var cvs = path.join(plugins, 'CVS');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', cvs);
-            var res = util.findPlugins(plugins);
-            expect(res.length).toEqual(2);
-            expect(res.indexOf('CVS')).toEqual(-1);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/wrappers.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/wrappers.spec.js b/cordova-lib/spec-cordova/wrappers.spec.js
deleted file mode 100644
index 2afbe9b..0000000
--- a/cordova-lib/spec-cordova/wrappers.spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var Q = require('q'),
-    cordova = require('../cordova');
-
-describe('callback wrapper', function() {
-    var calls = ['prepare', 'build', 'create', 'emulate', 'plugin', 'platform', 'compile', 'run'];
-    for (var i = 0; i < calls.length; i++) {
-        var call = calls[i];
-
-        describe('`' + call + '`', function() {
-            var raw;
-            beforeEach(function() {
-                raw = spyOn(cordova.raw, call);
-            });
-
-            it('should work with no callback and success', function() {
-                raw.andReturn(Q());
-                cordova[call]();
-                expect(raw).toHaveBeenCalled();
-            });
-
-            it('should call the callback on success', function(done) {
-                raw.andReturn(Q());
-                cordova[call](function(err) {
-                    expect(err).toBeUndefined();
-                    done();
-                });
-            });
-
-            it('should call the callback with the error on failure', function(done) {
-                var err = new Error('junk');
-                raw.andReturn(Q.reject(err));
-                cordova[call](function(e) {
-                    expect(e).toEqual(err);
-                    done();
-                });
-            });
-        });
-    }
-});
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/xml-helpers.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/xml-helpers.spec.js b/cordova-lib/spec-cordova/xml-helpers.spec.js
deleted file mode 100644
index 6af8c4b..0000000
--- a/cordova-lib/spec-cordova/xml-helpers.spec.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var path = require('path')
-  , xml_helpers = require('../src/xml-helpers')
-  , et = require('elementtree')
-
-  , title = et.XML('<title>HELLO</title>')
-  , usesNetworkOne = et.XML('<uses-permission ' +
-            'android:name="PACKAGE_NAME.permission.C2D_MESSAGE"/>')
-  , usesNetworkTwo = et.XML("<uses-permission android:name=\
-            \"PACKAGE_NAME.permission.C2D_MESSAGE\" />")
-  , usesReceive = et.XML("<uses-permission android:name=\
-            \"com.google.android.c2dm.permission.RECEIVE\"/>")
-  , helloTagOne = et.XML("<h1>HELLO</h1>")
-  , goodbyeTag = et.XML("<h1>GOODBYE</h1>")
-  , helloTagTwo = et.XML("<h1>  HELLO  </h1>");
-
-
-describe('xml-helpers', function(){
-    describe('parseElementtreeSync', function() {
-        it('should parse xml with a byte order mark', function() {
-            var xml_path = path.join(__dirname, 'fixtures', 'projects', 'windows', 'bom_test.xml');
-            expect(function() {
-                xml_helpers.parseElementtreeSync(xml_path);
-            }).not.toThrow();
-        })
-    });
-    describe('equalNodes', function() {
-        it('should return false for different tags', function(){
-            expect(xml_helpers.equalNodes(usesNetworkOne, title)).toBe(false);
-        });
-
-        it('should return true for identical tags', function(){
-            expect(xml_helpers.equalNodes(usesNetworkOne, usesNetworkTwo)).toBe(true);
-        });
-
-        it('should return false for different attributes', function(){
-            expect(xml_helpers.equalNodes(usesNetworkOne, usesReceive)).toBe(false);
-        });
-
-        it('should distinguish between text', function(){
-            expect(xml_helpers.equalNodes(helloTagOne, goodbyeTag)).toBe(false);
-        });
-
-        it('should ignore whitespace in text', function(){
-            expect(xml_helpers.equalNodes(helloTagOne, helloTagTwo)).toBe(true);
-        });
-
-        describe('should compare children', function(){
-            it('by child quantity', function(){
-                var one = et.XML('<i><b>o</b></i>'),
-                    two = et.XML('<i><b>o</b><u></u></i>');
-
-                expect(xml_helpers.equalNodes(one, two)).toBe(false);
-            });
-
-            it('by child equality', function(){
-                var one = et.XML('<i><b>o</b></i>'),
-                    two = et.XML('<i><u></u></i>'),
-                    uno = et.XML('<i>\n<b>o</b>\n</i>');
-
-                expect(xml_helpers.equalNodes(one, uno)).toBe(true);
-                expect(xml_helpers.equalNodes(one, two)).toBe(false);
-            });
-        });
-    });
-    describe('pruneXML', function() {
-        var config_xml;
-
-        beforeEach(function() {
-            config_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'projects', 'android', 'res', 'xml', 'config.xml'));
-        });
-
-        it('should remove any children that match the specified selector', function() {
-            var children = config_xml.findall('plugins/plugin');
-            xml_helpers.pruneXML(config_xml, children, 'plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
-        });
-        it('should do nothing if the children cannot be found', function() {
-            var children = [title];
-            xml_helpers.pruneXML(config_xml, children, 'plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(17);
-        });
-        it('should be able to handle absolute selectors', function() {
-            var children = config_xml.findall('plugins/plugin');
-            xml_helpers.pruneXML(config_xml, children, '/cordova/plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
-        });
-        it('should be able to handle absolute selectors with wildcards', function() {
-            var children = config_xml.findall('plugins/plugin');
-            xml_helpers.pruneXML(config_xml, children, '/*/plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
-        });
-    });
-
-    describe('graftXML', function() {
-        var config_xml, plugin_xml;
-
-        beforeEach(function() {
-            config_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'projects', 'android', 'res', 'xml', 'config.xml'));
-            plugin_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'plugins', 'ChildBrowser', 'plugin.xml'));
-        });
-
-        it('should add children to the specified selector', function() {
-            var children = plugin_xml.find('config-file').getchildren();
-            xml_helpers.graftXML(config_xml, children, 'plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(19);
-        });
-        it('should be able to handle absolute selectors', function() {
-            var children = plugin_xml.find('config-file').getchildren();
-            xml_helpers.graftXML(config_xml, children, '/cordova');
-            expect(config_xml.findall('access').length).toEqual(3);
-        });
-        it('should be able to handle absolute selectors with wildcards', function() {
-            var children = plugin_xml.find('config-file').getchildren();
-            xml_helpers.graftXML(config_xml, children, '/*');
-            expect(config_xml.findall('access').length).toEqual(3);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/ConfigParser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/ConfigParser.js b/cordova-lib/src/cordova/ConfigParser.js
deleted file mode 100644
index 067c30f..0000000
--- a/cordova-lib/src/cordova/ConfigParser.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var et = require('elementtree'),
-    xml= require('./xml-helpers'),
-    CordovaError = require('./CordovaError'),
-    fs = require('fs');
-
-/** Wraps a config.xml file */
-function ConfigParser(path) {
-    this.path = path;
-    try {
-        this.doc = xml.parseElementtreeSync(path);
-    } catch (e) {
-        console.error('Parsing '+path+' failed');
-        throw e;
-    }
-    var r = this.doc.getroot();
-    if (r.tag !== 'widget') {
-        throw new CordovaError(path + ' has incorrect root node name (expected "widget", was "' + r.tag + '")');
-    }
-}
-
-function getNodeTextSafe(el) {
-    return el && el.text && el.text.trim();
-}
-
-function findOrCreate(doc, name) {
-    var ret = doc.find(name);
-    if (!ret) {
-        ret = new et.Element(name);
-        doc.getroot().append(content);
-    }
-    return ret;
-}
-
-ConfigParser.prototype = {
-    packageName: function(id) {
-        return this.doc.getroot().attrib['id'];
-    },
-    setPackageName: function(id) {
-        this.doc.getroot().attrib['id'] = id;
-    },
-    name: function() {
-        return getNodeTextSafe(this.doc.find('name'));
-    },
-    setName: function(name) {
-        var el = findOrCreate(this.doc, 'name');
-        el.text = name;
-    },
-    description: function() {
-        return this.doc.find('description').text.trim();
-    },
-    setDescription: function() {
-        this.doc.find('description').text = name;
-        var el = findOrCreate(this.doc, 'description');
-    },
-    version: function() {
-        return this.doc.getroot().attrib['version'];
-    },
-    android_versionCode: function() {
-        return this.doc.getroot().attrib['android-versionCode'];
-    },
-    ios_CFBundleVersion: function() {
-        return this.doc.getroot().attrib['ios-CFBundleVersion'];
-    },
-    setVersion: function(value) {
-        this.doc.getroot().attrib['version'] = value;
-    },
-    author: function() {
-        return getNodeTextSafe(this.doc.find('author'));
-    },
-    getPreference: function(name) {
-        var preferences = this.doc.findall('preference');
-        var ret = null;
-        preferences.forEach(function (preference) {
-            // Take the last one that matches.
-            if (preference.attrib.name.toLowerCase() === name.toLowerCase()) {
-                ret = preference.attrib.value;
-            }
-        });
-        return ret;
-    },
-    /**
-     * Returns all icons for the platform specified.
-     * @param  {String} platform The platform.
-     * @return {Array} Icons for the platform specified.
-     */
-    getIcons: function(platform) {
-        var ret = [];
-            iconElements = [];
-
-        if (platform) { // platform specific icons
-            this.doc.findall('platform[@name=\'' + platform + '\']/icon').forEach(function(elt){
-                elt.platform = platform; // mark as platform specific icon
-                iconElements.push(elt)
-            });
-        }
-        // root level icons
-        iconElements = iconElements.concat(this.doc.findall('icon'));
-        // parse icon elements
-        iconElements.forEach(function (elt) {
-            var icon = {};
-            icon.src = elt.attrib.src;
-            icon.density = elt.attrib['density'] || elt.attrib['cdv:density'] || elt.attrib['gap:density'];
-            icon.platform = elt.platform || null; // null means icon represents default icon (shared between platforms)
-            icon.width = elt.attrib.width;
-            icon.height = elt.attrib.height;
-            // If one of width or Height is undefined, assume they are equal.
-            icon.width = icon.width || icon.height;
-            icon.height = icon.height || icon.width;
-
-            // default icon
-            if (!icon.width && !icon.height && !icon.density) {
-                ret.defaultIcon = icon;
-            }
-            ret.push(icon);
-        });
-
-        /**
-         * Returns icon with specified width and height
-         * @param  {number} w  Width of icon
-         * @param  {number} h  Height of icon
-         * @return {Icon}      Icon object or null if not found
-         */
-        ret.getIconBySize = function(w, h){
-            // If only one of width and height is given
-            // then we assume that they are equal.
-            var width = w || h, height = h || w;
-            for (var idx in this) {
-                var icon = this[idx];
-                if (width == icon.width && height == icon.width) return icon;
-            }
-            return null;
-        };
-        /** Returns default icons */
-        ret.getDefault = function() {
-            return ret.defaultIcon;
-        }
-
-        return ret;
-    },
-    write:function() {
-        fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
-    }
-};
-
-module.exports = ConfigParser;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/CordovaError.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/CordovaError.js b/cordova-lib/src/cordova/CordovaError.js
deleted file mode 100644
index 5576e06..0000000
--- a/cordova-lib/src/cordova/CordovaError.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-
-// A derived exception class. See usage example in cli.js
-// Based on:
-// stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/8460753#8460753
-function CordovaError(message) {
-    Error.captureStackTrace(this, this.constructor);
-    this.name = this.constructor.name;
-    this.message = message;
-}
-CordovaError.prototype.__proto__ = Error.prototype;
-
-module.exports = CordovaError;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/build.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/build.js b/cordova-lib/src/cordova/build.js
deleted file mode 100644
index 5a0f0d3..0000000
--- a/cordova-lib/src/cordova/build.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_util      = require('./util'),
-    Q                 = require('q'),
-    hooker            = require('./hooker');
-
-// Returns a promise.
-module.exports = function build(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-
-    if (!options) {
-        options = {
-            verbose: false,
-            platforms: [],
-            options: []
-        };
-    }
-
-    options = cordova_util.preProcessOptions(options);
-
-    // fire build hooks
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_build', options)
-    .then(function() {
-        return require('../cordova').raw.prepare(options);
-    }).then(function() {
-        return require('../cordova').raw.compile(options);
-    }).then(function() {
-        return hooks.fire('after_build', options);
-    });
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/compile.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/compile.js b/cordova-lib/src/cordova/compile.js
deleted file mode 100644
index 857c3a5..0000000
--- a/cordova-lib/src/cordova/compile.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-/*global require: true, module: true, process: true*/
-/*jslint sloppy: true, white: true, newcap: true */
-
-var path              = require('path'),
-    cordova_util      = require('./util'),
-    hooker            = require('./hooker'),
-    superspawn        = require('./superspawn');
-
-// Returns a promise.
-module.exports = function compile(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-    options = cordova_util.preProcessOptions(options);
-
-    var hooks = new hooker(projectRoot);
-    var ret = hooks.fire('before_compile', options);
-    options.platforms.forEach(function(platform) {
-        ret = ret.then(function() {
-            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'build');
-            return superspawn.spawn(cmd, options.options, { stdio: 'inherit', printCommand: true });
-        });
-    });
-    ret = ret.then(function() {
-        return hooks.fire('after_compile', options);
-    });
-    return ret;
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/config.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/config.js b/cordova-lib/src/cordova/config.js
deleted file mode 100644
index d0c8d9a..0000000
--- a/cordova-lib/src/cordova/config.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var path          = require('path'),
-    fs            = require('fs'),
-    url           = require('url'),
-    shell         = require('shelljs');
-
-// Map of project_root -> JSON
-var configCache = {};
-var autoPersist = true;
-
-function config(project_root, opts) {
-    var json = config.read(project_root);
-    for (var p in opts) {
-        json[p] = opts[p];
-    }
-    if (autoPersist) {
-        config.write(project_root, json);
-    } else {
-        configCache[project_root] = JSON.stringify(json);
-    }
-    return json;
-};
-
-config.setAutoPersist = function(value) {
-    autoPersist = value;
-};
-
-config.read = function get_config(project_root) {
-    var data = configCache[project_root];
-    if (data === undefined) {
-        var configPath = path.join(project_root, '.cordova', 'config.json');
-        if (!fs.existsSync(configPath)) {
-            data = '{}';
-        } else {
-            data = fs.readFileSync(configPath, 'utf-8');
-        }
-    }
-    configCache[project_root] = data;
-    return JSON.parse(data);
-};
-
-config.write = function set_config(project_root, json) {
-    var configPath = path.join(project_root, '.cordova', 'config.json');
-    var contents = JSON.stringify(json, null, 4);
-    configCache[project_root] = contents;
-    // Don't write the file for an empty config.
-    if (contents != '{}' || fs.existsSync(configPath)) {
-        shell.mkdir('-p', path.join(project_root, '.cordova'));
-        fs.writeFileSync(configPath, contents, 'utf-8');
-    }
-    return json;
-};
-
-config.has_custom_path = function(project_root, platform) {
-    var json = config.read(project_root);
-    if (json.lib && json.lib[platform]) {
-        var uri = url.parse(json.lib[platform].uri);
-        if (!(uri.protocol)) return uri.path;
-        else if (uri.protocol && uri.protocol[1] ==':') return uri.href;
-    }
-    return false;
-};
-
-module.exports = config;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/cordova.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/cordova.js b/cordova-lib/src/cordova/cordova.js
deleted file mode 100644
index 687392b..0000000
--- a/cordova-lib/src/cordova/cordova.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_events = require('./src/events');
-var cordova_util = require('./src/util');
-
-var off = function() {
-    cordova_events.removeListener.apply(cordova_events, arguments);
-};
-
-var emit = function() {
-    cordova_events.emit.apply(cordova_events, arguments);
-};
-
-exports = module.exports = {
-    on:        function() {
-        cordova_events.on.apply(cordova_events, arguments);
-    },
-    off:       off,
-    removeListener:off,
-    removeAllListeners:function() {
-        cordova_events.removeAllListeners.apply(cordova_events, arguments);
-    },
-    emit:      emit,
-    trigger:   emit,
-    raw: {}
-};
-
-exports.findProjectRoot = function(opt_startDir) {
-    return cordova_util.isCordova(opt_startDir);
-}
-
-// Each of these APIs takes a final parameter that is a callback function.
-// The callback is passed the error object upon failure, or undefined upon success.
-// To use a promise instead, call the APIs via cordova.raw.FOO(), which returns
-// a promise instead of using a final-parameter-callback.
-var addModuleProperty = cordova_util.addModuleProperty;
-addModuleProperty(module, 'prepare', './src/prepare', true);
-addModuleProperty(module, 'build', './src/build', true);
-addModuleProperty(module, 'help', './src/help');
-addModuleProperty(module, 'config', './src/config');
-addModuleProperty(module, 'create', './src/create', true);
-addModuleProperty(module, 'emulate', './src/emulate', true);
-addModuleProperty(module, 'plugin', './src/plugin', true);
-addModuleProperty(module, 'plugins', './src/plugin', true);
-addModuleProperty(module, 'serve', './src/serve');
-addModuleProperty(module, 'platform', './src/platform', true);
-addModuleProperty(module, 'platforms', './src/platform', true);
-addModuleProperty(module, 'compile', './src/compile', true);
-addModuleProperty(module, 'run', './src/run', true);
-addModuleProperty(module, 'info', './src/info', true);
-
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/create.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/create.js b/cordova-lib/src/cordova/create.js
deleted file mode 100644
index 025e56b..0000000
--- a/cordova-lib/src/cordova/create.js
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var path          = require('path'),
-    fs            = require('fs'),
-    shell         = require('shelljs'),
-    platforms     = require('../platforms'),
-    help          = require('./help'),
-    events        = require('./events'),
-    config        = require('./config'),
-    lazy_load     = require('./lazy_load'),
-    Q             = require('q'),
-    CordovaError  = require('./CordovaError'),
-    ConfigParser = require('./ConfigParser'),
-    util          = require('./util');
-
-var DEFAULT_NAME = "HelloCordova",
-    DEFAULT_ID   = "io.cordova.hellocordova";
-
-/**
- * Usage:
- * @dir - directory where the project will be created. Required.
- * @id - app id. Optional, default is DEFAULT_ID.
- * @name - app name. Optional, default is DEFAULT_NAME.
- * @cfg - extra config to be saved in .cordova/config.json
- **/
-// Returns a promise.
-module.exports = create;
-function create(dir, id, name, cfg) {
-    if (!dir ) {
-        return Q(help());
-    }
-
-    // Massage parameters
-    if (typeof cfg == 'string') {
-        cfg = JSON.parse(cfg);
-    }
-    cfg = cfg || {};
-    id = id || cfg.id || DEFAULT_ID;
-    name = name || cfg.name || DEFAULT_NAME;
-
-    // Make absolute.
-    dir = path.resolve(dir);
-
-    events.emit('log', 'Creating a new cordova project with name "' + name + '" and id "' + id + '" at location "' + dir + '"');
-
-    var www_dir = path.join(dir, 'www');
-
-    // dir must be either empty or not exist at all.
-
-    // dir must be either empty except for .cordova config file or not exist at all..
-    var sanedircontents = function (d) {
-        var contents = fs.readdirSync(d);
-        if (contents.length === 0) {
-            return true;
-        } else if (contents.length == 1) {
-            if (contents[0] == '.cordova') {
-                return true;
-            }
-        }
-        return false;
-    };
-
-    if (fs.existsSync(dir) && !sanedircontents(dir)) {
-        return Q.reject(new CordovaError('Path already exists and is not empty: ' + dir));
-    }
-
-    // Read / Write .cordova/config.json file if necessary.
-    var config_json = config(dir, cfg);
-
-    var p;
-    var symlink = false; // Whether to symlink the www dir instead of copying.
-    var www_parent_dir;
-    var custom_config_xml;
-    var custom_merges;
-    var custom_hooks;
-
-    if (config_json.lib && config_json.lib.www) {
-        events.emit('log', 'Using custom www assets from '+config_json.lib.www.uri);
-        // TODO (kamrik): extend lazy_load for retrieval without caching to allow net urls for --src.
-        var www_version = config_json.lib.www.version || 'not_versioned';
-        var www_id = config_json.lib.www.id || 'dummy_id';
-        symlink  = !!config_json.lib.www.link;
-        if ( www_dir.indexOf(path.resolve(config_json.lib.www.uri)) === 0 ) {
-            throw new CordovaError(
-                'Project must not be created inside the www assets dir.' +
-                '\n    project dir:\t' + dir +
-                '\n    www assets dir:\t' + config_json.lib.www.uri
-            );
-        }
-        if(symlink) {
-            p = Q(config_json.lib.www.uri);
-            events.emit('verbose', 'Symlinking custom www assets into "' + www_dir + '"');
-        } else {
-            p = lazy_load.custom(config_json.lib.www.uri, www_id, 'www', www_version)
-            .then(function(d) {
-                events.emit('verbose', 'Copying custom www assets into "' + www_dir + '"');
-                return d;
-            });
-        }
-    } else {
-        // No custom www - use stock cordova-hello-world-app.
-        events.emit('verbose', 'Using stock cordova hello-world application.');
-        p = lazy_load.cordova('www')
-        .then(function(d) {
-            events.emit('verbose', 'Copying stock Cordova www assets into "' + www_dir + '"');
-            return d;
-        });
-    }
-
-    return p.then(function(www_lib) {
-        if (!fs.existsSync(www_lib)) {
-            throw new CordovaError('Could not find directory: '+www_lib);
-        }
-        // Keep going into child "www" folder if exists in stock app package.
-        while (fs.existsSync(path.join(www_lib, 'www'))) {
-            www_parent_dir = www_lib;
-            www_lib = path.join(www_lib, 'www');
-        }
-
-        // Find if we also have custom merges and config.xml as siblings of custom www.
-        if (www_parent_dir && config_json.lib && config_json.lib.www) {
-            custom_config_xml = path.join(www_parent_dir, 'config.xml');
-            if ( !fs.existsSync(custom_config_xml) ) {
-                custom_config_xml = null;
-            }
-            custom_merges = path.join(www_parent_dir, 'merges');
-            if ( !fs.existsSync(custom_merges) ) {
-                custom_merges = null;
-            }
-            custom_hooks = path.join(www_parent_dir, 'hooks');
-            if ( !fs.existsSync(custom_hooks) ) {
-                custom_hooks = null;
-            }
-        }
-
-        var dirAlreadyExisted = fs.existsSync(dir);
-        if (!dirAlreadyExisted) {
-            shell.mkdir(dir);
-        }
-        if (symlink) {
-            try {
-                fs.symlinkSync(www_lib, www_dir, 'dir');
-                if (custom_merges) {
-                    fs.symlinkSync(custom_merges, path.join(dir, 'merges'), 'dir');
-                }
-                if (custom_hooks) {
-                    fs.symlinkSync(custom_hooks, path.join(dir, 'hooks'), 'dir');
-                }
-                if (custom_config_xml) {
-                    fs.symlinkSync(custom_config_xml, path.join(dir, 'config.xml'));
-                }
-            } catch (e) {
-                if (!dirAlreadyExisted) {
-                    fs.rmdirSync(dir);
-                }
-                if (process.platform.slice(0, 3) == 'win' && e.code == 'EPERM')  {
-                    throw new CordovaError('Symlinks on Windows require Administrator privileges');
-                }
-                throw e;
-            }
-        } else {
-            shell.mkdir(www_dir);
-            shell.cp('-R', path.join(www_lib, '*'), www_dir);
-            if (custom_merges) {
-                var merges_dir = path.join(dir, 'merges');
-                shell.mkdir(merges_dir);
-                shell.cp('-R', path.join(custom_merges, '*'), merges_dir);
-            }
-            if (custom_hooks) {
-                var hooks_dir = path.join(dir, 'hooks');
-                shell.mkdir(hooks_dir);
-                shell.cp('-R', path.join(custom_hooks, '*'), hooks_dir);
-            }
-            if (custom_config_xml) {
-                shell.cp(custom_config_xml, path.join(dir, 'config.xml'));
-            }
-
-        }
-
-        // Create basic project structure.
-        shell.mkdir(path.join(dir, 'platforms'));
-        if ( !custom_merges) {
-            shell.mkdir(path.join(dir, 'merges'));
-        }
-        shell.mkdir(path.join(dir, 'plugins'));
-        shell.mkdir(path.join(dir, 'hooks'));
-
-        // Add hooks README.md
-        shell.cp(path.join(__dirname, '..', 'templates', 'hooks-README.md'), path.join(dir, 'hooks', 'README.md'));
-
-        var configPath = util.projectConfig(dir);
-        // Add template config.xml for apps that are missing it
-        if (!fs.existsSync(configPath)) {
-            var template_config_xml = path.join(__dirname, '..', 'templates', 'config.xml');
-            shell.cp(template_config_xml, configPath);
-            // Write out id and name to config.xml
-            var config = new ConfigParser(configPath);
-            config.setPackageName(id);
-            config.setName(name);
-            config.write();
-        }
-    });
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/emulate.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/emulate.js b/cordova-lib/src/cordova/emulate.js
deleted file mode 100644
index c1d3a10..0000000
--- a/cordova-lib/src/cordova/emulate.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-/*global require: true, module: true, process: true*/
-/*jslint sloppy: true, white: true, newcap: true */
-
-var cordova_util      = require('./util'),
-    path              = require('path'),
-    hooker            = require('./hooker'),
-    superspawn        = require('./superspawn'),
-    Q                 = require('q');
-
-// Returns a promise.
-module.exports = function emulate(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-    options = cordova_util.preProcessOptions(options);
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_emulate', options)
-    .then(function() {
-        // Run a prepare first!
-        return require('../cordova').raw.prepare(options.platforms);
-    }).then(function() {
-        // Deploy in parallel (output gets intermixed though...)
-        return Q.all(options.platforms.map(function(platform) {
-            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'run');
-            var args = ['--emulator'].concat(options.options);
-
-            return superspawn.spawn(cmd, args, {stdio: 'inherit', printCommand: true});
-        }));
-    }).then(function() {
-        return hooks.fire('after_emulate', options);
-    });
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/events.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/events.js b/cordova-lib/src/cordova/events.js
deleted file mode 100644
index be40fec..0000000
--- a/cordova-lib/src/cordova/events.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var events = require('events');
-
-var emitter = new events.EventEmitter();
-
-module.exports = emitter;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/hooker.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/hooker.js b/cordova-lib/src/cordova/hooker.js
deleted file mode 100644
index e4ccaff..0000000
--- a/cordova-lib/src/cordova/hooker.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var util  = require('./util'),
-    fs    = require('fs'),
-    os    = require('os'),
-    events= require('./events'),
-    superspawn = require('./superspawn'),
-    CordovaError = require('./CordovaError'),
-    Q     = require('q'),
-    path  = require('path'),
-    _ = require('underscore');
-
-module.exports = function hooker(root) {
-    var r = util.isCordova(root);
-    if (!r) throw new CordovaError('Not a Cordova project ("'+root+'"), can\'t use hooks.');
-    else this.root = r;
-};
-
-// Returns a promise.
-module.exports.fire = function global_fire(hook, opts) {
-    opts = opts || {};
-    var handlers = events.listeners(hook);
-    return execute_handlers_serially(handlers, opts);
-};
-
-function compareNumbers(a, b) {
-    return isNaN (parseInt(a))
-        ? a.toLowerCase().localeCompare(b.toLowerCase ? b.toLowerCase(): b)
-        : parseInt(a) > parseInt(b) ? 1 : parseInt(a) < parseInt(b) ? -1 : 0;
-}
-
-module.exports.prototype = {
-    // Returns a promise.
-    fire:function fire(hook, opts) {
-        var root = this.root;
-        opts = opts || {};
-        opts.root = root;
-
-        function fireHooksInDir(dir) {
-            if (!(fs.existsSync(dir))) {
-                return Q();
-            } else {
-                var scripts = fs.readdirSync(dir).sort(compareNumbers).filter(function(s) {
-                    return s[0] != '.';
-                });
-                return execute_scripts_serially(scripts, root, dir, opts);
-            }
-        }
-        // Fire JS hook for the event
-        // These ones need to "serialize" events, that is, each handler attached to the event needs to finish processing (if it "opted in" to the callback) before the next one will fire.
-        var handlers = events.listeners(hook);
-        return execute_handlers_serially(handlers, opts)
-        .then(function() {
-            return fireHooksInDir(path.join(root, '.cordova', 'hooks', hook));
-        }).then(function() {
-            return fireHooksInDir(path.join(root, 'hooks', hook));
-        });
-    }
-};
-
-function extractSheBangInterpreter(fullpath) {
-    var hookFd = fs.openSync(fullpath, "r");
-    try {
-        // this is a modern cluster size. no need to read less
-        var fileData = new Buffer (4096);
-        var octetsRead = fs.readSync(hookFd, fileData, 0, 4096, 0);
-        var fileChunk = fileData.toString();
-    } finally {
-        fs.closeSync(hookFd);
-    }
-
-    var hookCmd, shMatch;
-    // Filter out /usr/bin/env so that "/usr/bin/env node" works like "node".
-    var shebangMatch = fileChunk.match(/^#!(?:\/usr\/bin\/env )?([^\r\n]+)/m);
-    if (octetsRead == 4096 && !fileChunk.match(/[\r\n]/))
-        events.emit('warn', 'shebang is too long for "' + fullpath + '"');
-    if (shebangMatch)
-        hookCmd = shebangMatch[1];
-    // Likewise, make /usr/bin/bash work like "bash".
-    if (hookCmd)
-        shMatch = hookCmd.match(/bin\/((?:ba)?sh)$/)
-    if (shMatch)
-        hookCmd = shMatch[1]
-    return hookCmd;
-}
-
-// Returns a promise.
-function execute_scripts_serially(scripts, root, dir, opts) {
-    opts = opts || {};
-    var isWindows = os.platform().slice(0, 3) === 'win';
-    if (scripts.length) {
-        var s = scripts.shift();
-        var fullpath = path.join(dir, s);
-        if (fs.statSync(fullpath).isDirectory()) {
-            events.emit('verbose', 'skipped directory "' + fullpath + '" within hook directory');
-            return execute_scripts_serially(scripts, root, dir, opts); // skip directories if they're in there.
-        } else {
-            var command = fullpath;
-            var args = [root];
-            if (os.platform().slice(0, 3) == 'win') {
-                // TODO: Make shebang sniffing a setting (not everyone will want this).
-                var interpreter = extractSheBangInterpreter(fullpath);
-                // we have shebang, so try to run this script using correct interpreter
-                if (interpreter) {
-                    args.unshift(command);
-                    command = interpreter;
-                }
-            }
-
-            var execOpts = {cwd: root, printCommand: true, stdio: 'inherit'};
-            execOpts.env = {};
-            execOpts.env.CORDOVA_VERSION = require('../package').version;
-            execOpts.env.CORDOVA_PLATFORMS = opts.platforms ? opts.platforms.join() : '';
-            execOpts.env.CORDOVA_PLUGINS = opts.plugins?opts.plugins.join():'';
-            execOpts.env.CORDOVA_HOOK = fullpath;
-            execOpts.env.CORDOVA_CMDLINE = process.argv.join(' ');
-
-            return superspawn.spawn(command, args, execOpts)
-            .catch(function(err) {
-                // Don't treat non-executable files as errors. They could be READMEs, or Windows-only scripts.
-                if (!isWindows && err.code == 'EACCES') {
-                    events.emit('verbose', 'skipped non-executable file: ' + fullpath);
-                } else {
-                    throw new CordovaError('Hook failed with error code ' + err.code + ': ' + fullpath);
-                }
-            }).then(function() {
-                return execute_scripts_serially(scripts, root, dir, opts);
-            });
-        }
-    } else {
-        return Q(); // Nothing to do.
-    }
-}
-
-// Returns a promise.
-function execute_handlers_serially(handlers, opts) {
-    if (handlers.length) {
-        // Chain the handlers in series.
-        return handlers.reduce(function(soFar, f) {
-            return soFar.then(function() { return f(opts) });
-        }, Q());
-    } else {
-        return Q(); // Nothing to do.
-    }
-}


[20/24] Remove all cordova-lib files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js
deleted file mode 100755
index c064499..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/check_reqs.js
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    fs    = require('fs'),
-    ROOT  = path.join(__dirname, '..', '..');
-
-// Get valid target from framework/project.properties
-module.exports.get_target = function() {
-    if(fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
-        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties'));
-        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
-    } else if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
-        // if no target found, we're probably in a project and project.properties is in ROOT.
-        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
-        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
-    }
-}
-
-module.exports.check_ant = function() {
-    var test = shell.exec('ant -version', {silent:true, async:false});
-    if(test.code > 0) {
-        console.error('ERROR : executing command \'ant\', make sure you have ant installed and added to your path.');
-        return false;
-    }
-    return true;
-}
-
-module.exports.check_java = function() {
-    if(process.env.JAVA_HOME) {
-        var test = shell.exec('java', {silent:true, async:false});
-        if(test.code > 0) {
-            console.error('ERROR : executing command \'java\', make sure you java environment is set up. Including your JDK and JRE.');
-            return false;
-        }
-        return true;
-    } else {
-        console.error('ERROR : Make sure JAVA_HOME is set, as well as paths to your JDK and JRE for java.');
-        return false;
-    }
-}
-
-module.exports.check_android = function() {
-    var valid_target = this.get_target();
-    var targets = shell.exec('android list targets', {silent:true, async:false});
-
-    if(targets.code > 0 && targets.output.match(/command\snot\sfound/)) {
-        console.error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.');
-        return false;
-    } else if(!targets.output.match(valid_target)) {
-        console.error('Please install Android target ' + valid_target.split('-')[1] + ' (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools.');
-        return false;
-    }
-    return true;
-}
-
-module.exports.run = function() {
-    return this.check_ant() && this.check_java && this.check_android();
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js
deleted file mode 100755
index 8f14015..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/clean.js
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    ROOT = path.join(__dirname, '..', '..');
-
-/*
- * Cleans the project using ant
- */
-module.exports.run = function() {
-    var cmd = 'ant clean -f ' + path.join(ROOT, 'build.xml');
-    var result = shell.exec(cmd, {silent:false, async:false});
-    if (result.code > 0) {
-        console.error('ERROR: Failed to clean android project.');
-        console.error(result.output);
-        process.exit(2);
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'clean')));
-    console.log('Cleans the project directory.');
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js
deleted file mode 100755
index 363dc2b..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/device.js
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    build = require('./build'),
-    appinfo = require('./appinfo'),
-    exec  = require('child_process').exec,
-    ROOT = path.join(__dirname, '..', '..');
-
-/**
- * Returns a list of the device ID's found
- */
-module.exports.list = function() {
-    var cmd = 'adb devices';
-    var result = shell.exec(cmd, {silent:true, async:false});
-    if (result.code > 0) {
-        console.error('Failed to execute android command \'' + cmd + '\'.');
-        process.exit(2);
-    } else {
-        var response = result.output.split('\n');
-        var device_list = [];
-        for (var i = 1; i < response.length; i++) {
-            if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
-                device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
-            }
-        }
-        return device_list;
-    }
-}
-
-/*
- * Installs a previously built application on the device
- * and launches it.
- */
-module.exports.install = function(target) {
-    var device_list = this.list();
-    if (device_list.length > 0) {
-        // default device
-        target = typeof target !== 'undefined' ? target : device_list[0];
-        if (device_list.indexOf(target) > -1) {
-            var apk_path = build.get_apk();
-            var launchName = appinfo.getActivityName();
-            console.log('Installing app on device...');
-            cmd = 'adb -s ' + target + ' install -r ' + apk_path;
-            var install = shell.exec(cmd, {silent:false, async:false});
-            if (install.error || install.output.match(/Failure/)) {
-                console.error('ERROR : Failed to install apk to device : ');
-                console.error(install.output);
-                process.exit(2);
-            }
-
-            //unlock screen
-            cmd = 'adb -s ' + target + ' shell input keyevent 82';
-            shell.exec(cmd, {silent:true, async:false});
-
-            // launch the application
-            console.log('Launching application...');
-            cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
-            var launch = shell.exec(cmd, {silent:true, async:false});
-            if(launch.code > 0) {
-                console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
-                console.error(launch.output);
-                process.exit(2);
-            } else {
-                console.log('LAUNCH SUCCESS');
-            }
-        } else {
-            console.error('ERROR : Unable to find target \'' + target + '\'.');
-            console.error('Failed to deploy to device.');
-            process.exit(2);
-        }
-    } else {
-        console.error('ERROR : Failed to deploy to device, no devices found.');
-        process.exit(2);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js
deleted file mode 100755
index cc658a9..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/emulator.js
+++ /dev/null
@@ -1,337 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    appinfo = require('./appinfo'),
-    build = require('./build'),
-    ROOT  = path.join(__dirname, '..', '..'),
-    new_emulator = 'cordova_emulator';
-
-/**
- * Returns a list of emulator images in the form of objects
- * {
-       name   : <emulator_name>,
-       path   : <path_to_emulator_image>,
-       target : <api_target>,
-       abi    : <cpu>,
-       skin   : <skin>
-   }
- */
-module.exports.list_images = function() {
-    var cmd = 'android list avds';
-    var result = shell.exec(cmd, {silent:true, async:false});
-    if (result.code > 0) {
-        console.error('Failed to execute android command \'' + cmd + '\'.');
-        process.exit(2);
-    } else {
-        var response = result.output.split('\n');
-        var emulator_list = [];
-        for (var i = 1; i < response.length; i++) {
-            // To return more detailed information use img_obj
-            var img_obj = {};
-            if (response[i].match(/Name:\s/)) {
-                img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
-                if (response[i + 1].match(/Path:\s/)) {
-                    i++;
-                    img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
-                }
-                if (response[i + 1].match(/\(API\slevel\s/)) {
-                    i++;
-                    img_obj['target'] = response[i].replace('\r', '');
-                }
-                if (response[i + 1].match(/ABI:\s/)) {
-                    i++;
-                    img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
-                }
-                if (response[i + 1].match(/Skin:\s/)) {
-                    i++;
-                    img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
-                }
-
-                emulator_list.push(img_obj);
-            }
-            /* To just return a list of names use this
-            if (response[i].match(/Name:\s/)) {
-                emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
-            }*/
-
-        }
-        return emulator_list;
-    }
-}
-
-/**
- * Will return the closest avd to the projects target
- * or undefined if no avds exist.
- */
-module.exports.best_image = function() {
-    var project_target = this.get_target().replace('android-', '');
-    var images = this.list_images();
-    var closest = 9999;
-    var best = images[0];
-    for (i in images) {
-        var target = images[i].target;
-        if(target) {
-            var num = target.split('(API level ')[1].replace(')', '');
-            if (num == project_target) {
-                return images[i];
-            } else if (project_target - num < closest && project_target > num) {
-                var closest = project_target - num;
-                best = images[i];
-            }
-        }
-    }
-    return best;
-}
-
-module.exports.list_started = function() {
-    var cmd = 'adb devices';
-    var result = shell.exec(cmd, {silent:true, async:false});
-    if (result.code > 0) {
-        console.error('Failed to execute android command \'' + cmd + '\'.');
-        process.exit(2);
-    } else {
-        var response = result.output.split('\n');
-        var started_emulator_list = [];
-        for (var i = 1; i < response.length; i++) {
-            if (response[i].match(/device/) && response[i].match(/emulator/)) {
-                started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
-            }
-        }
-        return started_emulator_list;
-    }
-}
-
-module.exports.get_target = function() {
-    var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
-    return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
-}
-
-module.exports.list_targets = function() {
-    var target_out = shell.exec('android list targets', {silent:true, async:false}).output.split('\n');
-    var targets = [];
-    for (var i = target_out.length; i >= 0; i--) {
-        if(target_out[i].match(/id:/)) {
-            targets.push(targets[i].split(' ')[1]);
-        }
-    }
-    return targets;
-}
-
-/*
- * Starts an emulator with the given ID,
- * and returns the started ID of that emulator.
- * If no ID is given it will used the first image availible,
- * if no image is availible it will error out (maybe create one?).
- */
-module.exports.start = function(emulator_ID) {
-    var started_emulators = this.list_started();
-    var num_started = started_emulators.length;
-    if (typeof emulator_ID === 'undefined') {
-        var emulator_list = this.list_images();
-        if (emulator_list.length > 0) {
-            emulator_ID = this.best_image().name;
-            console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID);
-        } else {
-            console.error('ERROR : No emulator images (avds) found, if you would like to create an');
-            console.error(' avd follow the instructions provided here : ');
-            console.error(' http://developer.android.com/tools/devices/index.html')
-            console.error(' Or run \'android create avd --name <name> --target <targetID>\' ');
-            console.error(' in on the command line.');
-            process.exit(2);
-            /*console.log('WARNING : no emulators availible, creating \'' + new_emulator + '\'.');
-            this.create_image(new_emulator, this.get_target());
-            emulator_ID = new_emulator;*/
-        }
-    }
-
-    var pipe_null = (process.platform == 'win32' || process.platform == 'win64'? '> NUL' : '> /dev/null');
-    var cmd = 'emulator -avd ' + emulator_ID + ' ' + pipe_null + ' &';
-    if(process.platform == 'win32' || process.platform == 'win64') {
-        cmd = '%comspec% /c start cmd /c ' + cmd;
-    }
-    var result = shell.exec(cmd, {silent:true, async:false}, function(code, output) {
-        if (code > 0) {
-            console.error('Failed to execute android command \'' + cmd + '\'.');
-            console.error(output);
-            process.exit(2);
-        }
-    });
-
-    // wait for emulator to start
-    console.log('Waiting for emulator...');
-    var new_started = this.wait_for_emulator(num_started);
-    var emulator_id;
-    if (new_started.length > 1) {
-        for (i in new_started) {
-            console.log(new_started[i]);
-            console.log(started_emulators.indexOf(new_started[i]));
-            if (started_emulators.indexOf(new_started[i]) < 0) {
-                emulator_id = new_started[i];
-            }
-        }
-    } else {
-        emulator_id = new_started[0];
-    }
-    if (!emulator_id) {
-        console.error('ERROR :  Failed to start emulator, could not find new emulator');
-        process.exit(2);
-    }
-
-    //wait for emulator to boot up
-    process.stdout.write('Booting up emulator (this may take a while)...');
-    this.wait_for_boot(emulator_id);
-    console.log('BOOT COMPLETE');
-
-    //unlock screen
-    cmd = 'adb -s ' + emulator_id + ' shell input keyevent 82';
-    shell.exec(cmd, {silent:false, async:false});
-
-    //return the new emulator id for the started emulators
-    return emulator_id;
-}
-
-/*
- * Waits for the new emulator to apear on the started-emulator list.
- */
-module.exports.wait_for_emulator = function(num_running) {
-    var new_started = this.list_started();
-    if (new_started.length > num_running) {
-        return new_started;
-    } else {
-        this.sleep(1);
-        return this.wait_for_emulator(num_running);
-    }
-}
-
-/*
- * Waits for the boot animation property of the emulator to switch to 'stopped'
- */
-module.exports.wait_for_boot = function(emulator_id) {
-    var cmd;
-    // ShellJS opens a lot of file handles, and the default on OS X is too small.
-    // TODO : This is not working, need to find a better way to increese the ulimit.
-    if(process.platform == 'win32' || process.platform == 'win64') {
-        cmd = 'adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
-    } else {
-        cmd = 'ulimit -S -n 4096; adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
-    }
-    var boot_anim = shell.exec(cmd, {silent:true, async:false});
-    if (boot_anim.output.match(/stopped/)) {
-        return;
-    } else {
-        process.stdout.write('.');
-        this.sleep(3);
-        return this.wait_for_boot(emulator_id);
-    }
-}
-
-/*
- * TODO : find a better way to wait for the emulator (maybe using async methods?)
- */
-module.exports.sleep = function(time_sec) {
-    if (process.platform == 'win32' || process.platform == 'win64') {
-        shell.exec('ping 127.0.0.1 -n ' + time_sec, {silent:true, async:false});
-    } else {
-        shell.exec('sleep ' + time_sec, {silent:true, async:false});
-    }
-}
-
-/*
- * Create avd
- * TODO : Enter the stdin input required to complete the creation of an avd.
- */
-module.exports.create_image = function(name, target) {
-    console.log('Creating avd named ' + name);
-    if (target) {
-        var cmd = 'android create avd --name ' + name + ' --target ' + target;
-        var create = shell.exec(cmd, {sient:false, async:false});
-        if (create.error) {
-            console.error('ERROR : Failed to create emulator image : ');
-            console.error(' Do you have the latest android targets including ' + target + '?');
-            console.error(create.output);
-            process.exit(2);
-        }
-    } else {
-        console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
-        var cmd = 'android create avd --name ' + name + ' --target ' + this.list_targets()[0];
-        var create = shell.exec(cmd, {sient:false, async:false});
-        if (create.error) {
-            console.error('ERROR : Failed to create emulator image : ');
-            console.error(create.output);
-            process.exit(2);
-        }
-        console.error('ERROR : Unable to create an avd emulator, no targets found.');
-        console.error('Please insure you have targets availible by runing the "android" command').
-        process.exit(2);
-    }
-}
-
-/*
- * Installs a previously built application on the emulator and launches it.
- * If no target is specified, then it picks one.
- * If no started emulators are found, error out.
- */
-module.exports.install = function(target) {
-    var emulator_list = this.list_started();
-    if (emulator_list.length < 1) {
-        console.error('ERROR : No started emulators found, please start an emultor before deploying your project.');
-        process.exit(2);
-        /*console.log('WARNING : No started emulators found, attemting to start an avd...');
-        this.start(this.best_image().name);*/
-    }
-    // default emulator
-    target = typeof target !== 'undefined' ? target : emulator_list[0];
-    if (emulator_list.indexOf(target) > -1) {
-        console.log('Installing app on emulator...');
-        var apk_path = build.get_apk();
-        var cmd = 'adb -s ' + target + ' install -r ' + apk_path;
-        var install = shell.exec(cmd, {sient:false, async:false});
-        if (install.error || install.output.match(/Failure/)) {
-            console.error('ERROR : Failed to install apk to emulator : ');
-            console.error(install.output);
-            process.exit(2);
-        }
-
-        //unlock screen
-        cmd = 'adb -s ' + target + ' shell input keyevent 82';
-        shell.exec(cmd, {silent:true, async:false});
-
-        // launch the application
-        console.log('Launching application...');
-        var launchName = appinfo.getActivityName();
-        cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
-        console.log(cmd);
-        var launch = shell.exec(cmd, {silent:false, async:false});
-        if(launch.code > 0) {
-            console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
-            console.error(launch.output);
-            process.exit(2);
-        } else {
-            console.log('LAUNCH SUCCESS');
-        }
-    } else {
-        console.error('ERROR : Unable to find target \'' + target + '\'.');
-        console.error('Failed to deploy to emulator.');
-        process.exit(2);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device
deleted file mode 100755
index 679efbf..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-device
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var device = require('./device'),
-    args   = process.argv;
-
-if(args.length > 2) {
-    var install_target;
-    if (args[2].substring(0, 9) == '--target=') {
-        install_target = args[2].substring(9, args[2].length);
-        device.install(install_target);
-        process.exit(0);
-     } else {
-        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
-        process.exit(2);
-     }
-} else {
-    device.install();
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator
deleted file mode 100755
index c006eb2..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/install-emulator
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulator = require('./emulator'),
-    args     = process.argv;
-
-if(args.length > 2) {
-    var install_target;
-    if (args[2].substring(0, 9) == '--target=') {
-        install_target = args[2].substring(9, args[2].length);
-        emulator.install(install_target);
-        process.exit(0);
-     } else {
-        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
-        process.exit(2);
-     }
-} else {
-    emulator.install();
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices
deleted file mode 100755
index 3ef4efa..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-devices
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var devices = require('./device');
-
-// Usage support for when args are given
-var device_list = devices.list();
-for(device in device_list) {
-    console.log(device_list[device]);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images
deleted file mode 100755
index 3230537..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-emulator-images
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulators = require('./emulator');
-
-// Usage support for when args are given
-var emulator_list = emulators.list_images();
-for(emulator in emulator_list) {
-    console.log(emulator_list[emulator].name);
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators
deleted file mode 100755
index 525a64c..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/list-started-emulators
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulators = require('./emulator');
-
-// Usage support for when args are given
-var emulator_list = emulators.list_started();
-for(emulator in emulator_list) {
-    console.log(emulator_list[emulator]);
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js
deleted file mode 100755
index b85cf60..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/log.js
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell = require('shelljs'),
-    path  = require('path'),
-    ROOT = path.join(__dirname, '..', '..');
-
-/*
- * Starts running logcat in the shell.
- */
-module.exports.run = function() {
-    var cmd = 'adb logcat | grep -v nativeGetEnabledTags';
-    var result = shell.exec(cmd, {silent:false, async:false});
-    if (result.code > 0) {
-        console.error('ERROR: Failed to run logcat command.');
-        console.error(result.output);
-        process.exit(2);
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'log')));
-    console.log('Gives the logcat output on the command line.');
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js
deleted file mode 100755
index 787d123..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/run.js
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var path  = require('path'),
-    build = require('./build'),
-    emulator = require('./emulator'),
-    device   = require('./device'),
-    ROOT = path.join(__dirname, '..', '..');
-
-/*
- * Runs the application on a device if availible.
- * If not device is found, it will use a started emulator.
- * If no started emulators are found it will attempt to start an avd.
- * If no avds are found it will error out.
- */
- module.exports.run = function(args) {
-    var build_type;
-    var install_target;
-
-    for (var i=2; i<args.length; i++) {
-        if (args[i] == '--debug') {
-            build_type = '--debug';
-        } else if (args[i] == '--release') {
-            build_type = '--release';
-        } else if (args[i] == '--nobuild') {
-            build_type = '--nobuild';
-        } else if (args[i] == '--device') {
-            install_target = '--device';
-        } else if (args[i] == '--emulator') {
-            install_target = '--emulator';
-        } else if (args[i].substring(0, 9) == '--target=') {
-            install_target = args[i].substring(9, args[i].length);
-        } else {
-            console.error('ERROR : Run option \'' + args[i] + '\' not recognized.');
-            process.exit(2);
-        }
-    }
-    build.run(build_type);
-    if (install_target == '--device') {
-        device.install();
-    } else if (install_target == '--emulator') {
-        if (emulator.list_started() == 0) {
-            emulator.start();
-        }
-        emulator.install();
-    } else if (install_target) {
-        var devices = device.list();
-        var started_emulators = emulator.list_started();
-        var avds = emulator.list_images();
-        if (devices.indexOf(install_target) > -1) {
-            device.install(install_target);
-        } else if (started_emulators.indexOf(install_target) > -1) {
-            emulator.install(install_target);
-        } else {
-            // if target emulator isn't started, then start it.
-            var emulator_ID;
-            for(avd in avds) {
-                if(avds[avd].name == install_target) {
-                    emulator_ID = emulator.start(install_target);
-                    emulator.install(emulator_ID);
-                    break;
-                }
-            }
-            if(!emulator_ID) {
-                console.error('ERROR : Target \'' + install_target + '\' not found, unalbe to run project');
-                process.exit(2);
-            }
-        }
-    } else {
-        // no target given, deploy to device if availible, otherwise use the emulator.
-        var device_list = device.list();
-        if (device_list.length > 0) {
-            console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.');
-            device.install(device_list[0])
-        } else {
-            var emulator_list = emulator.list_started();
-            if (emulator_list.length > 0) {
-                console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.');
-                emulator.install(emulator_list[0]);
-            } else {
-                console.log('WARNING : No started emulators found, starting an emulator.');
-                var best_avd = emulator.best_image();
-                if(best_avd) {
-                    var emulator_ID = emulator.start(best_avd.name);
-                    console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.');
-                    emulator.install(emulator_ID);
-                } else {
-                    emulator.start();
-                }
-            }
-        }
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'run')) + ' [options]');
-    console.log('Build options :');
-    console.log('    --debug : Builds project in debug mode');
-    console.log('    --release : Builds project in release mode');
-    console.log('    --nobuild : Runs the currently built project without recompiling');
-    console.log('Deploy options :');
-    console.log('    --device : Will deploy the built project to a device');
-    console.log('    --emulator : Will deploy the built project to an emulator if one exists');
-    console.log('    --target=<target_id> : Installs to the target with the specified id.');
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator
deleted file mode 100755
index 5d6c4dd..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/start-emulator
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var emulator = require('./emulator'),
-      args   = process.argv;
-
-if(args.length > 2) {
-    var install_target;
-    if (args[2].substring(0, 9) == '--target=') {
-        install_target = args[2].substring(9, args[2].length);
-        emulator.start(install_target);
-        process.exit(0);
-     } else {
-        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
-        process.exit(2);
-     }
-} else {
-    emulator.start();
-    process.exit(0);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log
deleted file mode 100755
index 087325f..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/log
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var log  = require('./lib/log'),
-    reqs = require('./lib/check_reqs'),
-    args = process.argv;
-
-// Usage support for when args are given
-if(args.length > 2) {
-    log.help();
-} else if(reqs.run()) {
-    log.run();
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run
deleted file mode 100755
index 57d7345..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/run
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var run  = require('./lib/run'),
-    reqs = require('./lib/check_reqs'),
-    args = process.argv;
-
-// Support basic help commands
-if (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
-                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
-    run.help();
-} else if(reqs.run()) {
-    run.run(args);
-    process.exit(0);
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version
deleted file mode 100755
index de1a76d..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/version
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-// Coho updates this line:
-var VERSION = "3.1.0";
-
-console.log(VERSION);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties b/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties
deleted file mode 100644
index d3f5072..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/local.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must *NOT* be checked into Version Control Systems,
-# as it contains information specific to your local configuration.
-
-# location of the SDK. This is only used by Ant
-# For customization when using a Version Control System, please read the
-# header note.
-sdk.dir=/Users/braden/cordova/android/android-sdk-macosx

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt b/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties b/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties
deleted file mode 100644
index a3ee5ab..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-17

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png
deleted file mode 100644
index 4d27634..0000000
Binary files a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-hdpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png
deleted file mode 100644
index cd5032a..0000000
Binary files a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-ldpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png
deleted file mode 100644
index e79c606..0000000
Binary files a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-mdpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png
deleted file mode 100644
index ec7ffbf..0000000
Binary files a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable-xhdpi/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png b/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png
deleted file mode 100644
index ec7ffbf..0000000
Binary files a/cordova-lib/spec-cordova/fixtures/platforms/android/res/drawable/icon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml
deleted file mode 100644
index 1e706b3..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/res/values/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<resources>
-    <string name="app_name">TestBase</string>
-</resources>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml
deleted file mode 100644
index 17ca237..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/res/xml/config.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <name>Hello Cordova</name>
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-    <access origin="*" />
-    <preference name="loglevel" value="DEBUG" />
-    <feature name="App">
-        <param name="android-package" value="org.apache.cordova.App" />
-    </feature>
-    <author email="dev@cordova.apache.org" href="http://cordova.io">
-        Apache Cordova Team
-    </author>
-    <content src="index.html" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java b/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java
deleted file mode 100644
index 928e074..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/src/org/testing/TestBase.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
- */
-
-package org.testing;
-
-import android.os.Bundle;
-import org.apache.cordova.*;
-
-public class TestBase extends CordovaActivity 
-{
-    @Override
-    public void onCreate(Bundle savedInstanceState)
-    {
-        super.onCreate(savedInstanceState);
-        super.init();
-        // Set by <content src="index.html" /> in config.xml
-        super.loadUrl(Config.getStartUrl());
-        //super.loadUrl("file:///android_asset/www/index.html")
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml
deleted file mode 100644
index 512c02f..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/plugin.xml
+++ /dev/null
@@ -1,142 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- Copyright 2013 Anis Kadri
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-
--->
-
-<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    id="com.phonegap.plugins.childbrowser"
-    version="0.6.0">
-
-    <name>Child Browser</name>
-
-    <asset src="www/childbrowser" target="childbrowser" />
-    <asset src="www/childbrowser_file.html" target="childbrowser_file.html" />
-
-    <js-module src="www/childbrowser.js" name="ChildBrowser">
-        <clobbers target="childbrowser" />
-    </js-module>
-
-    <config-file target="config.xml" parent="/*">
-        <access origin="build.phonegap.com" />
-        <access origin="s3.amazonaws.com" />
-    </config-file>
-    
-    <info>No matter what platform you are installing to, this notice is very important.</info>
-
-    <!-- android -->
-    <platform name="android">
-        <config-file target="AndroidManifest.xml" parent="/manifest/application">
-            <activity android:name="com.phonegap.plugins.childBrowser.ChildBrowser"
-                      android:label="@string/app_name">
-                <intent-filter>
-                </intent-filter>
-            </activity>
-        </config-file>
-
-        <!-- CDV < 2.0 -->
-        <config-file target="res/xml/plugins.xml" parent="/plugins">
-            <plugin name="ChildBrowser"
-                value="com.phonegap.plugins.childBrowser.ChildBrowser"/>
-        </config-file>
-
-        <!-- CDV 2.0+ (for now) -->
-        <config-file target="res/xml/config.xml" parent="/cordova/plugins">
-            <plugin name="ChildBrowser"
-                value="com.phonegap.plugins.childBrowser.ChildBrowser"/>
-        </config-file>
-
-        <source-file src="src/android/ChildBrowser.java"
-                target-dir="src/com/phonegap/plugins/childBrowser" />
-        <info>Please make sure you read this because it is very important to complete the installation of your plugin.</info>
-    </platform>
-
-    <!-- ios -->
-    <platform name="ios">
-        <plugins-plist key="com.phonegap.plugins.childbrowser"
-            string="ChildBrowserCommand" />
-
-        <config-file target="config.xml" parent="/widget/plugins">
-            <plugin name="ChildBrowser"
-                value="ChildBrowserCommand" />
-        </config-file>
-
-        <resource-file src="src/ios/ChildBrowser.bundle" />
-        <resource-file src="src/ios/ChildBrowserViewController.xib" />
-
-        <config-file target="*-Info.plist" parent="AppId">
-            <string>$APP_ID</string>
-        </config-file>
-        
-        <config-file target="*-Info.plist" parent="CFBundleURLTypes">
-            <array>
-              <dict>
-                <key>PackageName</key>
-                <string>$PACKAGE_NAME</string>
-              </dict>
-            </array>
-        </config-file>
-
-        <header-file src="src/ios/ChildBrowserCommand.h" />
-        <header-file src="src/ios/ChildBrowserViewController.h" />
-        <header-file src="src/ios/TargetDirTest.h" target-dir="targetDir"/>
-
-        <source-file src="src/ios/ChildBrowserCommand.m" />
-        <source-file src="src/ios/ChildBrowserViewController.m" />
-        <source-file src="src/ios/preserveDirs/PreserveDirsTest.m" preserve-dirs="true" />
-        <header-file src="src/ios/TargetDirTest.m" target-dir="targetDir"/>
-
-        <!-- framework for testing (not actual dependency of ChildBrowser -->
-        <framework src="libsqlite3.dylib" />
-        <framework src="social.framework" weak="true" />
-        <framework src="music.framework" weak="rabbit" />
-    </platform>
-    <!-- wp7 -->
-    <platform name="wp7">
-        <resource-file src="src\wp7\Images\appbar.back.rest.png" />
-        <config-file target="config.xml" parent="/widget/plugins">
-            <plugin name="ChildBrowser"
-                value="ChildBrowser"/>
-        </config-file>
-
-        <source-file src="src\wp7\ChildBrowserCommand.cs"
-                     target-dir="Plugins\" />
-
-        <!-- modify the project file to include the added files -->
-        <config-file target=".csproj" parent=".">  
-        </config-file> 
-
-    </platform>
-
-    <!-- wp8 -->
-    <platform name="wp8">
-        <resource-file src="src\wp7\Images\appbar.back.rest.png" />
-        <config-file target="config.xml" parent="/widget/plugins">
-            <plugin name="ChildBrowser"
-                value="ChildBrowser"/>
-        </config-file>
-
-        <source-file src="src\wp7\ChildBrowserCommand.cs"
-                     target-dir="Plugins\" />
-
-        <!-- modify the project file to include the added files -->
-        <config-file target=".csproj" parent=".">  
-        </config-file> 
-
-    </platform>
-</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
deleted file mode 100644
index 5263b0c..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/src/android/ChildBrowser.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *
- * Copyright 2013 Anis Kadri
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js
deleted file mode 100644
index 5263b0c..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *
- * Copyright 2013 Anis Kadri
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
deleted file mode 100644
index 257cc56..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser/image.jpg
+++ /dev/null
@@ -1 +0,0 @@
-foo

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html b/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
deleted file mode 100644
index 6de7b8c..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/ChildBrowser/www/childbrowser_file.html
+++ /dev/null
@@ -1 +0,0 @@
-This is a test file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml b/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml
deleted file mode 100644
index d8f5619..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/android/plugin.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    id="ca.filmaj.AndroidPlugin"
-    version="4.2.0">
-
-    <name>Android Plugin</name>
-
-    <asset src="www/android.js" target="android.js" />
-    <platform name="android">
-    </platform>
-</plugin>
-
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/Android.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/Android.java b/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/Android.java
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java b/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java
deleted file mode 100644
index c3af060..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/android/src/android/SomethingWithR.java
+++ /dev/null
@@ -1,6 +0,0 @@
-import com.yourapp.R;
-
-import android.app.*;
-
-public class SomethingWithR {
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/android/www/android.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/android/www/android.js b/cordova-lib/spec-cordova/fixtures/plugins/android/www/android.js
deleted file mode 100644
index e69de29..0000000

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

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml b/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml
deleted file mode 100644
index 774eda1..0000000
--- a/cordova-lib/spec-cordova/fixtures/plugins/test/plugin.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    id="com.phonegap.plugins.childbrowser"
-    version="3.0.0">
-
-    <name>Test Plugin</name>
-
-    <asset src="www/test.js" target="test.js" />
-    <platform name="ios">
-        <plugins-plist key="TestPlugin" string="Test" />
-    </platform>
-</plugin>
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/plugins/test/www/test.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/plugins/test/www/test.js b/cordova-lib/spec-cordova/fixtures/plugins/test/www/test.js
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml b/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml
deleted file mode 100644
index 0c52803..0000000
--- a/cordova-lib/spec-cordova/fixtures/projects/android/AndroidManifest.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
- Copyright 2013 Anis Kadri
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
-      package="com.alunny.childapp" android:versionName="1.1" android:versionCode="5">
-    <supports-screens
-    	android:largeScreens="true"
-    	android:normalScreens="true"
-    	android:smallScreens="true"
-    	android:xlargeScreens="true"
-    	android:resizeable="true"
-    	android:anyDensity="true"
-    	/>
-
-    <uses-permission android:name="android.permission.CAMERA" />
-    <uses-permission android:name="android.permission.VIBRATE" />
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.RECEIVE_SMS" />
-    <uses-permission android:name="android.permission.RECORD_AUDIO" />
-    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
-    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />   
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />   
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-
-    <uses-feature android:name="android.hardware.camera" />
-    <uses-feature android:name="android.hardware.camera.autofocus" />
-
-    <application android:icon="@drawable/icon" android:label="@string/app_name"
-    	android:debuggable="true">
-		<activity android:name="ChildApp" android:label="@string/app_name" 
-				  android:configChanges="orientation|keyboardHidden">
-			<intent-filter>
-				<action android:name="android.intent.action.MAIN" />
-				<category android:name="android.intent.category.LAUNCHER" />
-			</intent-filter>
-        </activity>
-        <activity android:name="com.phonegap.DroidGap" android:label="@string/app_name" 
-            	  android:configChanges="orientation|keyboardHidden">
-        	<intent-filter>
-        	</intent-filter>
-        </activity>
-    </application>
-
-	<uses-sdk android:minSdkVersion="5" />
-</manifest> 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/projects/android/assets/www/.gitkeep
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/assets/www/.gitkeep b/cordova-lib/spec-cordova/fixtures/projects/android/assets/www/.gitkeep
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml b/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml
deleted file mode 100644
index d37aba5..0000000
--- a/cordova-lib/spec-cordova/fixtures/projects/android/res/xml/config.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
--->
-<cordova>
-    <!--
-    access elements control the Android whitelist.
-    Domains are assumed blocked unless set otherwise
-     -->
-
-    <access origin="http://127.0.0.1*"/> <!-- allow local pages -->
-
-    <!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
-    <!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
-    <!-- <access origin=".*"/> Allow all domains, suggested development use only -->
-
-    <log level="DEBUG"/>
-    <preference name="useBrowserHistory" value="false" />
-<plugins>
-    <plugin name="App" value="org.apache.cordova.App"/>
-    <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
-    <plugin name="Device" value="org.apache.cordova.Device"/>
-    <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
-    <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
-    <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
-    <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
-    <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
-    <plugin name="File" value="org.apache.cordova.FileUtils"/>
-    <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
-    <plugin name="Notification" value="org.apache.cordova.Notification"/>
-    <plugin name="Storage" value="org.apache.cordova.Storage"/>
-    <plugin name="Temperature" value="org.apache.cordova.TempListener"/>
-    <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
-    <plugin name="Capture" value="org.apache.cordova.Capture"/>
-    <plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
-    <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
-</plugins>
-</cordova>
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/projects/android/src/.gitkeep
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/android/src/.gitkeep b/cordova-lib/spec-cordova/fixtures/projects/android/src/.gitkeep
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml b/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml
deleted file mode 100644
index 57cadf6..0000000
--- a/cordova-lib/spec-cordova/fixtures/projects/windows/bom_test.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-# http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
--->
-<widget>
-    <access origin="*"/>
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml b/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml
deleted file mode 100644
index 7c4ef3d..0000000
--- a/cordova-lib/spec-cordova/fixtures/templates/no_content_config.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
-        id        = "io.cordova.hellocordova"
-        version   = "0.0.1">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/helper.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/helper.js b/cordova-lib/spec-cordova/helper.js
deleted file mode 100644
index 351e6e4..0000000
--- a/cordova-lib/spec-cordova/helper.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/helpers.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/helpers.js b/cordova-lib/spec-cordova/helpers.js
deleted file mode 100644
index 3236516..0000000
--- a/cordova-lib/spec-cordova/helpers.js
+++ /dev/null
@@ -1,46 +0,0 @@
-
-var path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    os = require('os');
-
-module.exports.tmpDir = function(subdir) {
-    var dir = path.join(os.tmpdir(), 'e2e-test');
-    if (subdir) {
-        dir = path.join(dir, subdir);
-    }
-    shell.mkdir('-p', dir);
-    return dir;
-};
-
-// Returns the platform that should be used for testing on this host platform.
-/*
-var host = os.platform();
-if (host.match(/win/)) {
-    module.exports.testPlatform = 'wp8';
-} else if (host.match(/darwin/)) {
-    module.exports.testPlatform = 'ios';
-} else {
-    module.exports.testPlatform = 'android';
-}
-*/
-
-// Just use Android everywhere; we're mocking out any calls to the `android` binary.
-module.exports.testPlatform = 'android';
-
-// Add the toExist matcher.
-beforeEach(function() {
-    this.addMatchers({
-        'toExist': function() {
-            var notText = this.isNot ? ' not' : '';
-            var self = this;
-
-            this.message = function() {
-                return 'Expected file ' + self.actual + notText + ' to exist.';
-            };
-
-            return fs.existsSync(this.actual);
-        }
-    });
-});
-


[15/24] Remove all cordova-lib files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/templates/hooks-README.md
----------------------------------------------------------------------
diff --git a/cordova-lib/templates/hooks-README.md b/cordova-lib/templates/hooks-README.md
deleted file mode 100644
index d2563ea..0000000
--- a/cordova-lib/templates/hooks-README.md
+++ /dev/null
@@ -1,83 +0,0 @@
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
--->
-# Cordova Hooks
-
-This directory may contain scripts used to customize cordova commands. This
-directory used to exist at `.cordova/hooks`, but has now been moved to the
-project root. Any scripts you add to these directories will be executed before
-and after the commands corresponding to the directory name. Useful for
-integrating your own build systems or integrating with version control systems.
-
-__Remember__: Make your scripts executable.
-
-## Hook Directories
-The following subdirectories will be used for hooks:
-
-    after_build/
-    after_compile/
-    after_docs/
-    after_emulate/
-    after_platform_add/
-    after_platform_rm/
-    after_platform_ls/
-    after_plugin_add/
-    after_plugin_ls/
-    after_plugin_rm/
-    after_plugin_search/
-    after_prepare/
-    after_run/
-    after_serve/
-    before_build/
-    before_compile/
-    before_docs/
-    before_emulate/
-    before_platform_add/
-    before_platform_rm/
-    before_platform_ls/
-    before_plugin_add/
-    before_plugin_ls/
-    before_plugin_rm/
-    before_plugin_search/
-    before_prepare/
-    before_run/
-    before_serve/
-    pre_package/ <-- Windows 8 and Windows Phone only.
-
-## Script Interface
-
-All scripts are run from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables:
-
-* CORDOVA_VERSION - The version of the Cordova-CLI.
-* CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios).
-* CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer)
-* CORDOVA_HOOK - Path to the hook that is being executed.
-* CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate)
-
-If a script returns a non-zero exit code, then the parent cordova command will be aborted.
-
-
-## Writing hooks
-
-We highly recommend writting your hooks using Node.js so that they are
-cross-platform. Some good examples are shown here:
-
-[http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/)
-


[02/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/lazy_load.js
----------------------------------------------------------------------
diff --git a/src/lazy_load.js b/src/lazy_load.js
deleted file mode 100644
index bd6cf77..0000000
--- a/src/lazy_load.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var path          = require('path'),
-    fs            = require('fs'),
-    shell         = require('shelljs'),
-    platforms     = require('../platforms'),
-    npmconf       = require('npmconf'),
-    events        = require('./events'),
-    request       = require('request'),
-    config        = require('./config'),
-    hooker        = require('./hooker'),
-    zlib          = require('zlib'),
-    tar           = require('tar'),
-    URL           = require('url'),
-    Q             = require('q'),
-    util          = require('./util');
-
-module.exports = {
-    // Returns a promise for the path to the lazy-loaded directory.
-    cordova:function lazy_load(platform) {
-        if (!(platform in platforms)) {
-            return Q.reject(new Error('Cordova library "' + platform + '" not recognized.'));
-        }
-
-        var url = platforms[platform].url + ';a=snapshot;h=' + platforms[platform].version + ';sf=tgz';
-        return module.exports.custom(url, 'cordova', platform, platforms[platform].version);
-    },
-    // Returns a promise for the path to the lazy-loaded directory.
-    custom:function(url, id, platform, version) {
-        var download_dir;
-        var tmp_dir;
-        var lib_dir;
-
-        // Return early for already-cached remote URL, or for local URLs.
-        var uri = URL.parse(url);
-        var isUri = uri.protocol && uri.protocol[1] != ':'; // second part of conditional is for awesome windows support. fuuu windows
-        if (isUri) {
-            download_dir = (platform == 'wp7' || platform == 'wp8' ? path.join(util.libDirectory, 'wp', id, version) :
-                                                                     path.join(util.libDirectory, platform, id, version));
-            lib_dir = platforms[platform] && platforms[platform].subdirectory && platform !== "blackberry10" ? path.join(download_dir, platforms[platform].subdirectory) : download_dir;
-            if (fs.existsSync(download_dir)) {
-                events.emit('verbose', id + ' library for "' + platform + '" already exists. No need to download. Continuing.');
-                return Q(lib_dir);
-            }
-        } else {
-            // Local path.
-            lib_dir = platforms[platform] && platforms[platform].subdirectory ? path.join(url, platforms[platform].subdirectory) : url;
-            return Q(lib_dir);
-        }
-        return hooker.fire('before_library_download', {
-            platform:platform,
-            url:url,
-            id:id,
-            version:version
-        }).then(function() {
-            var uri = URL.parse(url);
-            var d = Q.defer();
-            npmconf.load(function(err, conf) {
-                // Check if NPM proxy settings are set. If so, include them in the request() call.
-                var proxy;
-                if (uri.protocol == 'https:') {
-                    proxy = conf.get('https-proxy');
-                } else if (uri.protocol == 'http:') {
-                    proxy = conf.get('proxy');
-                }
-                var strictSSL = conf.get('strict-ssl');
-
-                // Create a tmp dir. Using /tmp is a problem because it's often on a different partition and sehll.mv()
-                // fails in this case with "EXDEV, cross-device link not permitted".
-                tmp_subidr = 'tmp_' + id + '_' + process.pid + '_' + (new Date).valueOf();
-                tmp_dir = path.join(util.libDirectory, 'tmp', tmp_subidr);
-                shell.rm('-rf', tmp_dir);
-                shell.mkdir('-p', tmp_dir);
-
-                var size = 0;
-                var request_options = {uri:url};
-                if (proxy) {
-                    request_options.proxy = proxy;
-                }
-                if (typeof strictSSL == 'boolean') {
-                    request_options.strictSSL = strictSSL;
-                }
-                events.emit('verbose', 'Requesting ' + JSON.stringify(request_options) + '...');
-                events.emit('log', 'Downloading ' + id + ' library for ' + platform + '...');
-                var req = request.get(request_options, function(err, res, body) {
-                    if (err) {
-                        shell.rm('-rf', tmp_dir);
-                        d.reject(err);
-                    } else if (res.statusCode != 200) {
-                        shell.rm('-rf', tmp_dir);
-                        d.reject(new Error('HTTP error ' + res.statusCode + ' retrieving version ' + version + ' of ' + id + ' for ' + platform));
-                    } else {
-                        size = body.length;
-                    }
-                });
-
-                req.pipe(zlib.createUnzip())
-                .pipe(tar.Extract({path:tmp_dir}))
-                .on('error', function(err) {
-                    shell.rm('-rf', tmp_dir);
-                    d.reject(err);
-                })
-                .on('end', function() {
-                    events.emit('verbose', 'Downloaded, unzipped and extracted ' + size + ' byte response.');
-                    events.emit('log', 'Download complete');
-                    var entries = fs.readdirSync(tmp_dir);
-                    var entry = path.join(tmp_dir, entries[0]);
-                    shell.mkdir('-p', download_dir);
-                    shell.mv('-f', path.join(entry, (platform=='blackberry10'?'blackberry10':''), '*'), download_dir);
-                    shell.rm('-rf', tmp_dir);
-                    d.resolve(hooker.fire('after_library_download', {
-                        platform:platform,
-                        url:url,
-                        id:id,
-                        version:version,
-                        path: lib_dir,
-                        size:size,
-                        symlink:false
-                    }));
-                });
-            });
-            return d.promise.then(function () { return lib_dir; });
-        });
-    },
-    // Returns a promise for the path to the lazy-loaded directory.
-    based_on_config:function(project_root, platform) {
-        var custom_path = config.has_custom_path(project_root, platform);
-        if (custom_path) {
-            var dot_file = config.read(project_root);
-            return module.exports.custom(dot_file.lib[platform].uri, dot_file.lib[platform].id, platform, dot_file.lib[platform].version);
-        } else {
-            return module.exports.cordova(platform);
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/amazon_fireos_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/amazon_fireos_parser.js b/src/metadata/amazon_fireos_parser.js
deleted file mode 100644
index f119279..0000000
--- a/src/metadata/amazon_fireos_parser.js
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    project_config= require('../config'),
-    Q             = require('q'),
-    ConfigParser = require('../ConfigParser'),
-    CordovaError = require('../CordovaError');
-
-var awv_interface='awv_interface.jar';
-
-var default_prefs = {
-    "useBrowserHistory":"true",
-    "exit-on-suspend":"false"
-};
-
-module.exports = function android_parser(project) {
-    if (!fs.existsSync(path.join(project, 'AndroidManifest.xml'))) {
-        throw new CordovaError('The provided path "' + project + '" is not an Android project.');
-    }
-    this.path = project;
-    this.strings = path.join(this.path, 'res', 'values', 'strings.xml');
-    this.manifest = path.join(this.path, 'AndroidManifest.xml');
-    this.android_config = path.join(this.path, 'res', 'xml', 'config.xml');
-};
-
-// Returns a promise.
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    // Rely on platform's bin/create script to check requirements.
-    return Q(true);
-};
-
-module.exports.prototype = {
-    findOrientationPreference: function(config) {
-        var ret = config.getPreference('orientation');
-        if (ret && ret != 'default' && ret != 'portrait' && ret != 'landscape') {
-            events.emit('warn', 'Unknown value for orientation preference: ' + ret);
-            ret = null;
-        }
-
-        return ret;
-    },
-
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        // Update app name by editing res/values/strings.xml
-        var name = config.name();
-        var strings = xml.parseElementtreeSync(this.strings);
-        strings.find('string[@name="app_name"]').text = name;
-        fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
-        events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
-
-        var manifest = xml.parseElementtreeSync(this.manifest);
-        // Update the version by changing the AndroidManifest android:versionName
-        var version = config.version();
-        manifest.getroot().attrib["android:versionName"] = version;
-
-        // Update package name by changing the AndroidManifest id and moving the entry class around to the proper package directory
-        var pkg = config.packageName();
-        pkg = pkg.replace(/-/g, '_'); // Java packages cannot support dashes
-        var orig_pkg = manifest.getroot().attrib.package;
-        manifest.getroot().attrib.package = pkg;
-
-         // Set the orientation in the AndroidManifest
-        var orientationPref = this.findOrientationPreference(config);
-        if (orientationPref) {
-            var act = manifest.getroot().find('./application/activity');
-            switch (orientationPref) {
-                case 'default':
-                    delete act.attrib["android:screenOrientation"];
-                    break;
-                case 'portrait':
-                    act.attrib["android:screenOrientation"] = 'userPortrait';
-                    break;
-                case 'landscape':
-                    act.attrib["android:screenOrientation"] = 'userLandscape';
-            }
-        }
-
-
-        // Write out AndroidManifest.xml
-        fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
-
-        var orig_pkgDir = path.join(this.path, 'src', path.join.apply(null, orig_pkg.split('.')));
-        var java_files = fs.readdirSync(orig_pkgDir).filter(function(f) {
-          return f.indexOf('.svn') == -1 && f.indexOf('.java') >= 0 && fs.readFileSync(path.join(orig_pkgDir, f), 'utf-8').match(/extends\s+CordovaActivity/);
-        });
-        if (java_files.length == 0) {
-          throw new Error('No Java files found which extend CordovaActivity.');
-        } else if(java_files.length > 1) {
-          events.emit('log', 'Multiple candidate Java files (.java files which extend CordovaActivity) found. Guessing at the first one, ' + java_files[0]);
-        }
-
-        var orig_java_class = java_files[0];
-        var pkgDir = path.join(this.path, 'src', path.join.apply(null, pkg.split('.')));
-        shell.mkdir('-p', pkgDir);
-        var orig_javs = path.join(orig_pkgDir, orig_java_class);
-        var new_javs = path.join(pkgDir, orig_java_class);
-        var javs_contents = fs.readFileSync(orig_javs, 'utf-8');
-        javs_contents = javs_contents.replace(/package [\w\.]*;/, 'package ' + pkg + ';');
-        events.emit('verbose', 'Wrote out Android package name to "' + pkg + '"');
-        fs.writeFileSync(new_javs, javs_contents, 'utf-8');
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'assets', 'www');
-    },
-
-    config_xml:function(){
-        return this.android_config;
-    },
-
-     // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'framework', 'assets', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'amazon-fireos');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var platformWww = path.join(this.path, 'assets');
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-        this.update_overrides();
-        // delete any .svn folders copied over
-        util.deleteSvnFolders(platformWww);
-        return Q();
-    }
-};
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/android_parser.js b/src/metadata/android_parser.js
deleted file mode 100644
index ef50caf..0000000
--- a/src/metadata/android_parser.js
+++ /dev/null
@@ -1,303 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    project_config= require('../config'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError');
-
-var default_prefs = {
-    "useBrowserHistory":"true",
-    "exit-on-suspend":"false"
-};
-
-module.exports = function android_parser(project) {
-    if (!fs.existsSync(path.join(project, 'AndroidManifest.xml'))) {
-        throw new CordovaError('The provided path "' + project + '" is not an Android project.');
-    }
-    this.path = project;
-    this.strings = path.join(this.path, 'res', 'values', 'strings.xml');
-    this.manifest = path.join(this.path, 'AndroidManifest.xml');
-    this.android_config = path.join(this.path, 'res', 'xml', 'config.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    // Rely on platform's bin/create script to check requirements.
-    return Q(true);
-};
-
-module.exports.prototype = {
-    findOrientationPreference: function(config) {
-        var ret = config.getPreference('orientation');
-        if (ret && ret != 'default' && ret != 'portrait' && ret != 'landscape') {
-            events.emit('warn', 'Unknown value for orientation preference: ' + ret);
-            ret = null;
-        }
-
-        return ret;
-    },
-
-    findAndroidLaunchModePreference: function(config) {
-        var ret = config.getPreference('AndroidLaunchMode');
-        var valid = ['standard', 'singleTop', 'singleTask', 'singleInstance'].indexOf(ret) !== -1;
-        if (ret && !valid) {
-            events.emit('warn', 'Unknown value for launchMode preference: ' + ret);
-            ret = null;
-        }
-
-        return ret;
-    },
-
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        // Update app name by editing res/values/strings.xml
-        var name = config.name();
-        var strings = xml.parseElementtreeSync(this.strings);
-        strings.find('string[@name="app_name"]').text = name;
-        fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
-        events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
-
-        var icons = config.getIcons('android');
-        // if there are icon elements in config.xml
-        if (icons) {
-          var haveSeenDefaultIcon = false;
-          var iconCount = 0;
-          var android_icons = {};
-          var projectRoot = util.isCordova(this.path);
-          var default_icon;
-          var max_size;
-          var max_density;
-          // http://developer.android.com/design/style/iconography.html
-          var densities = {
-            "ldpi" : 36,
-            "mdpi" : 48,
-            "hdpi" : 72,
-            "xhdpi" : 96
-          };
-          for (var i=0; i<icons.length; i++) {
-            var icon = icons[i];
-            var destfilepath;
-            var size = icon.width;
-            if (!size) {
-              size = icon.height;
-            }
-            if (!size && !icon.density) {
-              if (default_icon) {
-                  events.emit('verbose', "more than one default icon: " + JSON.stringify(icon));
-              } else {
-                  default_icon = icon;
-              }
-            } else {
-              var parseIcon = function(icon, icon_size, size, density) {
-                // if density is explicitly defined, no need to calculate it from width/height
-                if (icon.density) {
-                    android_icons[icon.density] = icon;
-                    return;
-                }
-
-                var i = parseInt(icon_size);
-                if (size == parseInt(icon_size)) {
-                  var previous = android_icons[density];
-                  if (previous) {
-                    // already have that density. platform rules
-                    if (!previous.platform) {
-                      android_icons[density] = icon;
-                    } // else already have a platform icon of that density
-                  } else {
-                    android_icons[density] = icon;
-                  }
-                  android_icons[density] = icon;
-                  if (!max_size) {
-                    max_size = size;
-                    max_density = density;
-                  } else {
-                    if (max_size < size) {
-                      max_size = size
-                      max_density = density;
-                    }
-                  }
-                }
-              };
-              for (var density in densities) {
-                parseIcon(icon, size, densities[density], density);
-              }
-            }
-          }
-
-          var copyIcon = function(density) {
-            var srcfilepath;
-            var destfilepath = path.join(this.path, 'res', 'drawable-'+density, 'icon.png');
-            if (android_icons[density]) {
-              srcfilepath = path.join(projectRoot, android_icons[density].src);
-            } else {
-              if (default_icon) {
-                srcfilepath = path.join(projectRoot, default_icon.src);
-              } else {
-                if (max_density) {
-                  srcfilepath = path.join(projectRoot, android_icons[max_density].src);
-                } else {
-                  events.emit('verbose', 'no icon found matching Android typical densities');
-                }
-              }
-            }
-            if (srcfilepath) {
-                events.emit('verbose', 'Copying icon from ' + srcfilepath + ' to ' + destfilepath);
-                shell.cp('-f', srcfilepath, destfilepath);
-            }
-          }.bind(this);
-          for (var density in densities) {
-            copyIcon(density);
-          }
-
-        }
-
-        var manifest = xml.parseElementtreeSync(this.manifest);
-        // Update the version by changing the AndroidManifest android:versionName
-        var version = config.version();
-        var versionCode = config.android_versionCode() || default_versionCode(version);
-        manifest.getroot().attrib["android:versionName"] = version;
-        manifest.getroot().attrib["android:versionCode"] = versionCode;
-
-        // Update package name by changing the AndroidManifest id and moving the entry class around to the proper package directory
-        var pkg = config.packageName();
-        pkg = pkg.replace(/-/g, '_'); // Java packages cannot support dashes
-        var orig_pkg = manifest.getroot().attrib.package;
-        manifest.getroot().attrib.package = pkg;
-
-        var act = manifest.getroot().find('./application/activity');
-
-        // Set the orientation in the AndroidManifest
-        var orientationPref = this.findOrientationPreference(config);
-        if (orientationPref) {
-            switch (orientationPref) {
-                case 'default':
-                    delete act.attrib["android:screenOrientation"];
-                    break;
-                case 'portrait':
-                    act.attrib["android:screenOrientation"] = 'portrait';
-                    break;
-                case 'landscape':
-                    act.attrib["android:screenOrientation"] = 'landscape';
-            }
-        }
-
-        // Set android:launchMode in AndroidManifest
-        var androidLaunchModePref = this.findAndroidLaunchModePreference(config);
-        if (androidLaunchModePref) {
-            act.attrib["android:launchMode"] = androidLaunchModePref;
-        } else { // User has (explicitly) set an invalid value for AndroidLaunchMode preference
-            delete act.attrib["android:launchMode"]; // use Android default value (standard)
-        }
-
-        // Write out AndroidManifest.xml
-        fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
-
-        var orig_pkgDir = path.join(this.path, 'src', path.join.apply(null, orig_pkg.split('.')));
-        var java_files = fs.readdirSync(orig_pkgDir).filter(function(f) {
-          return f.indexOf('.svn') == -1 && f.indexOf('.java') >= 0 && fs.readFileSync(path.join(orig_pkgDir, f), 'utf-8').match(/extends\s+CordovaActivity/);
-        });
-        if (java_files.length == 0) {
-          throw new Error('No Java files found which extend CordovaActivity.');
-        } else if(java_files.length > 1) {
-          events.emit('log', 'Multiple candidate Java files (.java files which extend CordovaActivity) found. Guessing at the first one, ' + java_files[0]);
-        }
-
-        var orig_java_class = java_files[0];
-        var pkgDir = path.join(this.path, 'src', path.join.apply(null, pkg.split('.')));
-        shell.mkdir('-p', pkgDir);
-        var orig_javs = path.join(orig_pkgDir, orig_java_class);
-        var new_javs = path.join(pkgDir, orig_java_class);
-        var javs_contents = fs.readFileSync(orig_javs, 'utf-8');
-        javs_contents = javs_contents.replace(/package [\w\.]*;/, 'package ' + pkg + ';');
-        events.emit('verbose', 'Wrote out Android package name to "' + pkg + '"');
-        fs.writeFileSync(new_javs, javs_contents, 'utf-8');
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'assets', 'www');
-    },
-
-    config_xml:function(){
-        return this.android_config;
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'framework', 'assets', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'android');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var platformWww = path.join(this.path, 'assets');
-        try {
-            this.update_from_config(cfg);
-            this.update_overrides();
-        } catch(e) {
-            return Q.reject(e);
-        }
-        // delete any .svn folders copied over
-        util.deleteSvnFolders(platformWww);
-        return Q();
-    }
-};
-
-
-// Consturct the default value for versionCode as
-// PATCH + MINOR * 100 + MAJOR * 10000
-// see http://developer.android.com/tools/publishing/versioning.html
-function default_versionCode(version) {
-    nums = version.split('-')[0].split('.').map(Number);
-    var versionCode = nums[0] * 10000 + nums[1] * 100 + nums[2];
-    return versionCode;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/blackberry10_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/blackberry10_parser.js b/src/metadata/blackberry10_parser.js
deleted file mode 100644
index ba6530f..0000000
--- a/src/metadata/blackberry10_parser.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    shell         = require('shelljs'),
-    util          = require('../util'),
-    Q             = require('q'),
-    child_process = require('child_process'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    events        = require('../events'),
-    config        = require('../config');
-
-module.exports = function blackberry_parser(project) {
-    if (!fs.existsSync(path.join(project, 'www'))) {
-        throw new CordovaError('The provided path "' + project + '" is not a Cordova BlackBerry10 project.');
-    }
-    this.path = project;
-    this.config_path = path.join(this.path, 'www', 'config.xml');
-    this.xml = new ConfigParser(this.config_path);
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    var custom_path = config.has_custom_path(project_root, 'blackberry10');
-    var lib_path;
-    if (custom_path) {
-        lib_path = path.resolve(custom_path);
-    } else {
-        lib_path = path.join(util.libDirectory, 'blackberry10', 'cordova', require('../../platforms').blackberry10.version);
-    }
-    var d = Q.defer();
-    child_process.exec("\"" + path.join(lib_path, 'bin', 'check_reqs') + "\"", function(err, output, stderr) {
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-    update_from_config:function(config) {
-        var projectRoot = util.isCordova(this.path),
-            resDir = path.join(this.path, 'platform_www', 'res'),
-            icons,
-            i;
-
-        if (!config instanceof ConfigParser) {
-            throw new Error('update_from_config requires a ConfigParser object');
-        }
-
-        shell.rm('-rf', resDir);
-        shell.mkdir(resDir);
-
-        icons = config.getIcons('blackberry10');
-        if (icons) {
-            for (i = 0; i < icons.length; i++) {
-                var src = path.join(projectRoot, icons[i].src),
-                    dest = path.join(this.path, 'platform_www', icons[i].src),
-                    destFolder = path.join(dest, '..');
-
-                if (!fs.existsSync(destFolder)) {
-                    shell.mkdir(destFolder); // make sure target dir exists
-                }
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var self = this;
-
-        try {
-            self.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-        self.update_overrides();
-        util.deleteSvnFolders(this.www_dir());
-        return Q();
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'www');
-    },
-
-    config_xml:function(){
-        return this.config_path;
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'javascript', 'cordova.blackberry10.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-        var platform_cfg_backup = new ConfigParser(this.config_path);
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-        //Re-Write config.xml
-        platform_cfg_backup.write();
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'blackberry10');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/firefoxos_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/firefoxos_parser.js b/src/metadata/firefoxos_parser.js
deleted file mode 100644
index 351a409..0000000
--- a/src/metadata/firefoxos_parser.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs = require('fs'),
-    path = require('path'),
-    shell = require('shelljs'),
-    util = require('../util'),
-    events = require('../events'),
-    Q = require('q'),
-    ConfigParser = require('../ConfigParser');
-
-module.exports = function firefoxos_parser(project) {
-    this.path = project;
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    return Q(); // Requirements always met.
-};
-
-module.exports.prototype = {
-    // Returns a promise.
-    update_from_config: function() {
-        var config = new ConfigParser(this.config_xml());
-        var manifestPath = path.join(this.www_dir(), 'manifest.webapp');
-        var manifest;
-
-        if(fs.existsSync(manifestPath)) {
-            manifest = JSON.parse(fs.readFileSync(manifestPath));
-        }
-        else {
-            manifest = {
-                launch_path: "/index.html",
-                installs_allowed_from: ["*"]
-            };
-        }
-
-        manifest.version = config.version();
-        manifest.name = config.name();
-        manifest.pkgName = config.packageName();
-        manifest.description = config.description();
-        manifest.developer = {
-            name: config.author()
-        };
-
-        var authorNode = config.doc.find('author');
-        var authorUrl = authorNode.attrib['href'];
-
-        if (authorUrl) {
-            manifest.developer.url = authorUrl;
-        }
-
-        var permissionNodes = config.doc.findall('permission');
-        var privileged = false;
-
-        if (permissionNodes.length) {
-            manifest.permissions = manifest.permissions || {};
-
-            permissionNodes.forEach(function(node) {
-                var permissionName = node.attrib['name'];
-
-                // Don't change if it was already created
-                if (!manifest.permissions[permissionName]) {
-                    manifest.permissions[permissionName] = {
-                        description: node.attrib['description']
-                    };
-
-                    if (node.attrib['access']) {
-                        manifest.permissions[permissionName].access = node.attrib['access'];
-                    }
-
-                    if (node.attrib['privileged'] === "true") {
-                        privileged = true;
-                    }
-                }
-            });
-        }
-
-        if (privileged) {
-            manifest.type = 'privileged';
-        } else {
-            delete manifest.type;
-        }
-
-        fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 4));
-
-        return Q();
-    },
-
-    www_dir: function() {
-        return path.join(this.path, 'www');
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'cordova-lib', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    update_overrides: function() {
-        var projectRoot = util.isCordova(this.path);
-        var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'firefoxos');
-        if(fs.existsSync(mergesPath)) {
-            var overrides = path.join(mergesPath, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    config_xml:function(){
-        return path.join(this.path, 'config.xml');
-    },
-
-    // Returns a promise.
-    update_project: function(cfg) {
-        return this.update_from_config()
-            .then(function(){
-                this.update_overrides();
-                util.deleteSvnFolders(this.www_dir());
-            }.bind(this));
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/ios_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/ios_parser.js b/src/metadata/ios_parser.js
deleted file mode 100644
index f906ee3..0000000
--- a/src/metadata/ios_parser.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var fs            = require('fs'),
-    path          = require('path'),
-    xcode         = require('xcode'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    plist         = require('plist-with-patches'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    config        = require('../config');
-
-module.exports = function ios_parser(project) {
-    try {
-        var xcodeproj_dir = fs.readdirSync(project).filter(function(e) { return e.match(/\.xcodeproj$/i); })[0];
-        if (!xcodeproj_dir) throw new CordovaError('The provided path "' + project + '" is not a Cordova iOS project.');
-        this.xcodeproj = path.join(project, xcodeproj_dir);
-        this.originalName = this.xcodeproj.substring(this.xcodeproj.lastIndexOf(path.sep)+1, this.xcodeproj.indexOf('.xcodeproj'));
-        this.cordovaproj = path.join(project, this.originalName);
-    } catch(e) {
-        throw new CordovaError('The provided path "'+project+'" is not a Cordova iOS project.');
-    }
-    this.path = project;
-    this.pbxproj = path.join(this.xcodeproj, 'project.pbxproj');
-    this.config_path = path.join(this.cordovaproj, 'config.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    // Rely on platform's bin/create script to check requirements.
-    return Q(true);
-};
-
-module.exports.prototype = {
-    // Returns a promise.
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else {
-            return Q.reject(new Error('update_from_config requires a ConfigParser object'));
-        }
-        var name = config.name();
-        var pkg = config.packageName();
-        var version = config.version();
-
-        // Update package id (bundle id)
-        var plistFile = path.join(this.cordovaproj, this.originalName + '-Info.plist');
-        var infoPlist = plist.parseFileSync(plistFile);
-        infoPlist['CFBundleIdentifier'] = pkg;
-
-        // Update version (bundle version)
-        infoPlist['CFBundleShortVersionString'] = version;
-        var CFBundleVersion = config.ios_CFBundleVersion() || default_CFBundleVersion(version);
-        infoPlist['CFBundleVersion'] = CFBundleVersion;
-
-        var info_contents = plist.build(infoPlist);
-        info_contents = info_contents.replace(/<string>[\s\r\n]*<\/string>/g,'<string></string>');
-        fs.writeFileSync(plistFile, info_contents, 'utf-8');
-        events.emit('verbose', 'Wrote out iOS Bundle Identifier to "' + pkg + '"');
-        events.emit('verbose', 'Wrote out iOS Bundle Version to "' + version + '"');
-
-        // Update icons
-        var icons = config.getIcons('ios');
-        var platformRoot = this.cordovaproj;
-        var appRoot = util.isCordova(platformRoot);
-
-        var platformIcons = [
-            {dest: "icon-60.png", width: 60, height: 60},
-            {dest: "icon-60@2x.png", width: 120, height: 120},
-            {dest: "icon-76.png", width: 76, height: 76},
-            {dest: "icon-76@2x.png", width: 152, height: 152},
-            {dest: "icon-small.png", width: 29, height: 29},
-            {dest: "icon-small@2x.png", width: 58, height: 58},
-            {dest: "icon-40.png", width: 40, height: 40},
-            {dest: "icon-40@2x.png", width: 80, height: 80},
-            {dest: "icon.png", width: 57, height: 57},
-            {dest: "icon@2x.png", width: 114, height: 114},
-            {dest: "icon-72.png", width: 72, height: 72},
-            {dest: "icon-72@2x.png", width: 144, height: 144},
-            {dest: "icon-50.png", width: 50, height: 50},
-            {dest: "icon-50@2x.png", width: 100, height: 100}
-        ];
-
-        platformIcons.forEach(function (item) {
-            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
-            if (icon){
-                var src = path.join(appRoot, icon.src),
-                    dest = path.join(platformRoot, 'Resources/icons/', item.dest);
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        });
-
-        if (name != this.originalName) {
-            // Update product name inside pbxproj file
-            var proj = new xcode.project(this.pbxproj);
-            var parser = this;
-            var d = Q.defer();
-            proj.parse(function(err,hash) {
-                if (err) {
-                    d.reject(new Error('An error occured during parsing of project.pbxproj. Start weeping. Output: ' + err));
-                } else {
-                    proj.updateProductName(name);
-                    fs.writeFileSync(parser.pbxproj, proj.writeSync(), 'utf-8');
-                    // Move the xcodeproj and other name-based dirs over.
-                    shell.mv(path.join(parser.cordovaproj, parser.originalName + '-Info.plist'), path.join(parser.cordovaproj, name + '-Info.plist'));
-                    shell.mv(path.join(parser.cordovaproj, parser.originalName + '-Prefix.pch'), path.join(parser.cordovaproj, name + '-Prefix.pch'));
-                    shell.mv(parser.xcodeproj, path.join(parser.path, name + '.xcodeproj'));
-                    shell.mv(parser.cordovaproj, path.join(parser.path, name));
-                    // Update self object with new paths
-                    var old_name = parser.originalName;
-                    parser = new module.exports(parser.path);
-                    // Hack this shi*t
-                    var pbx_contents = fs.readFileSync(parser.pbxproj, 'utf-8');
-                    pbx_contents = pbx_contents.split(old_name).join(name);
-                    fs.writeFileSync(parser.pbxproj, pbx_contents, 'utf-8');
-                    events.emit('verbose', 'Wrote out iOS Product Name and updated XCode project file names from "'+old_name+'" to "' + name + '".');
-                    d.resolve();
-                }
-            });
-            return d.promise;
-        } else {
-            events.emit('verbose', 'iOS Product Name has not changed (still "' + this.originalName + '")');
-            return Q();
-        }
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'www');
-    },
-
-    config_xml:function(){
-        return this.config_path;
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'CordovaLib', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'ios');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var self = this;
-        return this.update_from_config(cfg)
-        .then(function() {
-            self.update_overrides();
-            util.deleteSvnFolders(self.www_dir());
-        });
-    }
-};
-
-
-// Construct a default value for CFBundleVersion as the version with any
-// -rclabel stripped=.
-function default_CFBundleVersion(version) {
-    return version.split('-')[0];
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/ubuntu_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/ubuntu_parser.js b/src/metadata/ubuntu_parser.js
deleted file mode 100644
index 947fb1e..0000000
--- a/src/metadata/ubuntu_parser.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- *
- * Copyright 2013 Canonical Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    project_config= require('../config'),
-    Q             = require('q'),
-    os            = require('os'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError');
-
-module.exports = function(project) {
-    this.path = project;
-    this.config = new ConfigParser(this.config_xml());
-    this.update_manifest();
-};
-
-function sanitize(str) {
-    return str.replace(/\n/g, ' ').replace(/^\s+|\s+$/g, '');
-}
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root, callback) {
-    var d = Q.defer();
-
-    events.emit('log', 'Checking ubuntu requirements...');
-    command = "dpkg-query -Wf'${db:Status-abbrev}' cmake debhelper libx11-dev libicu-dev pkg-config qtbase5-dev qtchooser qtdeclarative5-dev qtfeedback5-dev qtlocation5-dev qtmultimedia5-dev qtpim5-dev qtsensors5-dev qtsystems5-dev 2>/dev/null | grep -q '^i'";
-    events.emit('log', 'Running "' + command + '" (output to follow)');
-    shell.exec(command, {silent:true, async:true}, function(code, output) {
-        events.emit('log', output);
-        if (code != 0) {
-            d.reject(new CordovaError('Make sure you have the following packages installed: ' + output));
-        } else {
-            d.resolve();
-        }
-    });
-
-    return d.promise;
-};
-
-module.exports.prototype = {
-    // Returns a promise.
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else {
-            return Q.reject(new Error('update_from_config requires a ConfigParser object'));
-        }
-
-        this.config = new ConfigParser(this.config_xml());
-        this.config.setName(config.name());
-        this.config.setVersion(config.version());
-        this.config.setPackageName(config.packageName());
-        this.config.setDescription(config.description());
-
-        this.config.write();
-
-        return this.update_manifest();
-    },
-
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    update_manifest: function() {
-        var nodearch2debarch = { 'arm': 'armhf',
-                                 'ia32': 'i386',
-                                 'x64': 'amd64'};
-        var arch;
-        if (os.arch() in nodearch2debarch)
-            arch = nodearch2debarch[os.arch()];
-        else
-            return Q.reject(new Error('unknown cpu arch'));
-
-        if (!this.config.author())
-            return Q.reject(new Error('config.xml should contain author'));
-
-        var manifest = { name: this.config.packageName(),
-                         version: this.config.version(),
-                         title: this.config.name(),
-                         hooks: { cordova: { desktop: "cordova.desktop",
-                                             apparmor: "apparmor.json" } },
-                         framework: "ubuntu-sdk-13.10",
-                         maintainer: sanitize(this.config.author()),
-                         architecture: arch,
-                         description: sanitize(this.config.description()) };
-        fs.writeFileSync(path.join(this.path, 'manifest.json'), JSON.stringify(manifest));
-
-        var name = this.config.name().replace(/\n/g, ' '); //FIXME: escaping
-        var content = "[Desktop Entry]\nName=" + name + "\nExec=./cordova-ubuntu www/\nIcon=qmlscene\nTerminal=false\nType=Application\nX-Ubuntu-Touch=true";
-
-        fs.writeFileSync(path.join(this.path, 'cordova.desktop'), content);
-
-        var policy = { policy_groups: ["networking", "audio"], policy_version: 1 };
-
-        this.config.doc.getroot().findall('./feature/param').forEach(function (element) {
-            if (element.attrib.policy_group && policy.policy_groups.indexOf(policy.policy_groups) === -1)
-                policy.policy_groups.push(element.attrib.policy_group);
-        });
-
-        fs.writeFileSync(path.join(this.path, 'apparmor.json'), JSON.stringify(policy));
-
-        return Q();
-    },
-
-    config_xml:function(){
-        return path.join(this.path, 'config.xml');
-    },
-
-    www_dir:function() {
-        return path.join(this.path, 'www');
-    },
-
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var www = util.projectWww(projectRoot);
-
-        shell.rm('-rf', this.www_dir());
-        shell.cp('-rf', www, this.path);
-    },
-
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'ubuntu');
-        if(fs.existsSync(mergesPath)) {
-            var overrides = path.join(mergesPath, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var self = this;
-
-        return this.update_from_config(cfg)
-        .then(function() {
-            self.update_overrides();
-            util.deleteSvnFolders(self.www_dir());
-        });
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/windows8_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/windows8_parser.js b/src/metadata/windows8_parser.js
deleted file mode 100644
index 53c2d31..0000000
--- a/src/metadata/windows8_parser.js
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    events        = require('../events'),
-    Q             = require('q'),
-    child_process = require('child_process'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    xml           = require('../xml-helpers'),
-    config        = require('../config'),
-    hooker        = require('../hooker');
-
-module.exports = function windows8_parser(project) {
-    try {
-        // TODO : Check that it's not a windows8 project?
-        var jsproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.jsproj$/i); })[0];
-        if (!jsproj_file) throw new CordovaError('No .jsproj file in "'+project+'"');
-        this.windows8_proj_dir = project;
-        this.jsproj_path  = path.join(this.windows8_proj_dir, jsproj_file);
-        this.sln_path     = path.join(this.windows8_proj_dir, jsproj_file.replace(/\.jsproj/, '.sln'));
-    } catch(e) {
-        throw new CordovaError('The provided path "' + project + '" is not a Windows 8 project. ' + e);
-    }
-    this.manifest_path  = path.join(this.windows8_proj_dir, 'package.appxmanifest');
-};
-
-// Returns a promise
-module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking windows8 requirements...');
-    var lib_path = path.join(util.libDirectory, 'windows8', 'cordova',
-                    require('../../platforms').windows8.version, 'windows8');
-
-    var custom_path = config.has_custom_path(project_root, 'windows8');
-    if (custom_path) {
-        lib_path = path.join(custom_path, "windows8");
-    }
-    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output);
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-
-    update_from_config:function(config) {
-
-        //check config parser
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        //Get manifest file
-        var manifest = xml.parseElementtreeSync(this.manifest_path);
-
-        var version = this.fixConfigVersion(config.version());
-        var name = config.name();
-        var pkgName = config.packageName();
-        var author = config.author();
-
-        var identityNode = manifest.find('.//Identity');
-        if(identityNode) {
-            // Update app name in identity
-            var appIdName = identityNode['attrib']['Name'];
-            if (appIdName != pkgName) {
-                identityNode['attrib']['Name'] = pkgName;
-            }
-
-            // Update app version
-            var appVersion = identityNode['attrib']['Version'];
-            if(appVersion != version) {
-                identityNode['attrib']['Version'] = version;
-            }
-        }
-
-        // Update name (windows8 has it in the Application[@Id] and Application.VisualElements[@DisplayName])
-        var app = manifest.find('.//Application');
-        if(app) {
-
-            var appId = app['attrib']['Id'];
-
-            if (appId != pkgName) {
-                app['attrib']['Id'] = pkgName;
-            }
-
-            var visualElems = manifest.find('.//VisualElements') || manifest.find('.//m2:VisualElements');
-
-            if(visualElems) {
-                var displayName = visualElems['attrib']['DisplayName'];
-                if(displayName != name) {
-                    visualElems['attrib']['DisplayName'] = name;
-                }
-            }
-            else {
-                throw new Error('update_from_config expected a valid package.appxmanifest' +
-                                ' with a <VisualElements> node');
-            }
-        }
-        else {
-            throw new Error('update_from_config expected a valid package.appxmanifest' +
-                            ' with a <Application> node');
-        }
-
-        // Update properties
-        var properties = manifest.find('.//Properties');
-        if (properties && properties.find) {
-            var displayNameElement = properties.find('.//DisplayName');
-            if (displayNameElement && displayNameElement.text != name) {
-                displayNameElement.text = name;
-            }
-
-            var publisherNameElement = properties.find('.//PublisherDisplayName');
-            if (publisherNameElement && publisherNameElement.text != author) {
-                publisherNameElement.text = author;
-            }
-        }
-
-        // sort Capability elements as per CB-5350 Windows8 build fails due to invalid 'Capabilities' definition
-        // to sort elements we remove them and then add again in the appropriate order
-        var capabilitiesRoot = manifest.find('.//Capabilities'),
-            capabilities = capabilitiesRoot._children || [];
-
-        capabilities.forEach(function(elem){
-            capabilitiesRoot.remove(0, elem);
-        });
-        capabilities.sort(function(a, b) {
-            return (a.tag > b.tag)? 1: -1;
-        });
-        capabilities.forEach(function(elem){
-            capabilitiesRoot.append(elem);
-        });
-
-        //Write out manifest
-        fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
-
-        // Update icons
-        var icons = config.getIcons('windows8');
-        var platformRoot = this.windows8_proj_dir;
-        var appRoot = util.isCordova(platformRoot);
-
-        // Icons, that should be added to platform
-        var platformIcons = [
-            {dest: "images/logo.png", width: 150, height: 150},
-            {dest: "images/smalllogo.png", width: 30, height: 30},
-            {dest: "images/storelogo.png", width: 50, height: 50},
-        ];
-
-        platformIcons.forEach(function (item) {
-            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
-            if (icon){
-                var src = path.join(appRoot, icon.src),
-                    dest = path.join(platformRoot, item.dest);
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        });
-
-    },
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.windows8_proj_dir, 'www');
-    },
-    config_xml:function() {
-        return path.join(this.windows8_proj_dir,"config.xml");
-    },
-    // copy files from merges directory to actual www dir
-    copy_merges:function(merges_sub_path) {
-        var merges_path = path.join(util.appDir(util.isCordova(this.windows8_proj_dir)), 'merges', merges_sub_path);
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, "template", 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.windows8_proj_dir);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.windows8_proj_dir, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-
-        // Copy all files from merges directory.
-        this.copy_merges('windows8');
-
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // updates the jsproj file to explicitly list all www content.
-    update_jsproj:function() {
-        var jsproj_xml = xml.parseElementtreeSync(this.jsproj_path);
-        // remove any previous references to the www files
-        var item_groups = jsproj_xml.findall('ItemGroup');
-        for (var i = 0, l = item_groups.length; i < l; i++) {
-            var group = item_groups[i];
-            var files = group.findall('Content');
-            for (var j = 0, k = files.length; j < k; j++) {
-                var file = files[j];
-                if (file.attrib.Include.substr(0, 3) == 'www') {
-                    // remove file reference
-                    group.remove(0, file);
-                    // remove ItemGroup if empty
-                    var new_group = group.findall('Content');
-                    if(new_group.length < 1) {
-                        jsproj_xml.getroot().remove(0, group);
-                    }
-                }
-            }
-        }
-
-        // now add all www references back in from the root www folder
-        var project_root = util.isCordova(this.windows8_proj_dir);
-        var www_files = this.folder_contents('www', this.www_dir());
-        for(file in www_files) {
-            var item = new et.Element('ItemGroup');
-            var content = new et.Element('Content');
-            content.attrib.Include = www_files[file];
-            item.append(content);
-            jsproj_xml.getroot().append(item);
-        }
-        // save file
-        fs.writeFileSync(this.jsproj_path, jsproj_xml.write({indent:4}), 'utf-8');
-    },
-    // Returns an array of all the files in the given directory with relative paths
-    // - name     : the name of the top level directory (i.e all files will start with this in their path)
-    // - dir     : the directory whos contents will be listed under 'name' directory
-    folder_contents:function(name, dir) {
-        var results = [];
-        var folder_dir = fs.readdirSync(dir);
-        for(item in folder_dir) {
-            var stat = fs.statSync(path.join(dir, folder_dir[item]));
-
-            if(stat.isDirectory()) {
-                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
-                //Add all subfolder item paths
-                for(sub_item in sub_dir) {
-                    results.push(sub_dir[sub_item]);
-                }
-            }
-            else if(stat.isFile()) {
-                results.push(path.join(name, folder_dir[item]));
-            }
-            // else { it is a FIFO, or a Socket, Symbolic Link or something ... }
-        }
-        return results;
-    },
-
-    // calls the nessesary functions to update the windows8 project
-    update_project:function(cfg) {
-        //console.log("Updating windows8 project...");
-
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-
-        var that = this;
-        var projectRoot = util.isCordova(process.cwd());
-
-        var hooks = new hooker(projectRoot);
-        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['windows8'] })
-        .then(function() {
-            // overrides (merges) are handled in update_www()
-            that.update_jsproj();
-            that.add_bom();
-            util.deleteSvnFolders(that.www_dir());
-        });
-    },
-
-    // Adjust version number as per CB-5337 Windows8 build fails due to invalid app version
-    fixConfigVersion: function (version) {
-        if(version && version.match(/\.\d/g)) {
-            var numVersionComponents = version.match(/\.\d/g).length + 1;
-            while (numVersionComponents++ < 4) {
-                version += '.0';
-            }
-        }
-        return version;
-    },
-
-    // CB-5421 Add BOM to all html, js, css files to ensure app can pass Windows Store Certification
-    add_bom: function () {
-        var www = this.www_dir();
-        var files = shell.ls('-R', www);
-
-        files.forEach(function (file) {
-            if (!file.match(/\.(js|html|css|json)/)) {
-                return;
-            }
-
-            var filePath = path.join(www, file);
-            var content = fs.readFileSync(filePath);
-
-            if (content[0] !== 0xEF && content[1] !== 0xBE && content[2] !== 0xBB) {
-                fs.writeFileSync(filePath, '\ufeff' + content);
-            }
-        });
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/metadata/wp7_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/wp7_parser.js b/src/metadata/wp7_parser.js
deleted file mode 100644
index 91db24c..0000000
--- a/src/metadata/wp7_parser.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    child_process = require('child_process'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    config        = require('../config'),
-    hooker        = require('../hooker');
-
-module.exports = function wp7_parser(project) {
-    try {
-        // TODO : Check that it's not a wp7 project?
-        var csproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
-        if (!csproj_file) throw new CordovaError('No .csproj file in "'+project+'"');
-        this.wp7_proj_dir = project;
-        this.csproj_path  = path.join(this.wp7_proj_dir, csproj_file);
-        this.sln_path     = path.join(this.wp7_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
-    } catch(e) {
-        throw new CordovaError('The provided path "' + project + '" is not a Windows Phone 7 project. ' + e);
-    }
-    this.manifest_path  = path.join(this.wp7_proj_dir, 'Properties', 'WMAppManifest.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking wp7 requirements...');
-    var lib_path = path.join(util.libDirectory, 'wp', 'cordova', require('../../platforms').wp7.version, 'wp7');
-    var custom_path = config.has_custom_path(project_root, 'wp7');
-    if (custom_path) {
-        lib_path = path.join(custom_path, 'wp7');
-    }
-    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output+stderr);
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-    update_from_config:function(config) {
-        //check config parser
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        //Get manifest file
-        var manifest = xml.parseElementtreeSync(this.manifest_path);
-
-        //Update app version
-        var version = config.version();
-        manifest.find('.//App').attrib.Version = version;
-
-        // Update app name by editing app title in Properties\WMAppManifest.xml
-        var name = config.name();
-        var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
-        if(prev_name != name) {
-            events.emit('verbose', "Updating app name from " + prev_name + " to " + name);
-            manifest.find('.//App').attrib.Title = name;
-            manifest.find('.//App').attrib.Publisher = name + " Publisher";
-            manifest.find('.//App').attrib.Author = name + " Author";
-            manifest.find('.//PrimaryToken').attrib.TokenID = name;
-            //update name of sln and csproj.
-            name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
-            prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
-            var sln_name = fs.readdirSync(this.wp7_proj_dir).filter(function(e) { return e.match(/\.sln$/i); })[0];
-            var sln_path = path.join(this.wp7_proj_dir, sln_name);
-            var sln_file = fs.readFileSync(sln_path, 'utf-8');
-            var name_regex = new RegExp(prev_name, "g");
-            fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
-            shell.mv('-f', this.csproj_path, path.join(this.wp7_proj_dir, name + '.csproj'));
-            this.csproj_path = path.join(this.wp7_proj_dir, name + '.csproj');
-            shell.mv('-f', sln_path, path.join(this.wp7_proj_dir, name + '.sln'));
-            this.sln_path    = path.join(this.wp7_proj_dir, name + '.sln');
-        }
-
-        // Update package name by changing:
-        /*  - CordovaAppProj.csproj
-         *  - MainPage.xaml
-         *  - MainPage.xaml.cs
-         *  - App.xaml
-         *  - App.xaml.cs
-         */
-         var pkg = config.packageName();
-         var csproj = xml.parseElementtreeSync(this.csproj_path);
-         prev_name = csproj.find('.//RootNamespace').text;
-         if(prev_name != pkg) {
-            events.emit('verbose', "Updating package name from " + prev_name + " to " + pkg);
-            //CordovaAppProj.csproj
-            csproj.find('.//RootNamespace').text = pkg;
-            csproj.find('.//AssemblyName').text = pkg;
-            csproj.find('.//XapFilename').text = pkg + '.xap';
-            csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
-            fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
-            //MainPage.xaml
-            var mainPageXAML = xml.parseElementtreeSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'));
-            mainPageXAML.getroot().attrib['x:Class'] = pkg + '.MainPage';
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
-            //MainPage.xaml.cs
-            var mainPageCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
-            var namespaceRegEx = new RegExp('namespace ' + prev_name);
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-            //App.xaml
-            var appXAML = xml.parseElementtreeSync(path.join(this.wp7_proj_dir, 'App.xaml'));
-            appXAML.getroot().attrib['x:Class'] = pkg + '.App';
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
-            //App.xaml.cs
-            var appCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), 'utf-8');
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-         }
-
-         //Write out manifest
-         fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
-    },
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.wp7_proj_dir, 'www');
-    },
-    config_xml:function() {
-        return path.join(this.wp7_proj_dir, 'config.xml');
-    },
-    // copy files from merges directory to actual www dir
-    copy_merges:function(merges_sub_path) {
-        var merges_path = path.join(util.appDir(util.isCordova(this.wp7_proj_dir)), 'merges', merges_sub_path);
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, '..', 'common', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.wp7_proj_dir);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.wp7_proj_dir, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-
-        // Copy all files from merges directories - wp generic first, then wp7 specific.
-        this.copy_merges('wp');
-        this.copy_merges('wp7');
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // updates the csproj file to explicitly list all www content.
-    update_csproj:function() {
-        var csproj_xml = xml.parseElementtreeSync(this.csproj_path);
-        // remove any previous references to the www files
-        var item_groups = csproj_xml.findall('ItemGroup');
-        for (var i = 0, l = item_groups.length; i < l; i++) {
-            var group = item_groups[i];
-            var files = group.findall('Content');
-            for (var j = 0, k = files.length; j < k; j++) {
-                var file = files[j];
-                if (file.attrib.Include.substr(0, 3) == 'www') {
-                    // remove file reference
-                    group.remove(0, file);
-                    // remove ItemGroup if empty
-                    var new_group = group.findall('Content');
-                    if(new_group.length < 1) {
-                        csproj_xml.getroot().remove(0, group);
-                    }
-                }
-            }
-        }
-
-        // now add all www references back in from the wp www folder
-        var www_files = this.folder_contents('www', this.www_dir());
-        for(file in www_files) {
-            var item = new et.Element('ItemGroup');
-            var content = new et.Element('Content');
-            content.attrib.Include = www_files[file];
-            item.append(content);
-            csproj_xml.getroot().append(item);
-        }
-        // save file
-        fs.writeFileSync(this.csproj_path, csproj_xml.write({indent:4}), 'utf-8');
-    },
-    // Returns an array of all the files in the given directory with relative paths
-    // - name     : the name of the top level directory (i.e all files will start with this in their path)
-    // - dir      : the directory whos contents will be listed under 'name' directory
-    folder_contents:function(name, dir) {
-        var results = [];
-        var folder_dir = fs.readdirSync(dir);
-        for(item in folder_dir) {
-            var stat = fs.statSync(path.join(dir, folder_dir[item]));
-
-            if(stat.isDirectory()) {
-                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
-                //Add all subfolder item paths
-                for(sub_item in sub_dir) {
-                    results.push(sub_dir[sub_item]);
-                }
-            }
-            else if(stat.isFile()) {
-                results.push(path.join(name, folder_dir[item]));
-            }
-            // else { it is a FIFO, or a Socket or something ... }
-        }
-        return results;
-    },
-
-    // calls the nessesary functions to update the wp7 project
-    // Returns a promise.
-    update_project:function(cfg) {
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-        // trigger an event in case anyone needs to modify the contents of the www folder before we package it.
-        var that = this;
-        var projectRoot = util.isCordova(process.cwd());
-        var hooks = new hooker(projectRoot);
-
-        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['wp7']  })
-        .then(function() {
-            that.update_csproj();
-            // TODO: Add overrides support? Why is this missing?
-            util.deleteSvnFolders(that.www_dir());
-        });
-    }
-};


[17/24] Remove all cordova-lib files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/info.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/info.js b/cordova-lib/src/cordova/info.js
deleted file mode 100644
index c8b8e24..0000000
--- a/cordova-lib/src/cordova/info.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-'License'); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
- */
-
-/*
-A utility funciton to help output the information needed
-when submitting a help request.
-Outputs to a file
- */
-var cordova_util = require('./util'),
-    superspawn   = require('./superspawn'),
-    package      = require('../package'),
-    path         = require('path'),
-    fs           = require('fs'),
-    Q            = require('q');
-
-// Execute using a child_process exec, for any async command
-function execSpawn(command, args, resultMsg, errorMsg) {
-    return superspawn.spawn(command, args).then(function(result) {
-        return resultMsg + result;
-    }, function(error) {
-        return errorMsg + error;
-    });
-}
-
-function getPlatformInfo(platform, projectRoot) {
-    switch (platform) {
-    case 'ios':
-        return execSpawn('xcodebuild', ['-version'], 'iOS platform:\n\n', 'Error retrieving iOS platform information: ');
-    case 'android':
-        return execSpawn('android', ['list', 'target'], 'Android platform:\n\n', 'Error retrieving Android platform information: ');
-    }
-}
-
-
-module.exports = function info() {
-    //Get projectRoot
-    var projectRoot = cordova_util.cdProjectRoot();
-    var output = '';
-    if (!projectRoot) {
-        return Q.reject(new Error('Current working directory is not a Cordova-based project.'));
-    }
-
-    //Array of functions, Q.allSettled
-    console.log('Collecting Data...\n\n');
-    return Q.allSettled([
-            //Get Node version
-            Q('Node version: ' + process.version),
-            //Get Cordova version
-            Q('Cordova version: ' + package.version),
-            //Get project config.xml file using ano
-            getProjectConfig(projectRoot),
-            //Get list of plugins
-            listPlugins(projectRoot),
-            //Get Platforms information
-            getPlatforms(projectRoot)
-        ]).then(function(promises) {
-        promises.forEach(function(p) {
-            output += p.state === 'fulfilled' ? p.value + '\n\n' : p.reason + '\n\n';
-        });
-        console.info(output);
-        fs.writeFile(path.join(projectRoot, 'info.txt'), output, 'utf-8', function (err) {
-            if (err)
-                throw err;
-        });
-    });
-};
-
-function getPlatforms(projectRoot) {
-    var platforms = cordova_util.listPlatforms(projectRoot);
-    if (platforms.length) {
-        return Q.all(platforms.map(function(p) {
-            return getPlatformInfo(p, projectRoot);
-        })).then(function(outs) {
-          return outs.join('\n\n');
-        });
-    }
-    return Q.reject('No Platforms Currently Installed');
-}
-
-function listPlugins(projectRoot) {
-    var pluginPath = path.join(projectRoot, 'plugins'),
-        plugins    = cordova_util.findPlugins(pluginPath);
-
-    if (!plugins.length) {
-        return Q.reject('No Plugins Currently Installed');
-    }
-    return Q('Plugins: \n\n' + plugins);
-}
-
-function getProjectConfig(projectRoot) {
-    if (!fs.existsSync(projectRoot)  ) {
-        return Q.reject('Config.xml file not found');
-    }
-    return Q('Config.xml file: \n\n' + (fs.readFileSync(cordova_util.projectConfig(projectRoot), 'utf-8')));
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/lazy_load.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/lazy_load.js b/cordova-lib/src/cordova/lazy_load.js
deleted file mode 100644
index bd6cf77..0000000
--- a/cordova-lib/src/cordova/lazy_load.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var path          = require('path'),
-    fs            = require('fs'),
-    shell         = require('shelljs'),
-    platforms     = require('../platforms'),
-    npmconf       = require('npmconf'),
-    events        = require('./events'),
-    request       = require('request'),
-    config        = require('./config'),
-    hooker        = require('./hooker'),
-    zlib          = require('zlib'),
-    tar           = require('tar'),
-    URL           = require('url'),
-    Q             = require('q'),
-    util          = require('./util');
-
-module.exports = {
-    // Returns a promise for the path to the lazy-loaded directory.
-    cordova:function lazy_load(platform) {
-        if (!(platform in platforms)) {
-            return Q.reject(new Error('Cordova library "' + platform + '" not recognized.'));
-        }
-
-        var url = platforms[platform].url + ';a=snapshot;h=' + platforms[platform].version + ';sf=tgz';
-        return module.exports.custom(url, 'cordova', platform, platforms[platform].version);
-    },
-    // Returns a promise for the path to the lazy-loaded directory.
-    custom:function(url, id, platform, version) {
-        var download_dir;
-        var tmp_dir;
-        var lib_dir;
-
-        // Return early for already-cached remote URL, or for local URLs.
-        var uri = URL.parse(url);
-        var isUri = uri.protocol && uri.protocol[1] != ':'; // second part of conditional is for awesome windows support. fuuu windows
-        if (isUri) {
-            download_dir = (platform == 'wp7' || platform == 'wp8' ? path.join(util.libDirectory, 'wp', id, version) :
-                                                                     path.join(util.libDirectory, platform, id, version));
-            lib_dir = platforms[platform] && platforms[platform].subdirectory && platform !== "blackberry10" ? path.join(download_dir, platforms[platform].subdirectory) : download_dir;
-            if (fs.existsSync(download_dir)) {
-                events.emit('verbose', id + ' library for "' + platform + '" already exists. No need to download. Continuing.');
-                return Q(lib_dir);
-            }
-        } else {
-            // Local path.
-            lib_dir = platforms[platform] && platforms[platform].subdirectory ? path.join(url, platforms[platform].subdirectory) : url;
-            return Q(lib_dir);
-        }
-        return hooker.fire('before_library_download', {
-            platform:platform,
-            url:url,
-            id:id,
-            version:version
-        }).then(function() {
-            var uri = URL.parse(url);
-            var d = Q.defer();
-            npmconf.load(function(err, conf) {
-                // Check if NPM proxy settings are set. If so, include them in the request() call.
-                var proxy;
-                if (uri.protocol == 'https:') {
-                    proxy = conf.get('https-proxy');
-                } else if (uri.protocol == 'http:') {
-                    proxy = conf.get('proxy');
-                }
-                var strictSSL = conf.get('strict-ssl');
-
-                // Create a tmp dir. Using /tmp is a problem because it's often on a different partition and sehll.mv()
-                // fails in this case with "EXDEV, cross-device link not permitted".
-                tmp_subidr = 'tmp_' + id + '_' + process.pid + '_' + (new Date).valueOf();
-                tmp_dir = path.join(util.libDirectory, 'tmp', tmp_subidr);
-                shell.rm('-rf', tmp_dir);
-                shell.mkdir('-p', tmp_dir);
-
-                var size = 0;
-                var request_options = {uri:url};
-                if (proxy) {
-                    request_options.proxy = proxy;
-                }
-                if (typeof strictSSL == 'boolean') {
-                    request_options.strictSSL = strictSSL;
-                }
-                events.emit('verbose', 'Requesting ' + JSON.stringify(request_options) + '...');
-                events.emit('log', 'Downloading ' + id + ' library for ' + platform + '...');
-                var req = request.get(request_options, function(err, res, body) {
-                    if (err) {
-                        shell.rm('-rf', tmp_dir);
-                        d.reject(err);
-                    } else if (res.statusCode != 200) {
-                        shell.rm('-rf', tmp_dir);
-                        d.reject(new Error('HTTP error ' + res.statusCode + ' retrieving version ' + version + ' of ' + id + ' for ' + platform));
-                    } else {
-                        size = body.length;
-                    }
-                });
-
-                req.pipe(zlib.createUnzip())
-                .pipe(tar.Extract({path:tmp_dir}))
-                .on('error', function(err) {
-                    shell.rm('-rf', tmp_dir);
-                    d.reject(err);
-                })
-                .on('end', function() {
-                    events.emit('verbose', 'Downloaded, unzipped and extracted ' + size + ' byte response.');
-                    events.emit('log', 'Download complete');
-                    var entries = fs.readdirSync(tmp_dir);
-                    var entry = path.join(tmp_dir, entries[0]);
-                    shell.mkdir('-p', download_dir);
-                    shell.mv('-f', path.join(entry, (platform=='blackberry10'?'blackberry10':''), '*'), download_dir);
-                    shell.rm('-rf', tmp_dir);
-                    d.resolve(hooker.fire('after_library_download', {
-                        platform:platform,
-                        url:url,
-                        id:id,
-                        version:version,
-                        path: lib_dir,
-                        size:size,
-                        symlink:false
-                    }));
-                });
-            });
-            return d.promise.then(function () { return lib_dir; });
-        });
-    },
-    // Returns a promise for the path to the lazy-loaded directory.
-    based_on_config:function(project_root, platform) {
-        var custom_path = config.has_custom_path(project_root, platform);
-        if (custom_path) {
-            var dot_file = config.read(project_root);
-            return module.exports.custom(dot_file.lib[platform].uri, dot_file.lib[platform].id, platform, dot_file.lib[platform].version);
-        } else {
-            return module.exports.cordova(platform);
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js b/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
deleted file mode 100644
index f119279..0000000
--- a/cordova-lib/src/cordova/metadata/amazon_fireos_parser.js
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    project_config= require('../config'),
-    Q             = require('q'),
-    ConfigParser = require('../ConfigParser'),
-    CordovaError = require('../CordovaError');
-
-var awv_interface='awv_interface.jar';
-
-var default_prefs = {
-    "useBrowserHistory":"true",
-    "exit-on-suspend":"false"
-};
-
-module.exports = function android_parser(project) {
-    if (!fs.existsSync(path.join(project, 'AndroidManifest.xml'))) {
-        throw new CordovaError('The provided path "' + project + '" is not an Android project.');
-    }
-    this.path = project;
-    this.strings = path.join(this.path, 'res', 'values', 'strings.xml');
-    this.manifest = path.join(this.path, 'AndroidManifest.xml');
-    this.android_config = path.join(this.path, 'res', 'xml', 'config.xml');
-};
-
-// Returns a promise.
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    // Rely on platform's bin/create script to check requirements.
-    return Q(true);
-};
-
-module.exports.prototype = {
-    findOrientationPreference: function(config) {
-        var ret = config.getPreference('orientation');
-        if (ret && ret != 'default' && ret != 'portrait' && ret != 'landscape') {
-            events.emit('warn', 'Unknown value for orientation preference: ' + ret);
-            ret = null;
-        }
-
-        return ret;
-    },
-
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        // Update app name by editing res/values/strings.xml
-        var name = config.name();
-        var strings = xml.parseElementtreeSync(this.strings);
-        strings.find('string[@name="app_name"]').text = name;
-        fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
-        events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
-
-        var manifest = xml.parseElementtreeSync(this.manifest);
-        // Update the version by changing the AndroidManifest android:versionName
-        var version = config.version();
-        manifest.getroot().attrib["android:versionName"] = version;
-
-        // Update package name by changing the AndroidManifest id and moving the entry class around to the proper package directory
-        var pkg = config.packageName();
-        pkg = pkg.replace(/-/g, '_'); // Java packages cannot support dashes
-        var orig_pkg = manifest.getroot().attrib.package;
-        manifest.getroot().attrib.package = pkg;
-
-         // Set the orientation in the AndroidManifest
-        var orientationPref = this.findOrientationPreference(config);
-        if (orientationPref) {
-            var act = manifest.getroot().find('./application/activity');
-            switch (orientationPref) {
-                case 'default':
-                    delete act.attrib["android:screenOrientation"];
-                    break;
-                case 'portrait':
-                    act.attrib["android:screenOrientation"] = 'userPortrait';
-                    break;
-                case 'landscape':
-                    act.attrib["android:screenOrientation"] = 'userLandscape';
-            }
-        }
-
-
-        // Write out AndroidManifest.xml
-        fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
-
-        var orig_pkgDir = path.join(this.path, 'src', path.join.apply(null, orig_pkg.split('.')));
-        var java_files = fs.readdirSync(orig_pkgDir).filter(function(f) {
-          return f.indexOf('.svn') == -1 && f.indexOf('.java') >= 0 && fs.readFileSync(path.join(orig_pkgDir, f), 'utf-8').match(/extends\s+CordovaActivity/);
-        });
-        if (java_files.length == 0) {
-          throw new Error('No Java files found which extend CordovaActivity.');
-        } else if(java_files.length > 1) {
-          events.emit('log', 'Multiple candidate Java files (.java files which extend CordovaActivity) found. Guessing at the first one, ' + java_files[0]);
-        }
-
-        var orig_java_class = java_files[0];
-        var pkgDir = path.join(this.path, 'src', path.join.apply(null, pkg.split('.')));
-        shell.mkdir('-p', pkgDir);
-        var orig_javs = path.join(orig_pkgDir, orig_java_class);
-        var new_javs = path.join(pkgDir, orig_java_class);
-        var javs_contents = fs.readFileSync(orig_javs, 'utf-8');
-        javs_contents = javs_contents.replace(/package [\w\.]*;/, 'package ' + pkg + ';');
-        events.emit('verbose', 'Wrote out Android package name to "' + pkg + '"');
-        fs.writeFileSync(new_javs, javs_contents, 'utf-8');
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'assets', 'www');
-    },
-
-    config_xml:function(){
-        return this.android_config;
-    },
-
-     // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'framework', 'assets', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'amazon-fireos');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var platformWww = path.join(this.path, 'assets');
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-        this.update_overrides();
-        // delete any .svn folders copied over
-        util.deleteSvnFolders(platformWww);
-        return Q();
-    }
-};
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/android_parser.js b/cordova-lib/src/cordova/metadata/android_parser.js
deleted file mode 100644
index ef50caf..0000000
--- a/cordova-lib/src/cordova/metadata/android_parser.js
+++ /dev/null
@@ -1,303 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    project_config= require('../config'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError');
-
-var default_prefs = {
-    "useBrowserHistory":"true",
-    "exit-on-suspend":"false"
-};
-
-module.exports = function android_parser(project) {
-    if (!fs.existsSync(path.join(project, 'AndroidManifest.xml'))) {
-        throw new CordovaError('The provided path "' + project + '" is not an Android project.');
-    }
-    this.path = project;
-    this.strings = path.join(this.path, 'res', 'values', 'strings.xml');
-    this.manifest = path.join(this.path, 'AndroidManifest.xml');
-    this.android_config = path.join(this.path, 'res', 'xml', 'config.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    // Rely on platform's bin/create script to check requirements.
-    return Q(true);
-};
-
-module.exports.prototype = {
-    findOrientationPreference: function(config) {
-        var ret = config.getPreference('orientation');
-        if (ret && ret != 'default' && ret != 'portrait' && ret != 'landscape') {
-            events.emit('warn', 'Unknown value for orientation preference: ' + ret);
-            ret = null;
-        }
-
-        return ret;
-    },
-
-    findAndroidLaunchModePreference: function(config) {
-        var ret = config.getPreference('AndroidLaunchMode');
-        var valid = ['standard', 'singleTop', 'singleTask', 'singleInstance'].indexOf(ret) !== -1;
-        if (ret && !valid) {
-            events.emit('warn', 'Unknown value for launchMode preference: ' + ret);
-            ret = null;
-        }
-
-        return ret;
-    },
-
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        // Update app name by editing res/values/strings.xml
-        var name = config.name();
-        var strings = xml.parseElementtreeSync(this.strings);
-        strings.find('string[@name="app_name"]').text = name;
-        fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8');
-        events.emit('verbose', 'Wrote out Android application name to "' + name + '"');
-
-        var icons = config.getIcons('android');
-        // if there are icon elements in config.xml
-        if (icons) {
-          var haveSeenDefaultIcon = false;
-          var iconCount = 0;
-          var android_icons = {};
-          var projectRoot = util.isCordova(this.path);
-          var default_icon;
-          var max_size;
-          var max_density;
-          // http://developer.android.com/design/style/iconography.html
-          var densities = {
-            "ldpi" : 36,
-            "mdpi" : 48,
-            "hdpi" : 72,
-            "xhdpi" : 96
-          };
-          for (var i=0; i<icons.length; i++) {
-            var icon = icons[i];
-            var destfilepath;
-            var size = icon.width;
-            if (!size) {
-              size = icon.height;
-            }
-            if (!size && !icon.density) {
-              if (default_icon) {
-                  events.emit('verbose', "more than one default icon: " + JSON.stringify(icon));
-              } else {
-                  default_icon = icon;
-              }
-            } else {
-              var parseIcon = function(icon, icon_size, size, density) {
-                // if density is explicitly defined, no need to calculate it from width/height
-                if (icon.density) {
-                    android_icons[icon.density] = icon;
-                    return;
-                }
-
-                var i = parseInt(icon_size);
-                if (size == parseInt(icon_size)) {
-                  var previous = android_icons[density];
-                  if (previous) {
-                    // already have that density. platform rules
-                    if (!previous.platform) {
-                      android_icons[density] = icon;
-                    } // else already have a platform icon of that density
-                  } else {
-                    android_icons[density] = icon;
-                  }
-                  android_icons[density] = icon;
-                  if (!max_size) {
-                    max_size = size;
-                    max_density = density;
-                  } else {
-                    if (max_size < size) {
-                      max_size = size
-                      max_density = density;
-                    }
-                  }
-                }
-              };
-              for (var density in densities) {
-                parseIcon(icon, size, densities[density], density);
-              }
-            }
-          }
-
-          var copyIcon = function(density) {
-            var srcfilepath;
-            var destfilepath = path.join(this.path, 'res', 'drawable-'+density, 'icon.png');
-            if (android_icons[density]) {
-              srcfilepath = path.join(projectRoot, android_icons[density].src);
-            } else {
-              if (default_icon) {
-                srcfilepath = path.join(projectRoot, default_icon.src);
-              } else {
-                if (max_density) {
-                  srcfilepath = path.join(projectRoot, android_icons[max_density].src);
-                } else {
-                  events.emit('verbose', 'no icon found matching Android typical densities');
-                }
-              }
-            }
-            if (srcfilepath) {
-                events.emit('verbose', 'Copying icon from ' + srcfilepath + ' to ' + destfilepath);
-                shell.cp('-f', srcfilepath, destfilepath);
-            }
-          }.bind(this);
-          for (var density in densities) {
-            copyIcon(density);
-          }
-
-        }
-
-        var manifest = xml.parseElementtreeSync(this.manifest);
-        // Update the version by changing the AndroidManifest android:versionName
-        var version = config.version();
-        var versionCode = config.android_versionCode() || default_versionCode(version);
-        manifest.getroot().attrib["android:versionName"] = version;
-        manifest.getroot().attrib["android:versionCode"] = versionCode;
-
-        // Update package name by changing the AndroidManifest id and moving the entry class around to the proper package directory
-        var pkg = config.packageName();
-        pkg = pkg.replace(/-/g, '_'); // Java packages cannot support dashes
-        var orig_pkg = manifest.getroot().attrib.package;
-        manifest.getroot().attrib.package = pkg;
-
-        var act = manifest.getroot().find('./application/activity');
-
-        // Set the orientation in the AndroidManifest
-        var orientationPref = this.findOrientationPreference(config);
-        if (orientationPref) {
-            switch (orientationPref) {
-                case 'default':
-                    delete act.attrib["android:screenOrientation"];
-                    break;
-                case 'portrait':
-                    act.attrib["android:screenOrientation"] = 'portrait';
-                    break;
-                case 'landscape':
-                    act.attrib["android:screenOrientation"] = 'landscape';
-            }
-        }
-
-        // Set android:launchMode in AndroidManifest
-        var androidLaunchModePref = this.findAndroidLaunchModePreference(config);
-        if (androidLaunchModePref) {
-            act.attrib["android:launchMode"] = androidLaunchModePref;
-        } else { // User has (explicitly) set an invalid value for AndroidLaunchMode preference
-            delete act.attrib["android:launchMode"]; // use Android default value (standard)
-        }
-
-        // Write out AndroidManifest.xml
-        fs.writeFileSync(this.manifest, manifest.write({indent: 4}), 'utf-8');
-
-        var orig_pkgDir = path.join(this.path, 'src', path.join.apply(null, orig_pkg.split('.')));
-        var java_files = fs.readdirSync(orig_pkgDir).filter(function(f) {
-          return f.indexOf('.svn') == -1 && f.indexOf('.java') >= 0 && fs.readFileSync(path.join(orig_pkgDir, f), 'utf-8').match(/extends\s+CordovaActivity/);
-        });
-        if (java_files.length == 0) {
-          throw new Error('No Java files found which extend CordovaActivity.');
-        } else if(java_files.length > 1) {
-          events.emit('log', 'Multiple candidate Java files (.java files which extend CordovaActivity) found. Guessing at the first one, ' + java_files[0]);
-        }
-
-        var orig_java_class = java_files[0];
-        var pkgDir = path.join(this.path, 'src', path.join.apply(null, pkg.split('.')));
-        shell.mkdir('-p', pkgDir);
-        var orig_javs = path.join(orig_pkgDir, orig_java_class);
-        var new_javs = path.join(pkgDir, orig_java_class);
-        var javs_contents = fs.readFileSync(orig_javs, 'utf-8');
-        javs_contents = javs_contents.replace(/package [\w\.]*;/, 'package ' + pkg + ';');
-        events.emit('verbose', 'Wrote out Android package name to "' + pkg + '"');
-        fs.writeFileSync(new_javs, javs_contents, 'utf-8');
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'assets', 'www');
-    },
-
-    config_xml:function(){
-        return this.android_config;
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'framework', 'assets', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'android');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var platformWww = path.join(this.path, 'assets');
-        try {
-            this.update_from_config(cfg);
-            this.update_overrides();
-        } catch(e) {
-            return Q.reject(e);
-        }
-        // delete any .svn folders copied over
-        util.deleteSvnFolders(platformWww);
-        return Q();
-    }
-};
-
-
-// Consturct the default value for versionCode as
-// PATCH + MINOR * 100 + MAJOR * 10000
-// see http://developer.android.com/tools/publishing/versioning.html
-function default_versionCode(version) {
-    nums = version.split('-')[0].split('.').map(Number);
-    var versionCode = nums[0] * 10000 + nums[1] * 100 + nums[2];
-    return versionCode;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/blackberry10_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/blackberry10_parser.js b/cordova-lib/src/cordova/metadata/blackberry10_parser.js
deleted file mode 100644
index ba6530f..0000000
--- a/cordova-lib/src/cordova/metadata/blackberry10_parser.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    shell         = require('shelljs'),
-    util          = require('../util'),
-    Q             = require('q'),
-    child_process = require('child_process'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    events        = require('../events'),
-    config        = require('../config');
-
-module.exports = function blackberry_parser(project) {
-    if (!fs.existsSync(path.join(project, 'www'))) {
-        throw new CordovaError('The provided path "' + project + '" is not a Cordova BlackBerry10 project.');
-    }
-    this.path = project;
-    this.config_path = path.join(this.path, 'www', 'config.xml');
-    this.xml = new ConfigParser(this.config_path);
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    var custom_path = config.has_custom_path(project_root, 'blackberry10');
-    var lib_path;
-    if (custom_path) {
-        lib_path = path.resolve(custom_path);
-    } else {
-        lib_path = path.join(util.libDirectory, 'blackberry10', 'cordova', require('../../platforms').blackberry10.version);
-    }
-    var d = Q.defer();
-    child_process.exec("\"" + path.join(lib_path, 'bin', 'check_reqs') + "\"", function(err, output, stderr) {
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-    update_from_config:function(config) {
-        var projectRoot = util.isCordova(this.path),
-            resDir = path.join(this.path, 'platform_www', 'res'),
-            icons,
-            i;
-
-        if (!config instanceof ConfigParser) {
-            throw new Error('update_from_config requires a ConfigParser object');
-        }
-
-        shell.rm('-rf', resDir);
-        shell.mkdir(resDir);
-
-        icons = config.getIcons('blackberry10');
-        if (icons) {
-            for (i = 0; i < icons.length; i++) {
-                var src = path.join(projectRoot, icons[i].src),
-                    dest = path.join(this.path, 'platform_www', icons[i].src),
-                    destFolder = path.join(dest, '..');
-
-                if (!fs.existsSync(destFolder)) {
-                    shell.mkdir(destFolder); // make sure target dir exists
-                }
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var self = this;
-
-        try {
-            self.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-        self.update_overrides();
-        util.deleteSvnFolders(this.www_dir());
-        return Q();
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'www');
-    },
-
-    config_xml:function(){
-        return this.config_path;
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'javascript', 'cordova.blackberry10.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-        var platform_cfg_backup = new ConfigParser(this.config_path);
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-        //Re-Write config.xml
-        platform_cfg_backup.write();
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'blackberry10');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/firefoxos_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/firefoxos_parser.js b/cordova-lib/src/cordova/metadata/firefoxos_parser.js
deleted file mode 100644
index 351a409..0000000
--- a/cordova-lib/src/cordova/metadata/firefoxos_parser.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs = require('fs'),
-    path = require('path'),
-    shell = require('shelljs'),
-    util = require('../util'),
-    events = require('../events'),
-    Q = require('q'),
-    ConfigParser = require('../ConfigParser');
-
-module.exports = function firefoxos_parser(project) {
-    this.path = project;
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    return Q(); // Requirements always met.
-};
-
-module.exports.prototype = {
-    // Returns a promise.
-    update_from_config: function() {
-        var config = new ConfigParser(this.config_xml());
-        var manifestPath = path.join(this.www_dir(), 'manifest.webapp');
-        var manifest;
-
-        if(fs.existsSync(manifestPath)) {
-            manifest = JSON.parse(fs.readFileSync(manifestPath));
-        }
-        else {
-            manifest = {
-                launch_path: "/index.html",
-                installs_allowed_from: ["*"]
-            };
-        }
-
-        manifest.version = config.version();
-        manifest.name = config.name();
-        manifest.pkgName = config.packageName();
-        manifest.description = config.description();
-        manifest.developer = {
-            name: config.author()
-        };
-
-        var authorNode = config.doc.find('author');
-        var authorUrl = authorNode.attrib['href'];
-
-        if (authorUrl) {
-            manifest.developer.url = authorUrl;
-        }
-
-        var permissionNodes = config.doc.findall('permission');
-        var privileged = false;
-
-        if (permissionNodes.length) {
-            manifest.permissions = manifest.permissions || {};
-
-            permissionNodes.forEach(function(node) {
-                var permissionName = node.attrib['name'];
-
-                // Don't change if it was already created
-                if (!manifest.permissions[permissionName]) {
-                    manifest.permissions[permissionName] = {
-                        description: node.attrib['description']
-                    };
-
-                    if (node.attrib['access']) {
-                        manifest.permissions[permissionName].access = node.attrib['access'];
-                    }
-
-                    if (node.attrib['privileged'] === "true") {
-                        privileged = true;
-                    }
-                }
-            });
-        }
-
-        if (privileged) {
-            manifest.type = 'privileged';
-        } else {
-            delete manifest.type;
-        }
-
-        fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 4));
-
-        return Q();
-    },
-
-    www_dir: function() {
-        return path.join(this.path, 'www');
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'cordova-lib', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    update_overrides: function() {
-        var projectRoot = util.isCordova(this.path);
-        var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'firefoxos');
-        if(fs.existsSync(mergesPath)) {
-            var overrides = path.join(mergesPath, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    config_xml:function(){
-        return path.join(this.path, 'config.xml');
-    },
-
-    // Returns a promise.
-    update_project: function(cfg) {
-        return this.update_from_config()
-            .then(function(){
-                this.update_overrides();
-                util.deleteSvnFolders(this.www_dir());
-            }.bind(this));
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/ios_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/ios_parser.js b/cordova-lib/src/cordova/metadata/ios_parser.js
deleted file mode 100644
index f906ee3..0000000
--- a/cordova-lib/src/cordova/metadata/ios_parser.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var fs            = require('fs'),
-    path          = require('path'),
-    xcode         = require('xcode'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    plist         = require('plist-with-patches'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    config        = require('../config');
-
-module.exports = function ios_parser(project) {
-    try {
-        var xcodeproj_dir = fs.readdirSync(project).filter(function(e) { return e.match(/\.xcodeproj$/i); })[0];
-        if (!xcodeproj_dir) throw new CordovaError('The provided path "' + project + '" is not a Cordova iOS project.');
-        this.xcodeproj = path.join(project, xcodeproj_dir);
-        this.originalName = this.xcodeproj.substring(this.xcodeproj.lastIndexOf(path.sep)+1, this.xcodeproj.indexOf('.xcodeproj'));
-        this.cordovaproj = path.join(project, this.originalName);
-    } catch(e) {
-        throw new CordovaError('The provided path "'+project+'" is not a Cordova iOS project.');
-    }
-    this.path = project;
-    this.pbxproj = path.join(this.xcodeproj, 'project.pbxproj');
-    this.config_path = path.join(this.cordovaproj, 'config.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    // Rely on platform's bin/create script to check requirements.
-    return Q(true);
-};
-
-module.exports.prototype = {
-    // Returns a promise.
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else {
-            return Q.reject(new Error('update_from_config requires a ConfigParser object'));
-        }
-        var name = config.name();
-        var pkg = config.packageName();
-        var version = config.version();
-
-        // Update package id (bundle id)
-        var plistFile = path.join(this.cordovaproj, this.originalName + '-Info.plist');
-        var infoPlist = plist.parseFileSync(plistFile);
-        infoPlist['CFBundleIdentifier'] = pkg;
-
-        // Update version (bundle version)
-        infoPlist['CFBundleShortVersionString'] = version;
-        var CFBundleVersion = config.ios_CFBundleVersion() || default_CFBundleVersion(version);
-        infoPlist['CFBundleVersion'] = CFBundleVersion;
-
-        var info_contents = plist.build(infoPlist);
-        info_contents = info_contents.replace(/<string>[\s\r\n]*<\/string>/g,'<string></string>');
-        fs.writeFileSync(plistFile, info_contents, 'utf-8');
-        events.emit('verbose', 'Wrote out iOS Bundle Identifier to "' + pkg + '"');
-        events.emit('verbose', 'Wrote out iOS Bundle Version to "' + version + '"');
-
-        // Update icons
-        var icons = config.getIcons('ios');
-        var platformRoot = this.cordovaproj;
-        var appRoot = util.isCordova(platformRoot);
-
-        var platformIcons = [
-            {dest: "icon-60.png", width: 60, height: 60},
-            {dest: "icon-60@2x.png", width: 120, height: 120},
-            {dest: "icon-76.png", width: 76, height: 76},
-            {dest: "icon-76@2x.png", width: 152, height: 152},
-            {dest: "icon-small.png", width: 29, height: 29},
-            {dest: "icon-small@2x.png", width: 58, height: 58},
-            {dest: "icon-40.png", width: 40, height: 40},
-            {dest: "icon-40@2x.png", width: 80, height: 80},
-            {dest: "icon.png", width: 57, height: 57},
-            {dest: "icon@2x.png", width: 114, height: 114},
-            {dest: "icon-72.png", width: 72, height: 72},
-            {dest: "icon-72@2x.png", width: 144, height: 144},
-            {dest: "icon-50.png", width: 50, height: 50},
-            {dest: "icon-50@2x.png", width: 100, height: 100}
-        ];
-
-        platformIcons.forEach(function (item) {
-            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
-            if (icon){
-                var src = path.join(appRoot, icon.src),
-                    dest = path.join(platformRoot, 'Resources/icons/', item.dest);
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        });
-
-        if (name != this.originalName) {
-            // Update product name inside pbxproj file
-            var proj = new xcode.project(this.pbxproj);
-            var parser = this;
-            var d = Q.defer();
-            proj.parse(function(err,hash) {
-                if (err) {
-                    d.reject(new Error('An error occured during parsing of project.pbxproj. Start weeping. Output: ' + err));
-                } else {
-                    proj.updateProductName(name);
-                    fs.writeFileSync(parser.pbxproj, proj.writeSync(), 'utf-8');
-                    // Move the xcodeproj and other name-based dirs over.
-                    shell.mv(path.join(parser.cordovaproj, parser.originalName + '-Info.plist'), path.join(parser.cordovaproj, name + '-Info.plist'));
-                    shell.mv(path.join(parser.cordovaproj, parser.originalName + '-Prefix.pch'), path.join(parser.cordovaproj, name + '-Prefix.pch'));
-                    shell.mv(parser.xcodeproj, path.join(parser.path, name + '.xcodeproj'));
-                    shell.mv(parser.cordovaproj, path.join(parser.path, name));
-                    // Update self object with new paths
-                    var old_name = parser.originalName;
-                    parser = new module.exports(parser.path);
-                    // Hack this shi*t
-                    var pbx_contents = fs.readFileSync(parser.pbxproj, 'utf-8');
-                    pbx_contents = pbx_contents.split(old_name).join(name);
-                    fs.writeFileSync(parser.pbxproj, pbx_contents, 'utf-8');
-                    events.emit('verbose', 'Wrote out iOS Product Name and updated XCode project file names from "'+old_name+'" to "' + name + '".');
-                    d.resolve();
-                }
-            });
-            return d.promise;
-        } else {
-            events.emit('verbose', 'iOS Product Name has not changed (still "' + this.originalName + '")');
-            return Q();
-        }
-    },
-
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.path, 'www');
-    },
-
-    config_xml:function(){
-        return this.config_path;
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'CordovaLib', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.path, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // update the overrides folder into the www folder
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var merges_path = path.join(util.appDir(projectRoot), 'merges', 'ios');
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var self = this;
-        return this.update_from_config(cfg)
-        .then(function() {
-            self.update_overrides();
-            util.deleteSvnFolders(self.www_dir());
-        });
-    }
-};
-
-
-// Construct a default value for CFBundleVersion as the version with any
-// -rclabel stripped=.
-function default_CFBundleVersion(version) {
-    return version.split('-')[0];
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/ubuntu_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/ubuntu_parser.js b/cordova-lib/src/cordova/metadata/ubuntu_parser.js
deleted file mode 100644
index 947fb1e..0000000
--- a/cordova-lib/src/cordova/metadata/ubuntu_parser.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- *
- * Copyright 2013 Canonical Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    project_config= require('../config'),
-    Q             = require('q'),
-    os            = require('os'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError');
-
-module.exports = function(project) {
-    this.path = project;
-    this.config = new ConfigParser(this.config_xml());
-    this.update_manifest();
-};
-
-function sanitize(str) {
-    return str.replace(/\n/g, ' ').replace(/^\s+|\s+$/g, '');
-}
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root, callback) {
-    var d = Q.defer();
-
-    events.emit('log', 'Checking ubuntu requirements...');
-    command = "dpkg-query -Wf'${db:Status-abbrev}' cmake debhelper libx11-dev libicu-dev pkg-config qtbase5-dev qtchooser qtdeclarative5-dev qtfeedback5-dev qtlocation5-dev qtmultimedia5-dev qtpim5-dev qtsensors5-dev qtsystems5-dev 2>/dev/null | grep -q '^i'";
-    events.emit('log', 'Running "' + command + '" (output to follow)');
-    shell.exec(command, {silent:true, async:true}, function(code, output) {
-        events.emit('log', output);
-        if (code != 0) {
-            d.reject(new CordovaError('Make sure you have the following packages installed: ' + output));
-        } else {
-            d.resolve();
-        }
-    });
-
-    return d.promise;
-};
-
-module.exports.prototype = {
-    // Returns a promise.
-    update_from_config:function(config) {
-        if (config instanceof ConfigParser) {
-        } else {
-            return Q.reject(new Error('update_from_config requires a ConfigParser object'));
-        }
-
-        this.config = new ConfigParser(this.config_xml());
-        this.config.setName(config.name());
-        this.config.setVersion(config.version());
-        this.config.setPackageName(config.packageName());
-        this.config.setDescription(config.description());
-
-        this.config.write();
-
-        return this.update_manifest();
-    },
-
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    update_manifest: function() {
-        var nodearch2debarch = { 'arm': 'armhf',
-                                 'ia32': 'i386',
-                                 'x64': 'amd64'};
-        var arch;
-        if (os.arch() in nodearch2debarch)
-            arch = nodearch2debarch[os.arch()];
-        else
-            return Q.reject(new Error('unknown cpu arch'));
-
-        if (!this.config.author())
-            return Q.reject(new Error('config.xml should contain author'));
-
-        var manifest = { name: this.config.packageName(),
-                         version: this.config.version(),
-                         title: this.config.name(),
-                         hooks: { cordova: { desktop: "cordova.desktop",
-                                             apparmor: "apparmor.json" } },
-                         framework: "ubuntu-sdk-13.10",
-                         maintainer: sanitize(this.config.author()),
-                         architecture: arch,
-                         description: sanitize(this.config.description()) };
-        fs.writeFileSync(path.join(this.path, 'manifest.json'), JSON.stringify(manifest));
-
-        var name = this.config.name().replace(/\n/g, ' '); //FIXME: escaping
-        var content = "[Desktop Entry]\nName=" + name + "\nExec=./cordova-ubuntu www/\nIcon=qmlscene\nTerminal=false\nType=Application\nX-Ubuntu-Touch=true";
-
-        fs.writeFileSync(path.join(this.path, 'cordova.desktop'), content);
-
-        var policy = { policy_groups: ["networking", "audio"], policy_version: 1 };
-
-        this.config.doc.getroot().findall('./feature/param').forEach(function (element) {
-            if (element.attrib.policy_group && policy.policy_groups.indexOf(policy.policy_groups) === -1)
-                policy.policy_groups.push(element.attrib.policy_group);
-        });
-
-        fs.writeFileSync(path.join(this.path, 'apparmor.json'), JSON.stringify(policy));
-
-        return Q();
-    },
-
-    config_xml:function(){
-        return path.join(this.path, 'config.xml');
-    },
-
-    www_dir:function() {
-        return path.join(this.path, 'www');
-    },
-
-    update_www:function() {
-        var projectRoot = util.isCordova(this.path);
-        var www = util.projectWww(projectRoot);
-
-        shell.rm('-rf', this.www_dir());
-        shell.cp('-rf', www, this.path);
-    },
-
-    update_overrides:function() {
-        var projectRoot = util.isCordova(this.path);
-        var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'ubuntu');
-        if(fs.existsSync(mergesPath)) {
-            var overrides = path.join(mergesPath, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Returns a promise.
-    update_project:function(cfg) {
-        var self = this;
-
-        return this.update_from_config(cfg)
-        .then(function() {
-            self.update_overrides();
-            util.deleteSvnFolders(self.www_dir());
-        });
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/windows8_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/windows8_parser.js b/cordova-lib/src/cordova/metadata/windows8_parser.js
deleted file mode 100644
index 53c2d31..0000000
--- a/cordova-lib/src/cordova/metadata/windows8_parser.js
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    events        = require('../events'),
-    Q             = require('q'),
-    child_process = require('child_process'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    xml           = require('../xml-helpers'),
-    config        = require('../config'),
-    hooker        = require('../hooker');
-
-module.exports = function windows8_parser(project) {
-    try {
-        // TODO : Check that it's not a windows8 project?
-        var jsproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.jsproj$/i); })[0];
-        if (!jsproj_file) throw new CordovaError('No .jsproj file in "'+project+'"');
-        this.windows8_proj_dir = project;
-        this.jsproj_path  = path.join(this.windows8_proj_dir, jsproj_file);
-        this.sln_path     = path.join(this.windows8_proj_dir, jsproj_file.replace(/\.jsproj/, '.sln'));
-    } catch(e) {
-        throw new CordovaError('The provided path "' + project + '" is not a Windows 8 project. ' + e);
-    }
-    this.manifest_path  = path.join(this.windows8_proj_dir, 'package.appxmanifest');
-};
-
-// Returns a promise
-module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking windows8 requirements...');
-    var lib_path = path.join(util.libDirectory, 'windows8', 'cordova',
-                    require('../../platforms').windows8.version, 'windows8');
-
-    var custom_path = config.has_custom_path(project_root, 'windows8');
-    if (custom_path) {
-        lib_path = path.join(custom_path, "windows8");
-    }
-    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output);
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-
-    update_from_config:function(config) {
-
-        //check config parser
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        //Get manifest file
-        var manifest = xml.parseElementtreeSync(this.manifest_path);
-
-        var version = this.fixConfigVersion(config.version());
-        var name = config.name();
-        var pkgName = config.packageName();
-        var author = config.author();
-
-        var identityNode = manifest.find('.//Identity');
-        if(identityNode) {
-            // Update app name in identity
-            var appIdName = identityNode['attrib']['Name'];
-            if (appIdName != pkgName) {
-                identityNode['attrib']['Name'] = pkgName;
-            }
-
-            // Update app version
-            var appVersion = identityNode['attrib']['Version'];
-            if(appVersion != version) {
-                identityNode['attrib']['Version'] = version;
-            }
-        }
-
-        // Update name (windows8 has it in the Application[@Id] and Application.VisualElements[@DisplayName])
-        var app = manifest.find('.//Application');
-        if(app) {
-
-            var appId = app['attrib']['Id'];
-
-            if (appId != pkgName) {
-                app['attrib']['Id'] = pkgName;
-            }
-
-            var visualElems = manifest.find('.//VisualElements') || manifest.find('.//m2:VisualElements');
-
-            if(visualElems) {
-                var displayName = visualElems['attrib']['DisplayName'];
-                if(displayName != name) {
-                    visualElems['attrib']['DisplayName'] = name;
-                }
-            }
-            else {
-                throw new Error('update_from_config expected a valid package.appxmanifest' +
-                                ' with a <VisualElements> node');
-            }
-        }
-        else {
-            throw new Error('update_from_config expected a valid package.appxmanifest' +
-                            ' with a <Application> node');
-        }
-
-        // Update properties
-        var properties = manifest.find('.//Properties');
-        if (properties && properties.find) {
-            var displayNameElement = properties.find('.//DisplayName');
-            if (displayNameElement && displayNameElement.text != name) {
-                displayNameElement.text = name;
-            }
-
-            var publisherNameElement = properties.find('.//PublisherDisplayName');
-            if (publisherNameElement && publisherNameElement.text != author) {
-                publisherNameElement.text = author;
-            }
-        }
-
-        // sort Capability elements as per CB-5350 Windows8 build fails due to invalid 'Capabilities' definition
-        // to sort elements we remove them and then add again in the appropriate order
-        var capabilitiesRoot = manifest.find('.//Capabilities'),
-            capabilities = capabilitiesRoot._children || [];
-
-        capabilities.forEach(function(elem){
-            capabilitiesRoot.remove(0, elem);
-        });
-        capabilities.sort(function(a, b) {
-            return (a.tag > b.tag)? 1: -1;
-        });
-        capabilities.forEach(function(elem){
-            capabilitiesRoot.append(elem);
-        });
-
-        //Write out manifest
-        fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
-
-        // Update icons
-        var icons = config.getIcons('windows8');
-        var platformRoot = this.windows8_proj_dir;
-        var appRoot = util.isCordova(platformRoot);
-
-        // Icons, that should be added to platform
-        var platformIcons = [
-            {dest: "images/logo.png", width: 150, height: 150},
-            {dest: "images/smalllogo.png", width: 30, height: 30},
-            {dest: "images/storelogo.png", width: 50, height: 50},
-        ];
-
-        platformIcons.forEach(function (item) {
-            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
-            if (icon){
-                var src = path.join(appRoot, icon.src),
-                    dest = path.join(platformRoot, item.dest);
-                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
-                shell.cp('-f', src, dest);
-            }
-        });
-
-    },
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.windows8_proj_dir, 'www');
-    },
-    config_xml:function() {
-        return path.join(this.windows8_proj_dir,"config.xml");
-    },
-    // copy files from merges directory to actual www dir
-    copy_merges:function(merges_sub_path) {
-        var merges_path = path.join(util.appDir(util.isCordova(this.windows8_proj_dir)), 'merges', merges_sub_path);
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, "template", 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.windows8_proj_dir);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.windows8_proj_dir, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-
-        // Copy all files from merges directory.
-        this.copy_merges('windows8');
-
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // updates the jsproj file to explicitly list all www content.
-    update_jsproj:function() {
-        var jsproj_xml = xml.parseElementtreeSync(this.jsproj_path);
-        // remove any previous references to the www files
-        var item_groups = jsproj_xml.findall('ItemGroup');
-        for (var i = 0, l = item_groups.length; i < l; i++) {
-            var group = item_groups[i];
-            var files = group.findall('Content');
-            for (var j = 0, k = files.length; j < k; j++) {
-                var file = files[j];
-                if (file.attrib.Include.substr(0, 3) == 'www') {
-                    // remove file reference
-                    group.remove(0, file);
-                    // remove ItemGroup if empty
-                    var new_group = group.findall('Content');
-                    if(new_group.length < 1) {
-                        jsproj_xml.getroot().remove(0, group);
-                    }
-                }
-            }
-        }
-
-        // now add all www references back in from the root www folder
-        var project_root = util.isCordova(this.windows8_proj_dir);
-        var www_files = this.folder_contents('www', this.www_dir());
-        for(file in www_files) {
-            var item = new et.Element('ItemGroup');
-            var content = new et.Element('Content');
-            content.attrib.Include = www_files[file];
-            item.append(content);
-            jsproj_xml.getroot().append(item);
-        }
-        // save file
-        fs.writeFileSync(this.jsproj_path, jsproj_xml.write({indent:4}), 'utf-8');
-    },
-    // Returns an array of all the files in the given directory with relative paths
-    // - name     : the name of the top level directory (i.e all files will start with this in their path)
-    // - dir     : the directory whos contents will be listed under 'name' directory
-    folder_contents:function(name, dir) {
-        var results = [];
-        var folder_dir = fs.readdirSync(dir);
-        for(item in folder_dir) {
-            var stat = fs.statSync(path.join(dir, folder_dir[item]));
-
-            if(stat.isDirectory()) {
-                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
-                //Add all subfolder item paths
-                for(sub_item in sub_dir) {
-                    results.push(sub_dir[sub_item]);
-                }
-            }
-            else if(stat.isFile()) {
-                results.push(path.join(name, folder_dir[item]));
-            }
-            // else { it is a FIFO, or a Socket, Symbolic Link or something ... }
-        }
-        return results;
-    },
-
-    // calls the nessesary functions to update the windows8 project
-    update_project:function(cfg) {
-        //console.log("Updating windows8 project...");
-
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-
-        var that = this;
-        var projectRoot = util.isCordova(process.cwd());
-
-        var hooks = new hooker(projectRoot);
-        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['windows8'] })
-        .then(function() {
-            // overrides (merges) are handled in update_www()
-            that.update_jsproj();
-            that.add_bom();
-            util.deleteSvnFolders(that.www_dir());
-        });
-    },
-
-    // Adjust version number as per CB-5337 Windows8 build fails due to invalid app version
-    fixConfigVersion: function (version) {
-        if(version && version.match(/\.\d/g)) {
-            var numVersionComponents = version.match(/\.\d/g).length + 1;
-            while (numVersionComponents++ < 4) {
-                version += '.0';
-            }
-        }
-        return version;
-    },
-
-    // CB-5421 Add BOM to all html, js, css files to ensure app can pass Windows Store Certification
-    add_bom: function () {
-        var www = this.www_dir();
-        var files = shell.ls('-R', www);
-
-        files.forEach(function (file) {
-            if (!file.match(/\.(js|html|css|json)/)) {
-                return;
-            }
-
-            var filePath = path.join(www, file);
-            var content = fs.readFileSync(filePath);
-
-            if (content[0] !== 0xEF && content[1] !== 0xBE && content[2] !== 0xBB) {
-                fs.writeFileSync(filePath, '\ufeff' + content);
-            }
-        });
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/src/cordova/metadata/wp7_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/wp7_parser.js b/cordova-lib/src/cordova/metadata/wp7_parser.js
deleted file mode 100644
index 91db24c..0000000
--- a/cordova-lib/src/cordova/metadata/wp7_parser.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var fs            = require('fs'),
-    path          = require('path'),
-    et            = require('elementtree'),
-    xml           = require('../xml-helpers'),
-    util          = require('../util'),
-    events        = require('../events'),
-    shell         = require('shelljs'),
-    child_process = require('child_process'),
-    Q             = require('q'),
-    ConfigParser  = require('../ConfigParser'),
-    CordovaError  = require('../CordovaError'),
-    config        = require('../config'),
-    hooker        = require('../hooker');
-
-module.exports = function wp7_parser(project) {
-    try {
-        // TODO : Check that it's not a wp7 project?
-        var csproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
-        if (!csproj_file) throw new CordovaError('No .csproj file in "'+project+'"');
-        this.wp7_proj_dir = project;
-        this.csproj_path  = path.join(this.wp7_proj_dir, csproj_file);
-        this.sln_path     = path.join(this.wp7_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
-    } catch(e) {
-        throw new CordovaError('The provided path "' + project + '" is not a Windows Phone 7 project. ' + e);
-    }
-    this.manifest_path  = path.join(this.wp7_proj_dir, 'Properties', 'WMAppManifest.xml');
-};
-
-// Returns a promise.
-module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking wp7 requirements...');
-    var lib_path = path.join(util.libDirectory, 'wp', 'cordova', require('../../platforms').wp7.version, 'wp7');
-    var custom_path = config.has_custom_path(project_root, 'wp7');
-    if (custom_path) {
-        lib_path = path.join(custom_path, 'wp7');
-    }
-    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output+stderr);
-        if (err) {
-            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
-        } else {
-            d.resolve();
-        }
-    });
-    return d.promise;
-};
-
-module.exports.prototype = {
-    update_from_config:function(config) {
-        //check config parser
-        if (config instanceof ConfigParser) {
-        } else throw new Error('update_from_config requires a ConfigParser object');
-
-        //Get manifest file
-        var manifest = xml.parseElementtreeSync(this.manifest_path);
-
-        //Update app version
-        var version = config.version();
-        manifest.find('.//App').attrib.Version = version;
-
-        // Update app name by editing app title in Properties\WMAppManifest.xml
-        var name = config.name();
-        var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
-        if(prev_name != name) {
-            events.emit('verbose', "Updating app name from " + prev_name + " to " + name);
-            manifest.find('.//App').attrib.Title = name;
-            manifest.find('.//App').attrib.Publisher = name + " Publisher";
-            manifest.find('.//App').attrib.Author = name + " Author";
-            manifest.find('.//PrimaryToken').attrib.TokenID = name;
-            //update name of sln and csproj.
-            name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
-            prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
-            var sln_name = fs.readdirSync(this.wp7_proj_dir).filter(function(e) { return e.match(/\.sln$/i); })[0];
-            var sln_path = path.join(this.wp7_proj_dir, sln_name);
-            var sln_file = fs.readFileSync(sln_path, 'utf-8');
-            var name_regex = new RegExp(prev_name, "g");
-            fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
-            shell.mv('-f', this.csproj_path, path.join(this.wp7_proj_dir, name + '.csproj'));
-            this.csproj_path = path.join(this.wp7_proj_dir, name + '.csproj');
-            shell.mv('-f', sln_path, path.join(this.wp7_proj_dir, name + '.sln'));
-            this.sln_path    = path.join(this.wp7_proj_dir, name + '.sln');
-        }
-
-        // Update package name by changing:
-        /*  - CordovaAppProj.csproj
-         *  - MainPage.xaml
-         *  - MainPage.xaml.cs
-         *  - App.xaml
-         *  - App.xaml.cs
-         */
-         var pkg = config.packageName();
-         var csproj = xml.parseElementtreeSync(this.csproj_path);
-         prev_name = csproj.find('.//RootNamespace').text;
-         if(prev_name != pkg) {
-            events.emit('verbose', "Updating package name from " + prev_name + " to " + pkg);
-            //CordovaAppProj.csproj
-            csproj.find('.//RootNamespace').text = pkg;
-            csproj.find('.//AssemblyName').text = pkg;
-            csproj.find('.//XapFilename').text = pkg + '.xap';
-            csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
-            fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
-            //MainPage.xaml
-            var mainPageXAML = xml.parseElementtreeSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'));
-            mainPageXAML.getroot().attrib['x:Class'] = pkg + '.MainPage';
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
-            //MainPage.xaml.cs
-            var mainPageCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
-            var namespaceRegEx = new RegExp('namespace ' + prev_name);
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-            //App.xaml
-            var appXAML = xml.parseElementtreeSync(path.join(this.wp7_proj_dir, 'App.xaml'));
-            appXAML.getroot().attrib['x:Class'] = pkg + '.App';
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
-            //App.xaml.cs
-            var appCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), 'utf-8');
-            fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
-         }
-
-         //Write out manifest
-         fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
-    },
-    // Returns the platform-specific www directory.
-    www_dir:function() {
-        return path.join(this.wp7_proj_dir, 'www');
-    },
-    config_xml:function() {
-        return path.join(this.wp7_proj_dir, 'config.xml');
-    },
-    // copy files from merges directory to actual www dir
-    copy_merges:function(merges_sub_path) {
-        var merges_path = path.join(util.appDir(util.isCordova(this.wp7_proj_dir)), 'merges', merges_sub_path);
-        if (fs.existsSync(merges_path)) {
-            var overrides = path.join(merges_path, '*');
-            shell.cp('-rf', overrides, this.www_dir());
-        }
-    },
-
-    // Used for creating platform_www in projects created by older versions.
-    cordovajs_path:function(libDir) {
-        var jsPath = path.join(libDir, '..', 'common', 'www', 'cordova.js');
-        return path.resolve(jsPath);
-    },
-
-    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
-    update_www:function() {
-        var projectRoot = util.isCordova(this.wp7_proj_dir);
-        var app_www = util.projectWww(projectRoot);
-        var platform_www = path.join(this.wp7_proj_dir, 'platform_www');
-
-        // Clear the www dir
-        shell.rm('-rf', this.www_dir());
-        shell.mkdir(this.www_dir());
-        // Copy over all app www assets
-        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
-
-        // Copy all files from merges directories - wp generic first, then wp7 specific.
-        this.copy_merges('wp');
-        this.copy_merges('wp7');
-        // Copy over stock platform www assets (cordova.js)
-        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
-    },
-
-    // updates the csproj file to explicitly list all www content.
-    update_csproj:function() {
-        var csproj_xml = xml.parseElementtreeSync(this.csproj_path);
-        // remove any previous references to the www files
-        var item_groups = csproj_xml.findall('ItemGroup');
-        for (var i = 0, l = item_groups.length; i < l; i++) {
-            var group = item_groups[i];
-            var files = group.findall('Content');
-            for (var j = 0, k = files.length; j < k; j++) {
-                var file = files[j];
-                if (file.attrib.Include.substr(0, 3) == 'www') {
-                    // remove file reference
-                    group.remove(0, file);
-                    // remove ItemGroup if empty
-                    var new_group = group.findall('Content');
-                    if(new_group.length < 1) {
-                        csproj_xml.getroot().remove(0, group);
-                    }
-                }
-            }
-        }
-
-        // now add all www references back in from the wp www folder
-        var www_files = this.folder_contents('www', this.www_dir());
-        for(file in www_files) {
-            var item = new et.Element('ItemGroup');
-            var content = new et.Element('Content');
-            content.attrib.Include = www_files[file];
-            item.append(content);
-            csproj_xml.getroot().append(item);
-        }
-        // save file
-        fs.writeFileSync(this.csproj_path, csproj_xml.write({indent:4}), 'utf-8');
-    },
-    // Returns an array of all the files in the given directory with relative paths
-    // - name     : the name of the top level directory (i.e all files will start with this in their path)
-    // - dir      : the directory whos contents will be listed under 'name' directory
-    folder_contents:function(name, dir) {
-        var results = [];
-        var folder_dir = fs.readdirSync(dir);
-        for(item in folder_dir) {
-            var stat = fs.statSync(path.join(dir, folder_dir[item]));
-
-            if(stat.isDirectory()) {
-                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
-                //Add all subfolder item paths
-                for(sub_item in sub_dir) {
-                    results.push(sub_dir[sub_item]);
-                }
-            }
-            else if(stat.isFile()) {
-                results.push(path.join(name, folder_dir[item]));
-            }
-            // else { it is a FIFO, or a Socket or something ... }
-        }
-        return results;
-    },
-
-    // calls the nessesary functions to update the wp7 project
-    // Returns a promise.
-    update_project:function(cfg) {
-        try {
-            this.update_from_config(cfg);
-        } catch(e) {
-            return Q.reject(e);
-        }
-        // trigger an event in case anyone needs to modify the contents of the www folder before we package it.
-        var that = this;
-        var projectRoot = util.isCordova(process.cwd());
-        var hooks = new hooker(projectRoot);
-
-        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['wp7']  })
-        .then(function() {
-            that.update_csproj();
-            // TODO: Add overrides support? Why is this missing?
-            util.deleteSvnFolders(that.www_dir());
-        });
-    }
-};


[04/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/hooker.spec.js
----------------------------------------------------------------------
diff --git a/spec/hooker.spec.js b/spec/hooker.spec.js
deleted file mode 100644
index c85cc59..0000000
--- a/spec/hooker.spec.js
+++ /dev/null
@@ -1,261 +0,0 @@
- /**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-**/
-
-
-var cordova = require('../cordova'),
-    hooker = require('../src/hooker'),
-    shell  = require('shelljs'),
-    path   = require('path'),
-    fs     = require('fs'),
-    os     = require('os'),
-    Q      = require('q'),
-    child_process = require('child_process'),
-    helpers = require('./helpers');
-
-var platform = os.platform();
-var tmpDir = helpers.tmpDir('hooks_test');
-var project = path.join(tmpDir, 'project');
-var dotCordova = path.join(project, '.cordova');
-var hooksDir = path.join(project, '.cordova', 'hooks');
-var ext = platform.match(/(win32|win64)/)?'bat':'sh';
-
-
-// copy fixture
-shell.rm('-rf', project);
-shell.mkdir('-p', project);
-shell.cp('-R', path.join(__dirname, 'fixtures', 'base', '*'), project);
-shell.mkdir('-p', dotCordova);
-shell.cp('-R', path.join(__dirname, 'fixtures', 'hooks_' + ext), dotCordova);
-shell.mv(path.join(dotCordova, 'hooks_' + ext), hooksDir);
-shell.chmod('-R', 'ug+x', hooksDir);
-
-
-describe('hooker', function() {
-    it('should throw if provided directory is not a cordova project', function() {
-        expect(function() {
-            new hooker(tmpDir);
-        }).toThrow();
-    });
-});
-
-describe('global (static) fire method', function() {
-    it('should execute listeners serially', function(done) {
-        var test_event = 'foo';
-        var h1_fired = false;
-        var h1 = function() {
-            expect(h2_fired).toBe(false);
-            // Delay 100 ms here to check that h2 is not executed until after
-            // the promise returned by h1 is resolved.
-            var q = Q.delay(100).then(function() {
-                h1_fired = true;
-            });
-            return q;
-        };
-        var h2_fired = false;
-        var h2 = function() {
-            h2_fired = true;
-            expect(h1_fired).toBe(true);
-            return Q();
-        };
-
-        cordova.on(test_event, h1);
-        cordova.on(test_event, h2);
-        hooker.fire(test_event).then(function() {
-            expect(h1_fired).toBe(true);
-            expect(h2_fired).toBe(true);
-            done();
-        });
-    });
-});
-
-describe('module-level hooks', function() {
-    var handler = jasmine.createSpy().andReturn(Q());
-    var test_event = 'before_build';
-    var h;
-
-    beforeEach(function() {
-        h = new hooker(project);
-    });
-
-    afterEach(function() {
-        cordova.removeAllListeners(test_event);
-        handler.reset();
-    });
-
-    it('should fire handlers using cordova.on', function(done) {
-        cordova.on(test_event, handler);
-        h.fire(test_event)
-        .then(function() {
-            expect(handler).toHaveBeenCalled();
-        })
-        .fail(function(err) {
-            expect(err).not.toBeDefined();
-        })
-        .fin(done);
-    });
-
-    it('should pass the project root folder as parameter into the module-level handlers', function(done) {
-        cordova.on(test_event, handler);
-        h.fire(test_event)
-        .then(function() {
-            expect(handler).toHaveBeenCalledWith({root:project});
-        })
-        .fail(function(err) {
-            console.log(err);
-            expect(err).not.toBeDefined();
-        })
-        .fin(done);
-    });
-
-    it('should be able to stop listening to events using cordova.off', function(done) {
-        cordova.on(test_event, handler);
-        cordova.off(test_event, handler);
-        h.fire(test_event)
-        .then(function() {
-            expect(handler).not.toHaveBeenCalled();
-        })
-        .fail(function(err) {
-            console.log(err);
-            expect(err).toBeUndefined();
-        })
-        .fin(done);
-    });
-
-    it('should allow for hook to opt into asynchronous execution and block further hooks from firing using the done callback', function(done) {
-        var h1_fired = false;
-        var h1 = function() {
-            h1_fired = true;
-            expect(h2_fired).toBe(false);
-            return Q();
-        };
-        var h2_fired = false;
-        var h2 = function() {
-            h2_fired = true;
-            expect(h1_fired).toBe(true);
-            return Q();
-        };
-
-        cordova.on(test_event, h1);
-        cordova.on(test_event, h2);
-        h.fire(test_event).then(function() {
-            expect(h1_fired).toBe(true);
-            expect(h2_fired).toBe(true);
-            done();
-        });
-    });
-
-    it('should pass data object that fire calls into async handlers', function(done) {
-        var data = {
-            "hi":"ho",
-            "offtowork":"wego"
-        };
-        var async = function(opts) {
-            data.root = tmpDir;
-            expect(opts).toEqual(data);
-            return Q();
-        };
-        cordova.on(test_event, async);
-        h.fire(test_event, data).then(done);
-    });
-
-    it('should pass data object that fire calls into sync handlers', function(done) {
-        var data = {
-            "hi":"ho",
-            "offtowork":"wego"
-        };
-        var async = function(opts) {
-            data.root = tmpDir;
-            expect(opts).toEqual(data);
-        };
-        cordova.on(test_event, async);
-        h.fire(test_event, data).then(done);
-    });
-});
-
-
-describe('hooks', function() {
-    var h;
-    beforeEach(function() {
-        h = new hooker(project);
-    });
-
-
-    it('should not error if the hook is unrecognized', function(done) {
-        h.fire('CLEAN YOUR SHORTS GODDAMNIT LIKE A BIG BOY!')
-        .fail(function (err) {
-            expect('Call with unrecogized hook ').toBe('successful.\n' + err);
-        })
-        .fin(done);
-    });
-
-    it('should error if any script exits with non-zero code', function(done) {
-        h.fire('fail').then(function() {
-            expect('the call').toBe('a failure');
-        }, function(err) {
-            expect(err).toBeDefined();
-        })
-        .fin(done);
-    });
-
-    it('should execute all scripts in order', function(done) {
-        h.fire('test')
-        .then(function() {
-            var hooksOrderFile = path.join(project, 'hooks_order.txt');
-            var hooksEnvFile = path.join(project, 'hooks_env.json');
-            var hooksParamsFile = path.join(project, 'hooks_params.txt');
-            expect(hooksOrderFile).toExist();
-            expect(hooksEnvFile).toExist();
-            expect(hooksParamsFile).toExist();
-            expect(path.join(project, 'dotted_hook_should_not_fire.txt')).not.toExist();
-
-            var order = fs.readFileSync(hooksOrderFile, 'ascii').replace(/\W/gm, '');
-            expect(order).toBe('ab');
-
-            var params = fs.readFileSync(hooksParamsFile, 'ascii').trim().trim('"');
-            expect(params).toMatch(project.replace(/\\/g, '\\\\'));
-
-            var env = JSON.parse(fs.readFileSync(hooksEnvFile, 'ascii'));
-            expect(env.CORDOVA_VERSION).toEqual(require('../package').version);
-        })
-        .fail(function(err) {
-            console.log(err);
-            expect('Test hook call').toBe('successful');
-        })
-        .fin(done);
-
-    });
-
-    // Cleanup. Must be the last spec. Is there a better place for final cleanup in Jasmine?
-    it('should not fail during cleanup', function() {
-        process.chdir(path.join(__dirname, '..'));  // Non e2e tests assume CWD is repo root.
-        if(ext == 'sh') {
-            //shell.rm('-rf', tmpDir);
-        } else { // Windows:
-            // For some mysterious reason, both shell.rm and RMDIR /S /Q won't
-            // delete the dir on Windows, but they do remove the files leaving
-            // only folders. But the dir is removed just fine by
-            // shell.rm('-rf', tmpDir) at the top of this file with the next
-            // invocation of this test. The benefit of RMDIR /S /Q is that it
-            // doesn't print warnings like shell.rmdir() that look like this:
-            // rm: could not remove directory (code ENOTEMPTY): C:\Users\...
-            var cmd =  'RMDIR /S /Q ' + tmpDir;
-            child_process.exec(cmd);
-        }
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/lazy_load.spec.js
----------------------------------------------------------------------
diff --git a/spec/lazy_load.spec.js b/spec/lazy_load.spec.js
deleted file mode 100644
index 1a92ee9..0000000
--- a/spec/lazy_load.spec.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var lazy_load = require('../src/lazy_load'),
-    config = require('../src/config'),
-    util = require('../src/util'),
-    shell = require('shelljs'),
-    npmconf = require('npmconf');
-    path = require('path'),
-    hooker = require('../src/hooker'),
-    request = require('request'),
-    fs = require('fs'),
-    Q = require('q'),
-    platforms = require('../platforms');
-
-describe('lazy_load module', function() {
-    var custom_path;
-    beforeEach(function() {
-        custom_path = spyOn(config, 'has_custom_path').andReturn(false);
-    });
-    describe('cordova method (loads stock cordova libs)', function() {
-        var custom;
-        beforeEach(function() {
-            custom = spyOn(lazy_load, 'custom').andReturn(Q(path.join('lib','dir')));
-        });
-        it('should throw if platform is not a stock cordova platform', function(done) {
-            lazy_load.cordova('atari').then(function() {
-                expect('this call').toEqual('to fail');
-            }, function(err) {
-                expect('' + err).toContain('Cordova library "atari" not recognized.');
-            }).fin(done);
-        });
-        it('should invoke lazy_load.custom with appropriate url, platform, and version as specified in platforms manifest', function(done) {
-            lazy_load.cordova('android').then(function(dir) {
-                expect(custom).toHaveBeenCalledWith(platforms.android.url + ';a=snapshot;h=' + platforms.android.version + ';sf=tgz', 'cordova', 'android', platforms.android.version);
-                expect(dir).toBeDefined();
-                done();
-            });
-        });
-    });
-
-    describe('custom method (loads custom cordova libs)', function() {
-        var exists, fire, rm;
-        beforeEach(function() {
-            spyOn(shell, 'mkdir');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            exists = spyOn(fs, 'existsSync').andReturn(false);
-            readdir = spyOn(fs, 'readdirSync').andReturn(['somefile.txt']);
-            fire = spyOn(hooker, 'fire').andReturn(Q());
-        });
-
-        it('should callback with no errors and not fire event hooks if library already exists', function(done) {
-            exists.andReturn(true);
-            lazy_load.custom('http://some remote url', 'some id', 'platform X', 'three point five').then(function() {
-                expect(fire).not.toHaveBeenCalled()
-            }, function(err) {
-                expect(err).not.toBeDefined();
-            }).fin(done);
-        });
-        it('should callback with no errors and fire event hooks even if library already exists if the lib url is a local dir', function(done) {
-            exists.andReturn(true);
-            lazy_load.custom('some local dir', 'some id', 'platform X', 'three point six').then(function() {
-                expect(fire).not.toHaveBeenCalled()
-            }, function(err) {
-                expect(err).not.toBeDefined();
-            }).fin(done);
-        });
-
-        describe('remote URLs for libraries', function() {
-            var npmConfProxy;
-            var req,
-                load_spy,
-                events = {},
-                fakeRequest = {
-                    on: jasmine.createSpy().andCallFake(function(event, cb) {
-                        events[event] = cb;
-                        return fakeRequest;
-                    }),
-                    pipe: jasmine.createSpy().andCallFake(function() { return fakeRequest; })
-                };
-            beforeEach(function() {
-                npmConfProxy = null;
-                events = {};
-                fakeRequest.on.reset();
-                fakeRequest.pipe.reset();
-                req = spyOn(request, 'get').andCallFake(function() {
-                    // Fire the 'end' event shortly.
-                    setTimeout(function() {
-                        events['end']();
-                    }, 10);
-                    return fakeRequest;
-                });
-                load_spy = spyOn(npmconf, 'load').andCallFake(function(cb) { cb(null, { get: function() { return npmConfProxy }}); });
-            });
-
-            it('should call request with appopriate url params', function(done) {
-                var url = 'https://github.com/apache/someplugin';
-                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
-                    expect(req).toHaveBeenCalledWith({
-                        uri:url
-                    }, jasmine.any(Function));
-                }, function(err) {
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-            it('should take into account https-proxy npm configuration var if exists for https:// calls', function(done) {
-                var proxy = 'https://somelocalproxy.com';
-                npmConfProxy = proxy;
-                var url = 'https://github.com/apache/someplugin';
-                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
-                    expect(req).toHaveBeenCalledWith({
-                        uri:url,
-                        proxy:proxy
-                    }, jasmine.any(Function));
-                }, function(err) {
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-            it('should take into account proxy npm config var if exists for http:// calls', function(done) {
-                var proxy = 'http://somelocalproxy.com';
-                npmConfProxy = proxy;
-                var url = 'http://github.com/apache/someplugin';
-                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
-                    expect(req).toHaveBeenCalledWith({
-                        uri:url,
-                        proxy:proxy
-                    }, jasmine.any(Function));
-                }, function(err) {
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-        });
-
-        describe('local paths for libraries', function() {
-            it('should return the local path, no symlink', function(done) {
-                lazy_load.custom('/some/random/lib', 'id', 'X', 'three point eight').then(function(dir) {
-                    expect(dir).toEqual('/some/random/lib');
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-            it('should not file download hook', function(done) {
-                lazy_load.custom('/some/random/lib', 'id', 'X', 'three point nine').then(function() {
-                    expect(fire).not.toHaveBeenCalledWith('after_library_download', {platform:'X',url:'/some/random/lib',id:'id',version:'three point nine',path:'/some/random/lib', symlink:false});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-    });
-
-    describe('based_on_config method', function() {
-        var cordova, custom;
-        beforeEach(function() {
-            cordova = spyOn(lazy_load, 'cordova').andReturn(Q());
-            custom = spyOn(lazy_load, 'custom').andReturn(Q());
-        });
-        it('should invoke custom if a custom lib is specified', function(done) {
-            var read = spyOn(config, 'read').andReturn({
-                lib:{
-                    maybe:{
-                        uri:'you or eye?',
-                        id:'eye dee',
-                        version:'four point twenty'
-                    }
-                }
-            });
-            var p = '/some/random/custom/path';
-            custom_path.andReturn(p);
-            lazy_load.based_on_config('yup', 'maybe').then(function() {
-                expect(custom).toHaveBeenCalledWith('you or eye?', 'eye dee', 'maybe', 'four point twenty');
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should invoke cordova if no custom lib is specified', function(done) {
-            lazy_load.based_on_config('yup', 'ios').then(function() {
-                expect(cordova).toHaveBeenCalledWith('ios');
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/metadata/android_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/android_parser.spec.js b/spec/metadata/android_parser.spec.js
deleted file mode 100644
index 6c6ea41..0000000
--- a/spec/metadata/android_parser.spec.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-var STRINGS_XML = '<resources> <string name="app_name">mobilespec</string> </resources>';
-var MANIFEST_XML = '<manifest android:versionCode="1" android:versionName="0.0.1" package="org.apache.mobilespec">\n' +
-    '<application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">\n' +
-    '    <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="mobilespec" android:screenOrientation="VAL">\n' +
-    '        <intent-filter>\n' +
-    '            <action android:name="android.intent.action.MAIN" />\n' +
-    '            <category android:name="android.intent.category.LAUNCHER" />\n' +
-    '        </intent-filter>\n' +
-    '    </activity>\n' +
-    '</application>\n' +
-    '</manifest>\n';
-
-describe('android project parser', function() {
-    var proj = path.join('some', 'path');
-    var exists;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        spyOn(config, 'has_custom_path').andReturn(false);
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain an AndroidManifest.xml', function() {
-            exists.andReturn(false);
-            expect(function() {
-                new platforms.android.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, strings, manifest and android_config properties', function() {
-            expect(function() {
-                var p = new platforms.android.parser(proj);
-                expect(p.path).toEqual(proj);
-                expect(p.strings).toEqual(path.join(proj, 'res', 'values', 'strings.xml'));
-                expect(p.manifest).toEqual(path.join(proj, 'AndroidManifest.xml'));
-                expect(p.android_config).toEqual(path.join(proj, 'res', 'xml', 'config.xml'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, mkdir, is_cordova, write, read;
-        var android_proj = path.join(proj, 'platforms', 'android');
-        var stringsRoot;
-        var manifestRoot;
-        beforeEach(function() {
-            stringsRoot = null;
-            manifestRoot = null;
-            p = new platforms.android.parser(android_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync');
-            mkdir = spyOn(shell, 'mkdir');
-            spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-                if (/strings/.exec(path)) {
-                    return stringsRoot = new et.ElementTree(et.XML(STRINGS_XML));
-                } else if (/AndroidManifest/.exec(path)) {
-                    return manifestRoot = new et.ElementTree(et.XML(MANIFEST_XML));
-                }
-            });
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                spyOn(fs, 'readdirSync').andReturn([path.join(proj, 'src', 'android_pkg', 'MyApp.java')]);
-                cfg.name = function() { return 'testname' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                read.andReturn('package org.cordova.somepackage; public class MyApp extends CordovaActivity { }');
-            });
-
-            it('should handle no orientation', function() {
-                cfg.getPreference = function() { return null; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('VAL');
-            });
-            it('should handle default orientation', function() {
-                cfg.getPreference = function() { return 'default'; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toBeUndefined();
-            });
-            it('should handle portrait orientation', function() {
-                cfg.getPreference = function() { return 'portrait'; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('portrait');
-            });
-            it('should handle invalid orientation', function() {
-                cfg.getPreference = function() { return 'prtrait'; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('VAL');
-            });
-            it('should write out the app name to strings.xml', function() {
-                p.update_from_config(cfg);
-                expect(stringsRoot.getroot().find('string').text).toEqual('testname');
-            });
-            it('should write out the app id to androidmanifest.xml and update the cordova-android entry Java class', function() {
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().attrib.package).toEqual('testpkg');
-            });
-            it('should write out the app version to androidmanifest.xml', function() {
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().attrib['android:versionName']).toEqual('one point oh');
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return assets/www', function() {
-                expect(p.www_dir()).toEqual(path.join(android_proj, 'assets', 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(p.android_config);
-            });
-        });
-        describe('update_www method', function() {
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_overrides method', function() {
-            it('should do nothing if merges directory does not exist', function() {
-                exists.andReturn(false);
-                p.update_overrides();
-                expect(cp).not.toHaveBeenCalled();
-            });
-            it('should copy merges path into www', function() {
-                p.update_overrides();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                overrides = spyOn(p, 'update_overrides');
-                svn = spyOn(util, 'deleteSvnFolders');
-            });
-            it('should call update_from_config', function() {
-                p.update_project();
-                expect(config).toHaveBeenCalled();
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(err) {
-                    expect(err).toEqual(err);
-                });
-            });
-            it('should not call update_www', function() {
-                p.update_project();
-                expect(www).not.toHaveBeenCalled();
-            });
-            it('should call update_overrides', function() {
-                p.update_project();
-                expect(overrides).toHaveBeenCalled();
-            });
-            it('should call deleteSvnFolders', function() {
-                p.update_project();
-                expect(svn).toHaveBeenCalled();
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/metadata/blackberry_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/blackberry_parser.spec.js b/spec/metadata/blackberry_parser.spec.js
deleted file mode 100644
index b1d0b47..0000000
--- a/spec/metadata/blackberry_parser.spec.js
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    child_process = require('child_process'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
-    '<widget xmlns     = "http://www.w3.org/ns/widgets"\n' +
-    '        xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
-    '        id        = "io.cordova.hellocordova"\n' +
-    '        version   = "0.0.1">\n' +
-    '    <name>Hello Cordova</name>\n' +
-    '    <description>\n' +
-    '        A sample Apache Cordova application that responds to the deviceready event.\n' +
-    '    </description>\n' +
-    '    <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
-    '        Apache Cordova Team\n' +
-    '    </author>\n' +
-    '    <content src="index.html" />\n' +
-    '    <access origin="*" />\n' +
-    '    <preference name="fullscreen" value="true" />\n' +
-    '    <preference name="webviewbounce" value="true" />\n' +
-    '</widget>\n';
-
-describe('blackberry10 project parser', function() {
-    var proj = '/some/path';
-    var exists, custom, sh;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        sh = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            (cb || opts)(0, '', '');
-        });
-        spyOn(ConfigParser.prototype, 'write');
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function() {
-            return new et.ElementTree(et.XML(TEST_XML));
-        });
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw an exception with a path that is not a native blackberry project', function() {
-            exists.andReturn(false);
-            expect(function() {
-                new platforms.blackberry10.parser(proj);
-            }).toThrow();
-        });
-        it('should accept a proper native blackberry project path as construction parameter', function() {
-            var project;
-            expect(function() {
-                project = new platforms.blackberry10.parser(proj);
-            }).not.toThrow();
-            expect(project).toBeDefined();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if the blackberry-deploy shell-out fails', function(done) {
-            sh.andCallFake(function(cmd, opts, cb) {
-                (cb || opts)(1, 'no bb-deploy dewd!');
-            });
-            errorWrapper(platforms.blackberry10.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('no bb-deploy dewd');
-            });
-        });
-        it('should fire a callback with no error if shell out is successful', function(done) {
-            wrapper(platforms.blackberry10.parser.check_requirements(proj), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-    });
-    describe('instance', function() {
-        var p, cp, rm, mkdir, is_cordova, write, read;
-        var bb_proj = path.join(proj, 'platforms', 'blackberry10');
-        beforeEach(function() {
-            p = new platforms.blackberry10.parser(bb_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync');
-        });
-
-        describe('update_from_config method', function() {
-            var xml_name, xml_pkg, xml_version, xml_access_rm, xml_update, xml_append, xml_content;
-            beforeEach(function() {
-                xml_content = jasmine.createSpy('xml content');
-                xml_name = jasmine.createSpy('xml name');
-                xml_pkg = jasmine.createSpy('xml pkg');
-                xml_version = jasmine.createSpy('xml version');
-                xml_access_rm = jasmine.createSpy('xml access rm');
-                xml_access_add = jasmine.createSpy('xml access add');
-                xml_update = jasmine.createSpy('xml update');
-                xml_append = jasmine.createSpy('xml append');
-                xml_preference_remove = jasmine.createSpy('xml preference rm');
-                xml_preference_add = jasmine.createSpy('xml preference add');
-                p.xml.name = xml_name;
-                p.xml.packageName = xml_pkg;
-                p.xml.version = xml_version;
-                p.xml.content = xml_content;
-                p.xml.access = {
-                    remove:xml_access_rm,
-                    add: xml_access_add
-                };
-                p.xml.update = xml_update;
-                p.xml.doc = {
-                    getroot:function() { return { append:xml_append}; }
-                };
-                p.xml.preference = {
-                    add: xml_preference_add,
-                    remove: xml_preference_remove
-                };
-                cfg.name = function() { return 'testname'; };
-                cfg.packageName = function() { return 'testpkg'; };
-                cfg.version = function() { return 'one point oh'; };
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return /www', function() {
-                expect(p.www_dir()).toEqual(path.join(bb_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(proj, 'platforms', 'blackberry10', 'www', 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_overrides method', function() {
-            it('should do nothing if merges directory does not exist', function() {
-                exists.andReturn(false);
-                p.update_overrides();
-                expect(cp).not.toHaveBeenCalled();
-            });
-            it('should copy merges path into www', function() {
-                p.update_overrides();
-                expect(cp).toHaveBeenCalledWith('-rf', path.join(proj, 'merges', 'blackberry10', '*'), path.join(proj, 'platforms', 'blackberry10', 'www'));
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn, parse, get_env, write_env;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                overrides = spyOn(p, 'update_overrides');
-                svn = spyOn(util, 'deleteSvnFolders');
-                parse = spyOn(JSON, 'parse').andReturn({blackberry:{qnx:{}}});
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(e) {
-                    expect(e).toEqual(err);
-                });
-            });
-            it('should not call update_www', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(www).not.toHaveBeenCalled();
-                });
-            });
-            it('should call update_overrides', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(overrides).toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/metadata/firefoxos_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/firefoxos_parser.spec.js b/spec/metadata/firefoxos_parser.spec.js
deleted file mode 100644
index 49694eb..0000000
--- a/spec/metadata/firefoxos_parser.spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-describe('firefoxos project parser', function() {
-    var proj = path.join('some', 'path');
-    var exists, exec, custom;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
-            cb(0, '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-    });
-
-    describe('constructions', function() {
-        it('should create an instance with a path', function() {
-            expect(function() {
-                var p = new platforms.android.parser(proj);
-                expect(p.path).toEqual(proj);
-            }).not.toThrow();
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, is_cordova, write, read;
-        var ff_proj = path.join(proj, 'platforms', 'firefoxos');
-        beforeEach(function() {
-            p = new platforms.firefoxos.parser(ff_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname'; };
-                cfg.packageName = function() { return 'testpkg'; };
-                cfg.version = function() { return '1.0'; };
-            });
-
-          /*  it('should write manifest.webapp', function() {
-                //p.update_from_config(cfg);
-                //expect(write.mostRecentCall.args[0]).toEqual('manifest.webapp');
-            });*/
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/metadata/ios_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/ios_parser.spec.js b/spec/metadata/ios_parser.spec.js
deleted file mode 100644
index 5b2977e..0000000
--- a/spec/metadata/ios_parser.spec.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    plist = require('plist-with-patches'),
-    xcode = require('xcode'),
-    et = require('elementtree'),
-    fs = require('fs'),
-    Q = require('q'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('ios project parser', function () {
-    var proj = path.join('some', 'path');
-    var custom, readdir;
-    beforeEach(function() {
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.xcodeproj']);
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain an xcodeproj file', function() {
-            readdir.andReturn(['noxcodehere']);
-            expect(function() {
-                new platforms.ios.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, pbxproj, xcodeproj, originalName and cordovaproj properties', function() {
-            expect(function() {
-                var p = new platforms.ios.parser(proj);
-                expect(p.path).toEqual(proj);
-                expect(p.pbxproj).toEqual(path.join(proj, 'test.xcodeproj', 'project.pbxproj'));
-                expect(p.xcodeproj).toEqual(path.join(proj, 'test.xcodeproj'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, mkdir, is_cordova, write, read;
-        var ios_proj = path.join(proj, 'platforms', 'ios');
-        beforeEach(function() {
-            p = new platforms.ios.parser(ios_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            var mv;
-            var cfg_access_add, cfg_access_rm, cfg_pref_add, cfg_pref_rm, cfg_content;
-            var plist_parse, plist_build, xc;
-            var update_name, xc_write;
-            beforeEach(function() {
-                mv = spyOn(shell, 'mv');
-                plist_parse = spyOn(plist, 'parseFileSync').andReturn({
-                });
-                plist_build = spyOn(plist, 'build').andReturn('');
-                update_name = jasmine.createSpy('update_name');
-                xc_write = jasmine.createSpy('xcode writeSync');
-                xc = spyOn(xcode, 'project').andReturn({
-                    parse:function(cb) {cb();},
-                    updateProductName:update_name,
-                    writeSync:xc_write
-                });
-                cfg.name = function() { return 'testname' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                p = new platforms.ios.parser(ios_proj);
-            });
-
-            it('should update the app name in pbxproj by calling xcode.updateProductName, and move the ios native files to match the new name', function(done) {
-                var test_path = path.join(proj, 'platforms', 'ios', 'test');
-                var testname_path = path.join(proj, 'platforms', 'ios', 'testname');
-                wrapper(p.update_from_config(cfg), done, function() {
-                    expect(update_name).toHaveBeenCalledWith('testname');
-                    expect(mv).toHaveBeenCalledWith(path.join(test_path, 'test-Info.plist'), path.join(test_path, 'testname-Info.plist'));
-                    expect(mv).toHaveBeenCalledWith(path.join(test_path, 'test-Prefix.pch'), path.join(test_path, 'testname-Prefix.pch'));
-                    expect(mv).toHaveBeenCalledWith(test_path + '.xcodeproj', testname_path + '.xcodeproj');
-                    expect(mv).toHaveBeenCalledWith(test_path, testname_path);
-                });
-            });
-            it('should write out the app id to info plist as CFBundleIdentifier', function(done) {
-                wrapper(p.update_from_config(cfg), done, function() {
-                    expect(plist_build.mostRecentCall.args[0].CFBundleIdentifier).toEqual('testpkg');
-                });
-            });
-            it('should write out the app version to info plist as CFBundleVersion', function(done) {
-                wrapper(p.update_from_config(cfg), done, function() {
-                    expect(plist_build.mostRecentCall.args[0].CFBundleShortVersionString).toEqual('one point oh');
-                });
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return /www', function() {
-                expect(p.www_dir()).toEqual(path.join(ios_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(ios_proj, 'test', 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www(path.join('lib','dir'));
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_overrides method', function() {
-            var exists;
-            beforeEach(function() {
-                exists = spyOn(fs, 'existsSync').andReturn(true);
-            });
-            it('should do nothing if merges directory does not exist', function() {
-                exists.andReturn(false);
-                p.update_overrides();
-                expect(cp).not.toHaveBeenCalled();
-            });
-            it('should copy merges path into www', function() {
-                p.update_overrides();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config').andReturn(Q());
-                www = spyOn(p, 'update_www');
-                overrides = spyOn(p, 'update_overrides');
-                svn = spyOn(util, 'deleteSvnFolders');
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config errors', function(done) {
-                var e = new Error('uh oh!');
-                config.andReturn(Q.reject(e));
-                errorWrapper(p.update_project({}), done, function(err) {
-                    expect(err).toEqual(e);
-                });
-            });
-            it('should not call update_www', function(done) {
-                wrapper(p.update_project({}), done, function() {
-                    expect(www).not().toHaveBeenCalled();
-                });
-            });
-            it('should call update_overrides', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(overrides).toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/metadata/windows8_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/windows8_parser.spec.js b/spec/metadata/windows8_parser.spec.js
deleted file mode 100644
index 726391f..0000000
--- a/spec/metadata/windows8_parser.spec.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    child_process = require('child_process'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    et = require('elementtree'),
-    Q = require('q'),
-    fs = require('fs'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('windows8 project parser', function() {
-
-    var proj = '/some/path';
-    var exists, exec, custom, readdir, cfg_parser;
-    var winXml;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            if (!cb) cb = opts;
-            cb(null, '', '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.jsproj']);
-        winXml = null;
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-            return winXml = new et.ElementTree(et.XML('<foo><Application/><Identity/><VisualElements><a/></VisualElements><Capabilities><a/></Capabilities></foo>'));
-        });
-    });
-
-    function wrapper(promise, done, post) {
-        promise.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(promise, done, post) {
-        promise.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain a jsproj file', function() {
-            readdir.andReturn([]);
-            expect(function() {
-                new platforms.windows8.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, manifest properties', function() {
-            expect(function() {
-                var parser = new platforms.windows8.parser(proj);
-                expect(parser.windows8_proj_dir).toEqual(proj);
-                expect(parser.manifest_path).toEqual(path.join(proj, 'package.appxmanifest'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                if (!cb) cb = opts;
-                cb(50, 'there was an errorz!', '');
-            });
-            errorWrapper(platforms.windows8.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
-            wrapper(platforms.windows8.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
-            var custom_path = path.join('some','custom','path','to','windows8','lib');
-            custom.andReturn(custom_path);
-            wrapper(platforms.windows8.parser.check_requirements(proj),done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-            done();
-        });
-    });
-
-    describe('instance', function() {
-        var parser, cp, rm, is_cordova, write, read, mv, mkdir;
-        var windows8_proj = path.join(proj, 'platforms', 'windows8');
-        beforeEach(function() {
-            parser = new platforms.windows8.parser(windows8_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname' };
-                cfg.content = function() { return 'index.html' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                readdir.andReturn(['test.sln']);
-            });
-
-            it('should write out the app name to package.appxmanifest', function() {
-                parser.update_from_config(cfg);
-                var identityNode = winXml.getroot().find('.//Identity');
-                expect(identityNode.attrib.Name).toEqual(cfg.packageName());
-            });
-
-            it('should write out the app version to package.appxmanifest', function() {
-                parser.update_from_config(cfg);
-                var identityNode = winXml.getroot().find('.//Identity');
-                expect(identityNode.attrib.Version).toEqual('one point oh');
-            });
-        });
-
-        describe('www_dir method', function() {
-            it('should return www', function() {
-                expect(parser.www_dir()).toEqual(path.join(windows8_proj, 'www'));
-            });
-        });
-        describe('update_www method', function() {
-            var update_jsproj;
-            beforeEach(function() {
-                update_jsproj = spyOn(parser, 'update_jsproj');
-            });
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                parser.update_www(path.join('lib','dir'));
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn;
-            beforeEach(function() {
-                config = spyOn(parser, 'update_from_config');
-                www = spyOn(parser, 'update_www');
-                www = spyOn(parser, 'update_jsproj');
-                svn = spyOn(util, 'deleteSvnFolders');
-                exists.andReturn(false);
-            });
-            it('should call update_from_config', function() {
-                parser.update_project();
-                expect(config).toHaveBeenCalled();
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(parser.update_project({}), done, function(err) {
-                    expect(err).toEqual(err);
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(parser.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/metadata/wp7_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/wp7_parser.spec.js b/spec/metadata/wp7_parser.spec.js
deleted file mode 100644
index 0856391..0000000
--- a/spec/metadata/wp7_parser.spec.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    child_process = require('child_process'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    CordovaError = require('../../src/CordovaError'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('wp7 project parser', function() {
-    var proj = '/some/path';
-    var exists, exec, custom, readdir, cfg_parser;
-    var projXml, manifestXml;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            (cb || opts)(0, '', '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.csproj']);
-        projXml = manifestXml = null;
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-            if (/WMAppManifest.xml$/.exec(path)) {
-                return manifestXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/csproj$/.exec(path)) {
-                return projXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/xaml$/.exec(path)) {
-                return new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else {
-                throw new CordovaError('Unexpected parseElementtreeSync: ' + path);
-            }
-        });
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain a csproj file', function() {
-            readdir.andReturn([]);
-            expect(function() {
-                new platforms.wp7.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, manifest properties', function() {
-            expect(function() {
-                var p = new platforms.wp7.parser(proj);
-                expect(p.wp7_proj_dir).toEqual(proj);
-                expect(p.manifest_path).toEqual(path.join(proj, 'Properties', 'WMAppManifest.xml'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                (cb || opts)(50, 'there was an errorz!');
-            });
-            errorWrapper(platforms.wp7.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
-            wrapper(platforms.wp7.parser.check_requirements(proj), done, function(err) {
-                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
-            var custom_path = path.join('some','custom','path','to','wp7','lib');
-            custom.andReturn(custom_path);
-            wrapper(platforms.wp7.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, is_cordova, write, read, mv, mkdir;
-        var wp7_proj = path.join(proj, 'platforms', 'wp7');
-        beforeEach(function() {
-            p = new platforms.wp7.parser(wp7_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname' };
-                cfg.content = function() { return 'index.html' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                readdir.andReturn(['test.sln']);
-            });
-
-            it('should write out the app name to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Title).toEqual('testname');
-            });
-            it('should write out the app id to csproj file', function() {
-                p.update_from_config(cfg);
-                var appEl = projXml.getroot().find('.//RootNamespace');
-                expect(appEl.text).toContain('testpkg');
-            });
-            it('should write out the app version to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Version).toEqual('one point oh');
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return www', function() {
-                expect(p.www_dir()).toEqual(path.join(wp7_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(wp7_proj, 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-            var update_csproj;
-            beforeEach(function() {
-                update_csproj = spyOn(p, 'update_csproj');
-            });
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn, cfg, csproj;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                svn = spyOn(util, 'deleteSvnFolders');
-                csproj = spyOn(p, 'update_csproj');
-                exists.andReturn(false);
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function(){
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(e) {
-                    expect(e).toEqual(err);
-                });
-            });
-            it('should call update_www', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(www).not.toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/metadata/wp8_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/wp8_parser.spec.js b/spec/metadata/wp8_parser.spec.js
deleted file mode 100644
index 5ea461e..0000000
--- a/spec/metadata/wp8_parser.spec.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    child_process = require('child_process'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    CordovaError = require('../../src/CordovaError'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('wp8 project parser', function() {
-    var proj = '/some/path';
-    var exists, exec, custom, readdir, cfg_parser;
-    var manifestXml, projXml;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            (cb || opts)(0, '', '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.csproj']);
-        projXml = manifestXml = null;
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-            if (/WMAppManifest.xml$/.exec(path)) {
-                return manifestXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/csproj$/.exec(path)) {
-                return projXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/xaml$/.exec(path)) {
-                return new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else {
-                throw new CordovaError('Unexpected parseElementtreeSync: ' + path);
-            }
-        });
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain a csproj file', function() {
-            readdir.andReturn([]);
-            expect(function() {
-                new platforms.wp8.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, manifest properties', function() {
-            expect(function() {
-                var p = new platforms.wp8.parser(proj);
-                expect(p.wp8_proj_dir).toEqual(proj);
-                expect(p.manifest_path).toEqual(path.join(proj, 'Properties', 'WMAppManifest.xml'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                (cb || opts)(50, 'there was an errorz!');
-            });
-            errorWrapper(platforms.wp8.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
-            wrapper(platforms.wp8.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
-            var custom_path = path.join('some','custom','path','to','wp8','lib');
-            custom.andReturn(custom_path);
-            wrapper(platforms.wp8.parser.check_requirements(proj), done, function(err) {
-                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, is_cordova, write, read, mv, mkdir;
-        var wp8_proj = path.join(proj, 'platforms', 'wp8');
-        beforeEach(function() {
-            p = new platforms.wp8.parser(wp8_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname' };
-                cfg.content = function() { return 'index.html' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                readdir.andReturn(['test.sln']);
-            });
-
-            it('should write out the app name to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Title).toEqual('testname');
-            });
-            it('should write out the app id to csproj file', function() {
-                p.update_from_config(cfg);
-                var appEl = projXml.getroot().find('.//RootNamespace');
-                expect(appEl.text).toContain('testpkg');
-            });
-            it('should write out the app version to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Version).toEqual('one point oh');
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return www', function() {
-                expect(p.www_dir()).toEqual(path.join(wp8_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(wp8_proj, 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-            var update_csproj;
-            beforeEach(function() {
-                update_csproj = spyOn(p, 'update_csproj');
-            });
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn, csproj;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                svn = spyOn(util, 'deleteSvnFolders');
-                csproj = spyOn(p, 'update_csproj');
-                exists.andReturn(false);
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(e) {
-                    expect(e).toEqual(err);
-                });
-            });
-            it('should not call update_www', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(www).not.toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/platform.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform.spec.js b/spec/platform.spec.js
deleted file mode 100644
index e16d51d..0000000
--- a/spec/platform.spec.js
+++ /dev/null
@@ -1,108 +0,0 @@
-
-var helpers = require('./helpers'),
-    path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    platforms = require('../platforms'),
-    superspawn = require('../src/superspawn'),
-    config = require('../src/config'),
-    Q = require('q'),
-    events = require('../src/events'),
-    cordova = require('../cordova');
-
-var tmpDir = helpers.tmpDir('platform_test');
-var project = path.join(tmpDir, 'project');
-
-var platformParser = platforms[helpers.testPlatform].parser;
-
-describe('platform end-to-end', function() {
-    var results;
-
-    beforeEach(function() {
-        shell.rm('-rf', tmpDir);
-    });
-    afterEach(function() {
-        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
-        shell.rm('-rf', tmpDir);
-    });
-
-    // Factoring out some repeated checks.
-    function emptyPlatformList() {
-        return cordova.raw.platform('list').then(function() {
-            var installed = results.match(/Installed platforms: (.*)/);
-            expect(installed).toBeDefined();
-            expect(installed[1].indexOf(helpers.testPlatform)).toBe(-1);
-        });
-    }
-
-    function fullPlatformList() {
-        return cordova.raw.platform('list').then(function() {
-            var installed = results.match(/Installed platforms: (.*)/);
-            expect(installed).toBeDefined();
-            expect(installed[1].indexOf(helpers.testPlatform)).toBeGreaterThan(-1);
-        });
-    }
-
-    // The flows we want to test are add, rm, list, and upgrade.
-    // They should run the appropriate hooks.
-    // They should fail when not inside a Cordova project.
-    // These tests deliberately have no beforeEach and afterEach that are cleaning things up.
-    it('should successfully run', function(done) {
-        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
-        // Using /* doesn't work because of hidden files.
-        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
-        shell.mv(path.join(tmpDir, 'base'), project);
-        process.chdir(project);
-
-        // Now we load the config.json in the newly created project and edit the target platform's lib entry
-        // to point at the fixture version. This is necessary so that cordova.prepare can find cordova.js there.
-        var c = config.read(project);
-        c.lib[helpers.testPlatform].uri = path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform + '-lib');
-        config.write(project, c);
-
-        // The config.json in the fixture project points at fake "local" paths.
-        // Since it's not a URL, the lazy-loader will just return the junk path.
-        spyOn(superspawn, 'spawn').andCallFake(function(cmd, args) {
-            if (cmd.match(/create\b/)) {
-                // This is a call to the bin/create script, so do the copy ourselves.
-                shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', 'android'), path.join(project, 'platforms'));
-            } else if(cmd.match(/version\b/)) {
-                return Q('3.3.0');
-            } else if(cmd.match(/update\b/)) {
-                fs.writeFileSync(path.join(project, 'platforms', helpers.testPlatform, 'updated'), 'I was updated!', 'utf-8');
-            }
-            return Q();
-        });
-
-        events.on('results', function(res) { results = res; });
-
-        // Check there are no platforms yet.
-        emptyPlatformList().then(function() {
-            // Add the testing platform.
-            return cordova.raw.platform('add', [helpers.testPlatform]);
-        }).then(function() {
-            // Check the platform add was successful.
-            expect(path.join(project, 'platforms', helpers.testPlatform)).toExist();
-            expect(path.join(project, 'merges', helpers.testPlatform)).toExist();
-            expect(path.join(project, 'platforms', helpers.testPlatform, 'cordova')).toExist();
-        }).then(fullPlatformList) // Check for it in platform ls.
-        .then(function() {
-            // Try to update the platform.
-            return cordova.raw.platform('update', [helpers.testPlatform]);
-        }).then(function() {
-            // Our fake update script in the exec mock above creates this dummy file.
-            expect(path.join(project, 'platforms', helpers.testPlatform, 'updated')).toExist();
-        }).then(fullPlatformList) // Platform should still be in platform ls.
-        .then(function() {
-            // And now remove it.
-            return cordova.raw.platform('rm', [helpers.testPlatform]);
-        }).then(function() {
-            // It should be gone.
-            expect(path.join(project, 'platforms', helpers.testPlatform)).not.toExist();
-        }).then(emptyPlatformList) // platform ls should be empty too.
-        .fail(function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    });
-});
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/plugin.spec.js
----------------------------------------------------------------------
diff --git a/spec/plugin.spec.js b/spec/plugin.spec.js
deleted file mode 100644
index 2ad7b08..0000000
--- a/spec/plugin.spec.js
+++ /dev/null
@@ -1,68 +0,0 @@
-
-var helpers = require('./helpers'),
-    path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    Q = require('q'),
-    events = require('../src/events'),
-    cordova = require('../cordova');
-
-var tmpDir = helpers.tmpDir('plugin_test');
-var project = path.join(tmpDir, 'project');
-var pluginsDir = path.join(__dirname, 'fixtures', 'plugins');
-var pluginId = 'org.apache.cordova.fakeplugin1';
-
-describe('plugin end-to-end', function() {
-    var results;
-
-    beforeEach(function() {
-        shell.rm('-rf', project);
-    });
-    afterEach(function() {
-        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
-        shell.rm('-rf', tmpDir);
-    });
-
-    // The flow tested is: ls, add, ls, rm, ls.
-    // Plugin dependencies are not tested as that should be corvered in plugman tests.
-    // TODO (kamrik): Test the 'plugin search' command.
-    it('should successfully run', function(done) {
-        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
-        // Using /* doesn't work because of hidden files.
-        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
-        shell.mv(path.join(tmpDir, 'base'), project);
-        // Copy some platform to avoid working on a project with no platforms.
-        shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform), path.join(project, 'platforms'));
-        process.chdir(project);
-
-        events.on('results', function(res) { results = res; });
-
-        // Check there are no plugins yet.
-        cordova.raw.plugin('list').then(function() {
-            expect(results).toMatch(/No plugins added/gi);
-        }).then(function() {
-            // Add a fake plugin from fixtures.
-            return cordova.raw.plugin('add', path.join(pluginsDir, 'fake1'));
-        }).then(function() {
-           expect(path.join(project, 'plugins', pluginId, 'plugin.xml')).toExist();
-        }).then(function() {
-            return cordova.raw.plugin('ls');
-        }).then(function() {
-            expect(results).toContain(pluginId);
-            expect(results.length).toEqual(1);
-        }).then(function() {
-            // And now remove it.
-            return cordova.raw.plugin('rm', pluginId);
-        }).then(function() {
-            // The whole dir should be gone.
-            expect(path.join(project, 'plugins', pluginId)).not.toExist();
-        }).then(function() {
-            return cordova.raw.plugin('ls');
-        }).then(function() {
-            expect(results).toMatch(/No plugins added/gi);
-        }).fail(function(err) {
-            console.log(err);
-            expect(err).toBeUndefined();
-        }).fin(done);
-    });
-});


[13/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js
new file mode 100644
index 0000000..07e3feb
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js
@@ -0,0 +1,1712 @@
+// Platform: android
+// 3.1.0
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+;(function() {
+var CORDOVA_JS_BUILD_LABEL = '3.1.0';
+// file: lib/scripts/require.js
+
+var require,
+    define;
+
+(function () {
+    var modules = {},
+    // Stack of moduleIds currently being built.
+        requireStack = [],
+    // Map of module ID -> index into requireStack of modules currently being built.
+        inProgressModules = {},
+        SEPERATOR = ".";
+
+
+
+    function build(module) {
+        var factory = module.factory,
+            localRequire = function (id) {
+                var resultantId = id;
+                //Its a relative path, so lop off the last portion and add the id (minus "./")
+                if (id.charAt(0) === ".") {
+                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
+                }
+                return require(resultantId);
+            };
+        module.exports = {};
+        delete module.factory;
+        factory(localRequire, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw "module " + id + " not found";
+        } else if (id in inProgressModules) {
+            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
+            throw "Cycle in require graph: " + cycle;
+        }
+        if (modules[id].factory) {
+            try {
+                inProgressModules[id] = requireStack.length;
+                requireStack.push(id);
+                return build(modules[id]);
+            } finally {
+                delete inProgressModules[id];
+                requireStack.pop();
+            }
+        }
+        return modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw "module " + id + " already defined";
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+    define.moduleMap = modules;
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+
+
+var channel = require('cordova/channel');
+var platform = require('cordova/platform');
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+    windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] != 'undefined') {
+        documentEventHandlers[e].subscribe(handler);
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] != 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] != "undefined") {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] != "undefined") {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent(type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+
+var cordova = {
+    define:define,
+    require:require,
+    version:CORDOVA_JS_BUILD_LABEL,
+    platformId:platform.id,
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler:function(event) {
+        return (windowEventHandlers[event] = channel.create(event));
+    },
+    addStickyDocumentEventHandler:function(event) {
+        return (documentEventHandlers[event] = channel.createSticky(event));
+    },
+    addDocumentEventHandler:function(event) {
+        return (documentEventHandlers[event] = channel.create(event));
+    },
+    removeWindowEventHandler:function(event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler:function(event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retrieve original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function() {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     * bNoDetach is required for events which cause an exception which needs to be caught in native code
+     */
+    fireDocumentEvent: function(type, data, bNoDetach) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] != 'undefined') {
+            if( bNoDetach ) {
+                documentEventHandlers[type].fire(evt);
+            }
+            else {
+                setTimeout(function() {
+                    // Fire deviceready on listeners that were registered before cordova.js was loaded.
+                    if (type == 'deviceready') {
+                        document.dispatchEvent(evt);
+                    }
+                    documentEventHandlers[type].fire(evt);
+                }, 0);
+            }
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function(type, data) {
+        var evt = createEvent(type,data);
+        if (typeof windowEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+
+    /**
+     * Plugin callback mechanism.
+     */
+    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
+    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
+    callbackId: Math.floor(Math.random() * 2000000000),
+    callbacks:  {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     */
+    callbackSuccess: function(callbackId, args) {
+        try {
+            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
+        } catch (e) {
+            console.log("Error in error callback: " + callbackId + " = "+e);
+        }
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     */
+    callbackError: function(callbackId, args) {
+        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
+        // Derive success from status.
+        try {
+            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
+        } catch (e) {
+            console.log("Error in error callback: " + callbackId + " = "+e);
+        }
+    },
+
+    /**
+     * Called by native code when returning the result from an action.
+     */
+    callbackFromNative: function(callbackId, success, status, args, keepCallback) {
+        var callback = cordova.callbacks[callbackId];
+        if (callback) {
+            if (success && status == cordova.callbackStatus.OK) {
+                callback.success && callback.success.apply(null, args);
+            } else if (!success) {
+                callback.fail && callback.fail.apply(null, args);
+            }
+
+            // Clear callback if not expecting any more results
+            if (!keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+    addConstructor: function(func) {
+        channel.onCordovaReady.subscribe(function() {
+            try {
+                func();
+            } catch(e) {
+                console.log("Failed to run constructor: " + e);
+            }
+        });
+    }
+};
+
+
+module.exports = cordova;
+
+});
+
+// file: lib/android/android/nativeapiprovider.js
+define("cordova/android/nativeapiprovider", function(require, exports, module) {
+
+/**
+ * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
+ */
+
+var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
+var currentApi = nativeApi;
+
+module.exports = {
+    get: function() { return currentApi; },
+    setPreferPrompt: function(value) {
+        currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
+    },
+    // Used only by tests.
+    set: function(value) {
+        currentApi = value;
+    }
+};
+
+});
+
+// file: lib/android/android/promptbasednativeapi.js
+define("cordova/android/promptbasednativeapi", function(require, exports, module) {
+
+/**
+ * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
+ * This is used only on the 2.3 simulator, where addJavascriptInterface() is broken.
+ */
+
+module.exports = {
+    exec: function(service, action, callbackId, argsJson) {
+        return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId]));
+    },
+    setNativeToJsBridgeMode: function(value) {
+        prompt(value, 'gap_bridge_mode:');
+    },
+    retrieveJsMessages: function(fromOnlineEvent) {
+        return prompt(+fromOnlineEvent, 'gap_poll:');
+    }
+};
+
+});
+
+// file: lib/common/argscheck.js
+define("cordova/argscheck", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+    'A': 'Array',
+    'D': 'Date',
+    'N': 'Number',
+    'S': 'String',
+    'F': 'Function',
+    'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+    return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+    if (!moduleExports.enableChecks) {
+        return;
+    }
+    var errMsg = null;
+    var typeName;
+    for (var i = 0; i < spec.length; ++i) {
+        var c = spec.charAt(i),
+            cUpper = c.toUpperCase(),
+            arg = args[i];
+        // Asterix means allow anything.
+        if (c == '*') {
+            continue;
+        }
+        typeName = utils.typeName(arg);
+        if ((arg === null || arg === undefined) && c == cUpper) {
+            continue;
+        }
+        if (typeName != typeMap[cUpper]) {
+            errMsg = 'Expected ' + typeMap[cUpper];
+            break;
+        }
+    }
+    if (errMsg) {
+        errMsg += ', but got ' + typeName + '.';
+        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+        // Don't log when running unit tests.
+        if (typeof jasmine == 'undefined') {
+            console.error(errMsg);
+        }
+        throw TypeError(errMsg);
+    }
+}
+
+function getValue(value, defaultValue) {
+    return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
+
+});
+
+// file: lib/common/base64.js
+define("cordova/base64", function(require, exports, module) {
+
+var base64 = exports;
+
+base64.fromArrayBuffer = function(arrayBuffer) {
+    var array = new Uint8Array(arrayBuffer);
+    return uint8ToBase64(array);
+};
+
+//------------------------------------------------------------------------------
+
+/* This code is based on the performance tests at http://jsperf.com/b64tests
+ * This 12-bit-at-a-time algorithm was the best performing version on all
+ * platforms tested.
+ */
+
+var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64_12bit;
+
+var b64_12bitTable = function() {
+    b64_12bit = [];
+    for (var i=0; i<64; i++) {
+        for (var j=0; j<64; j++) {
+            b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];
+        }
+    }
+    b64_12bitTable = function() { return b64_12bit; };
+    return b64_12bit;
+};
+
+function uint8ToBase64(rawData) {
+    var numBytes = rawData.byteLength;
+    var output="";
+    var segment;
+    var table = b64_12bitTable();
+    for (var i=0;i<numBytes-2;i+=3) {
+        segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];
+        output += table[segment >> 12];
+        output += table[segment & 0xfff];
+    }
+    if (numBytes - i == 2) {
+        segment = (rawData[i] << 16) + (rawData[i+1] << 8);
+        output += table[segment >> 12];
+        output += b64_6bit[(segment & 0xfff) >> 6];
+        output += '=';
+    } else if (numBytes - i == 1) {
+        segment = (rawData[i] << 16);
+        output += table[segment >> 12];
+        output += '==';
+    }
+    return output;
+}
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function clobber(obj, key, value) {
+    exports.replaceHookForTesting(obj, key);
+    obj[key] = value;
+    // Getters can only be overridden by getters.
+    if (obj[key] !== value) {
+        utils.defineGetter(obj, key, function() {
+            return value;
+        });
+    }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+    if (message) {
+        utils.defineGetter(obj, key, function() {
+            console.log(message);
+            delete obj[key];
+            clobber(obj, key, value);
+            return value;
+        });
+    } else {
+        clobber(obj, key, value);
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+            var result = obj.path ? require(obj.path) : {};
+
+            if (clobber) {
+                // Clobber if it doesn't exist.
+                if (typeof parent[key] === 'undefined') {
+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                } else if (typeof obj.path !== 'undefined') {
+                    // If merging, merge properties onto parent, otherwise, clobber.
+                    if (merge) {
+                        recursiveMerge(parent[key], result);
+                    } else {
+                        assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                    }
+                }
+                result = parent[key];
+            } else {
+                // Overwrite if not currently defined.
+                if (typeof parent[key] == 'undefined') {
+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                } else {
+                    // Set result to what already exists, so we can build children into it if they exist.
+                    result = parent[key];
+                }
+            }
+
+            if (obj.children) {
+                include(result, obj.children, clobber, merge);
+            }
+        } catch(e) {
+            utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (target.prototype && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                clobber(target.prototype, prop, src[prop]);
+            } else {
+                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+                    recursiveMerge(target[prop], src[prop]);
+                } else {
+                    clobber(target, prop, src[prop]);
+                }
+            }
+        }
+    }
+}
+
+exports.buildIntoButDoNotClobber = function(objects, target) {
+    include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function(objects, target) {
+    include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+    include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady*              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
+ * onDeviceReady*              User event fired to indicate that Cordova is ready
+ * onResume                    User event fired to indicate a start/resume lifecycle event
+ * onPause                     User event fired to indicate a pause lifecycle event
+ * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ */
+var Channel = function(type, sticky) {
+    this.type = type;
+    // Map of guid -> function.
+    this.handlers = {};
+    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+    this.state = sticky ? 1 : 0;
+    // Used in sticky mode to remember args passed to fire().
+    this.fireArgs = null;
+    // Used by onHasSubscribersChange to know if there are any listeners.
+    this.numHandlers = 0;
+    // Function that is called when the first listener is subscribed, or when
+    // the last listener is unsubscribed.
+    this.onHasSubscribersChange = null;
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired. All channels must be sticky channels.
+         */
+        join: function(h, c) {
+            var len = c.length,
+                i = len,
+                f = function() {
+                    if (!(--i)) h();
+                };
+            for (var j=0; j<len; j++) {
+                if (c[j].state === 0) {
+                    throw Error('Can only use join with sticky channels.');
+                }
+                c[j].subscribe(f);
+            }
+            if (!len) h();
+        },
+        create: function(type) {
+            return channel[type] = new Channel(type, false);
+        },
+        createSticky: function(type) {
+            return channel[type] = new Channel(type, true);
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = channel[feature] || this.createSticky(feature);
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+    if (this.state == 2) {
+        f.apply(c || this, this.fireArgs);
+        return;
+    }
+
+    var func = f,
+        guid = f.observer_guid;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    if (!guid) {
+        // first time any channel has seen this subscriber
+        guid = '' + nextGuid++;
+    }
+    func.observer_guid = guid;
+    f.observer_guid = guid;
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[guid]) {
+        this.handlers[guid] = func;
+        this.numHandlers++;
+        if (this.numHandlers == 1) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(f) {
+    // need a function to unsubscribe
+    forceFunction(f);
+
+    var guid = f.observer_guid,
+        handler = this.handlers[guid];
+    if (handler) {
+        delete this.handlers[guid];
+        this.numHandlers--;
+        if (this.numHandlers === 0) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    var fail = false,
+        fireArgs = Array.prototype.slice.call(arguments);
+    // Apply stickiness.
+    if (this.state == 1) {
+        this.state = 2;
+        this.fireArgs = fireArgs;
+    }
+    if (this.numHandlers) {
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
+        for (var item in this.handlers) {
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            toCall[i].apply(this, fireArgs);
+        }
+        if (this.state == 2 && this.numHandlers) {
+            this.numHandlers = 0;
+            this.handlers = {};
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.createSticky('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onDOMContentLoaded');
+
+module.exports = channel;
+
+});
+
+// file: lib/android/exec.js
+define("cordova/exec", function(require, exports, module) {
+
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success    The success callback
+ * @param {Function} fail       The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+var cordova = require('cordova'),
+    nativeApiProvider = require('cordova/android/nativeapiprovider'),
+    utils = require('cordova/utils'),
+    base64 = require('cordova/base64'),
+    jsToNativeModes = {
+        PROMPT: 0,
+        JS_OBJECT: 1,
+        // This mode is currently for benchmarking purposes only. It must be enabled
+        // on the native side through the ENABLE_LOCATION_CHANGE_EXEC_MODE
+        // constant within CordovaWebViewClient.java before it will work.
+        LOCATION_CHANGE: 2
+    },
+    nativeToJsModes = {
+        // Polls for messages using the JS->Native bridge.
+        POLLING: 0,
+        // For LOAD_URL to be viable, it would need to have a work-around for
+        // the bug where the soft-keyboard gets dismissed when a message is sent.
+        LOAD_URL: 1,
+        // For the ONLINE_EVENT to be viable, it would need to intercept all event
+        // listeners (both through addEventListener and window.ononline) as well
+        // as set the navigator property itself.
+        ONLINE_EVENT: 2,
+        // Uses reflection to access private APIs of the WebView that can send JS
+        // to be executed.
+        // Requires Android 3.2.4 or above.
+        PRIVATE_API: 3
+    },
+    jsToNativeBridgeMode,  // Set lazily.
+    nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
+    pollEnabled = false,
+    messagesFromNative = [];
+
+function androidExec(success, fail, service, action, args) {
+    // Set default bridge modes if they have not already been set.
+    // By default, we use the failsafe, since addJavascriptInterface breaks too often
+    if (jsToNativeBridgeMode === undefined) {
+        androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+    }
+
+    // Process any ArrayBuffers in the args into a string.
+    for (var i = 0; i < args.length; i++) {
+        if (utils.typeName(args[i]) == 'ArrayBuffer') {
+            args[i] = base64.fromArrayBuffer(args[i]);
+        }
+    }
+
+    var callbackId = service + cordova.callbackId++,
+        argsJson = JSON.stringify(args);
+
+    if (success || fail) {
+        cordova.callbacks[callbackId] = {success:success, fail:fail};
+    }
+
+    if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) {
+        window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;
+    } else {
+        var messages = nativeApiProvider.get().exec(service, action, callbackId, argsJson);
+        // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
+        // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2.  See CB-2666.
+        if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && messages === "@Null arguments.") {
+            androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
+            androidExec(success, fail, service, action, args);
+            androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+            return;
+        } else {
+            androidExec.processMessages(messages);
+        }
+    }
+}
+
+function pollOnceFromOnlineEvent() {
+    pollOnce(true);
+}
+
+function pollOnce(opt_fromOnlineEvent) {
+    var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent);
+    androidExec.processMessages(msg);
+}
+
+function pollingTimerFunc() {
+    if (pollEnabled) {
+        pollOnce();
+        setTimeout(pollingTimerFunc, 50);
+    }
+}
+
+function hookOnlineApis() {
+    function proxyEvent(e) {
+        cordova.fireWindowEvent(e.type);
+    }
+    // The network module takes care of firing online and offline events.
+    // It currently fires them only on document though, so we bridge them
+    // to window here (while first listening for exec()-releated online/offline
+    // events).
+    window.addEventListener('online', pollOnceFromOnlineEvent, false);
+    window.addEventListener('offline', pollOnceFromOnlineEvent, false);
+    cordova.addWindowEventHandler('online');
+    cordova.addWindowEventHandler('offline');
+    document.addEventListener('online', proxyEvent, false);
+    document.addEventListener('offline', proxyEvent, false);
+}
+
+hookOnlineApis();
+
+androidExec.jsToNativeModes = jsToNativeModes;
+androidExec.nativeToJsModes = nativeToJsModes;
+
+androidExec.setJsToNativeBridgeMode = function(mode) {
+    if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
+        console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
+        mode = jsToNativeModes.PROMPT;
+    }
+    nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
+    jsToNativeBridgeMode = mode;
+};
+
+androidExec.setNativeToJsBridgeMode = function(mode) {
+    if (mode == nativeToJsBridgeMode) {
+        return;
+    }
+    if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
+        pollEnabled = false;
+    }
+
+    nativeToJsBridgeMode = mode;
+    // Tell the native side to switch modes.
+    nativeApiProvider.get().setNativeToJsBridgeMode(mode);
+
+    if (mode == nativeToJsModes.POLLING) {
+        pollEnabled = true;
+        setTimeout(pollingTimerFunc, 1);
+    }
+};
+
+// Processes a single message, as encoded by NativeToJsMessageQueue.java.
+function processMessage(message) {
+    try {
+        var firstChar = message.charAt(0);
+        if (firstChar == 'J') {
+            eval(message.slice(1));
+        } else if (firstChar == 'S' || firstChar == 'F') {
+            var success = firstChar == 'S';
+            var keepCallback = message.charAt(1) == '1';
+            var spaceIdx = message.indexOf(' ', 2);
+            var status = +message.slice(2, spaceIdx);
+            var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
+            var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
+            var payloadKind = message.charAt(nextSpaceIdx + 1);
+            var payload;
+            if (payloadKind == 's') {
+                payload = message.slice(nextSpaceIdx + 2);
+            } else if (payloadKind == 't') {
+                payload = true;
+            } else if (payloadKind == 'f') {
+                payload = false;
+            } else if (payloadKind == 'N') {
+                payload = null;
+            } else if (payloadKind == 'n') {
+                payload = +message.slice(nextSpaceIdx + 2);
+            } else if (payloadKind == 'A') {
+                var data = message.slice(nextSpaceIdx + 2);
+                var bytes = window.atob(data);
+                var arraybuffer = new Uint8Array(bytes.length);
+                for (var i = 0; i < bytes.length; i++) {
+                    arraybuffer[i] = bytes.charCodeAt(i);
+                }
+                payload = arraybuffer.buffer;
+            } else if (payloadKind == 'S') {
+                payload = window.atob(message.slice(nextSpaceIdx + 2));
+            } else {
+                payload = JSON.parse(message.slice(nextSpaceIdx + 1));
+            }
+            cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
+        } else {
+            console.log("processMessage failed: invalid message:" + message);
+        }
+    } catch (e) {
+        console.log("processMessage failed: Message: " + message);
+        console.log("processMessage failed: Error: " + e);
+        console.log("processMessage failed: Stack: " + e.stack);
+    }
+}
+
+// This is called from the NativeToJsMessageQueue.java.
+androidExec.processMessages = function(messages) {
+    if (messages) {
+        messagesFromNative.push(messages);
+        // Check for the reentrant case, and enqueue the message if that's the case.
+        if (messagesFromNative.length > 1) {
+            return;
+        }
+        while (messagesFromNative.length) {
+            // Don't unshift until the end so that reentrancy can be detected.
+            messages = messagesFromNative[0];
+            // The Java side can send a * message to indicate that it
+            // still has messages waiting to be retrieved.
+            if (messages == '*') {
+                messagesFromNative.shift();
+                window.setTimeout(pollOnce, 0);
+                return;
+            }
+
+            var spaceIdx = messages.indexOf(' ');
+            var msgLen = +messages.slice(0, spaceIdx);
+            var message = messages.substr(spaceIdx + 1, msgLen);
+            messages = messages.slice(spaceIdx + msgLen + 1);
+            processMessage(message);
+            if (messages) {
+                messagesFromNative[0] = messages;
+            } else {
+                messagesFromNative.shift();
+            }
+        }
+    }
+};
+
+module.exports = androidExec;
+
+});
+
+// file: lib/common/init.js
+define("cordova/init", function(require, exports, module) {
+
+var channel = require('cordova/channel');
+var cordova = require('cordova');
+var modulemapper = require('cordova/modulemapper');
+var platform = require('cordova/platform');
+var pluginloader = require('cordova/pluginloader');
+
+var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
+
+function logUnfiredChannels(arr) {
+    for (var i = 0; i < arr.length; ++i) {
+        if (arr[i].state != 2) {
+            console.log('Channel not fired: ' + arr[i].type);
+        }
+    }
+}
+
+window.setTimeout(function() {
+    if (channel.onDeviceReady.state != 2) {
+        console.log('deviceready has not fired after 5 seconds.');
+        logUnfiredChannels(platformInitChannelsArray);
+        logUnfiredChannels(channel.deviceReadyChannelsArray);
+    }
+}, 5000);
+
+// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
+// We replace it so that properties that can't be clobbered can instead be overridden.
+function replaceNavigator(origNavigator) {
+    var CordovaNavigator = function() {};
+    CordovaNavigator.prototype = origNavigator;
+    var newNavigator = new CordovaNavigator();
+    // This work-around really only applies to new APIs that are newer than Function.bind.
+    // Without it, APIs such as getGamepads() break.
+    if (CordovaNavigator.bind) {
+        for (var key in origNavigator) {
+            if (typeof origNavigator[key] == 'function') {
+                newNavigator[key] = origNavigator[key].bind(origNavigator);
+            }
+        }
+    }
+    return newNavigator;
+}
+if (window.navigator) {
+    window.navigator = replaceNavigator(window.navigator);
+}
+
+if (!window.console) {
+    window.console = {
+        log: function(){}
+    };
+}
+if (!window.console.warn) {
+    window.console.warn = function(msg) {
+        this.log("warn: " + msg);
+    };
+}
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+// Listen for DOMContentLoaded and notify our channel subscribers.
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+    channel.onDOMContentLoaded.fire();
+} else {
+    document.addEventListener('DOMContentLoaded', function() {
+        channel.onDOMContentLoaded.fire();
+    }, false);
+}
+
+// _nativeReady is global variable that the native side can set
+// to signify that the native code is ready. It is a global since
+// it may be called before any cordova JS is ready.
+if (window._nativeReady) {
+    channel.onNativeReady.fire();
+}
+
+modulemapper.clobbers('cordova', 'cordova');
+modulemapper.clobbers('cordova/exec', 'cordova.exec');
+modulemapper.clobbers('cordova/exec', 'Cordova.exec');
+
+// Call the platform-specific initialization.
+platform.bootstrap && platform.bootstrap();
+
+pluginloader.load(function() {
+    channel.onPluginsReady.fire();
+});
+
+/**
+ * Create all cordova objects once native side is ready.
+ */
+channel.join(function() {
+    modulemapper.mapModules(window);
+
+    platform.initialize && platform.initialize();
+
+    // Fire event to notify that all objects are created
+    channel.onCordovaReady.fire();
+
+    // Fire onDeviceReady event once page has fully loaded, all
+    // constructors have run and cordova info has been received from native
+    // side.
+    channel.join(function() {
+        require('cordova').fireDocumentEvent('deviceready');
+    }, channel.deviceReadyChannelsArray);
+
+}, platformInitChannelsArray);
+
+
+});
+
+// file: lib/common/modulemapper.js
+define("cordova/modulemapper", function(require, exports, module) {
+
+var builder = require('cordova/builder'),
+    moduleMap = define.moduleMap,
+    symbolList,
+    deprecationMap;
+
+exports.reset = function() {
+    symbolList = [];
+    deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+    if (!(moduleName in moduleMap)) {
+        throw new Error('Module ' + moduleName + ' does not exist.');
+    }
+    symbolList.push(strategy, moduleName, symbolPath);
+    if (opt_deprecationMessage) {
+        deprecationMap[symbolPath] = opt_deprecationMessage;
+    }
+}
+
+// Note: Android 2.3 does have Function.bind().
+exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.runs = function(moduleName) {
+    addEntry('r', moduleName, null);
+};
+
+function prepareNamespace(symbolPath, context) {
+    if (!symbolPath) {
+        return context;
+    }
+    var parts = symbolPath.split('.');
+    var cur = context;
+    for (var i = 0, part; part = parts[i]; ++i) {
+        cur = cur[part] = cur[part] || {};
+    }
+    return cur;
+}
+
+exports.mapModules = function(context) {
+    var origSymbols = {};
+    context.CDV_origSymbols = origSymbols;
+    for (var i = 0, len = symbolList.length; i < len; i += 3) {
+        var strategy = symbolList[i];
+        var moduleName = symbolList[i + 1];
+        var module = require(moduleName);
+        // <runs/>
+        if (strategy == 'r') {
+            continue;
+        }
+        var symbolPath = symbolList[i + 2];
+        var lastDot = symbolPath.lastIndexOf('.');
+        var namespace = symbolPath.substr(0, lastDot);
+        var lastName = symbolPath.substr(lastDot + 1);
+
+        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
+        var parentObj = prepareNamespace(namespace, context);
+        var target = parentObj[lastName];
+
+        if (strategy == 'm' && target) {
+            builder.recursiveMerge(target, module);
+        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
+            if (!(symbolPath in origSymbols)) {
+                origSymbols[symbolPath] = target;
+            }
+            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
+        }
+    }
+};
+
+exports.getOriginalSymbol = function(context, symbolPath) {
+    var origSymbols = context.CDV_origSymbols;
+    if (origSymbols && (symbolPath in origSymbols)) {
+        return origSymbols[symbolPath];
+    }
+    var parts = symbolPath.split('.');
+    var obj = context;
+    for (var i = 0; i < parts.length; ++i) {
+        obj = obj && obj[parts[i]];
+    }
+    return obj;
+};
+
+exports.reset();
+
+
+});
+
+// file: lib/android/platform.js
+define("cordova/platform", function(require, exports, module) {
+
+module.exports = {
+    id: 'android',
+    bootstrap: function() {
+        var channel = require('cordova/channel'),
+            cordova = require('cordova'),
+            exec = require('cordova/exec'),
+            modulemapper = require('cordova/modulemapper');
+
+        // Tell the native code that a page change has occurred.
+        exec(null, null, 'PluginManager', 'startup', []);
+        // Tell the JS that the native side is ready.
+        channel.onNativeReady.fire();
+
+        // TODO: Extract this as a proper plugin.
+        modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
+
+        // Inject a listener for the backbutton on the document.
+        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+        backButtonChannel.onHasSubscribersChange = function() {
+            // If we just attached the first handler or detached the last handler,
+            // let native know we need to override the back button.
+            exec(null, null, "App", "overrideBackbutton", [this.numHandlers == 1]);
+        };
+
+        // Add hardware MENU and SEARCH button handlers
+        cordova.addDocumentEventHandler('menubutton');
+        cordova.addDocumentEventHandler('searchbutton');
+
+        // Let native code know we are all done on the JS side.
+        // Native code will then un-hide the WebView.
+        channel.onCordovaReady.subscribe(function() {
+            exec(null, null, "App", "show", []);
+        });
+    }
+};
+
+});
+
+// file: lib/android/plugin/android/app.js
+define("cordova/plugin/android/app", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+module.exports = {
+    /**
+    * Clear the resource cache.
+    */
+    clearCache:function() {
+        exec(null, null, "App", "clearCache", []);
+    },
+
+    /**
+    * Load the url into the webview or into new browser instance.
+    *
+    * @param url           The URL to load
+    * @param props         Properties that can be passed in to the activity:
+    *      wait: int                           => wait msec before loading URL
+    *      loadingDialog: "Title,Message"      => display a native loading dialog
+    *      loadUrlTimeoutValue: int            => time in msec to wait before triggering a timeout error
+    *      clearHistory: boolean              => clear webview history (default=false)
+    *      openExternal: boolean              => open in a new browser (default=false)
+    *
+    * Example:
+    *      navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
+    */
+    loadUrl:function(url, props) {
+        exec(null, null, "App", "loadUrl", [url, props]);
+    },
+
+    /**
+    * Cancel loadUrl that is waiting to be loaded.
+    */
+    cancelLoadUrl:function() {
+        exec(null, null, "App", "cancelLoadUrl", []);
+    },
+
+    /**
+    * Clear web history in this web view.
+    * Instead of BACK button loading the previous web page, it will exit the app.
+    */
+    clearHistory:function() {
+        exec(null, null, "App", "clearHistory", []);
+    },
+
+    /**
+    * Go to previous page displayed.
+    * This is the same as pressing the backbutton on Android device.
+    */
+    backHistory:function() {
+        exec(null, null, "App", "backHistory", []);
+    },
+
+    /**
+    * Override the default behavior of the Android back button.
+    * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
+    *
+    * Note: The user should not have to call this method.  Instead, when the user
+    *       registers for the "backbutton" event, this is automatically done.
+    *
+    * @param override        T=override, F=cancel override
+    */
+    overrideBackbutton:function(override) {
+        exec(null, null, "App", "overrideBackbutton", [override]);
+    },
+
+    /**
+    * Exit and terminate the application.
+    */
+    exitApp:function() {
+        return exec(null, null, "App", "exitApp", []);
+    }
+};
+
+});
+
+// file: lib/common/pluginloader.js
+define("cordova/pluginloader", function(require, exports, module) {
+
+var modulemapper = require('cordova/modulemapper');
+
+// Helper function to inject a <script> tag.
+function injectScript(url, onload, onerror) {
+    var script = document.createElement("script");
+    // onload fires even when script fails loads with an error.
+    script.onload = onload;
+    script.onerror = onerror || onload;
+    script.src = url;
+    document.head.appendChild(script);
+}
+
+function onScriptLoadingComplete(moduleList, finishPluginLoading) {
+    // Loop through all the plugins and then through their clobbers and merges.
+    for (var i = 0, module; module = moduleList[i]; i++) {
+        if (module) {
+            try {
+                if (module.clobbers && module.clobbers.length) {
+                    for (var j = 0; j < module.clobbers.length; j++) {
+                        modulemapper.clobbers(module.id, module.clobbers[j]);
+                    }
+                }
+
+                if (module.merges && module.merges.length) {
+                    for (var k = 0; k < module.merges.length; k++) {
+                        modulemapper.merges(module.id, module.merges[k]);
+                    }
+                }
+
+                // Finally, if runs is truthy we want to simply require() the module.
+                // This can be skipped if it had any merges or clobbers, though,
+                // since the mapper will already have required the module.
+                if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+                    modulemapper.runs(module.id);
+                }
+            }
+            catch(err) {
+                // error with module, most likely clobbers, should we continue?
+            }
+        }
+    }
+
+    finishPluginLoading();
+}
+
+// Handler for the cordova_plugins.js content.
+// See plugman's plugin_loader.js for the details of this object.
+// This function is only called if the really is a plugins array that isn't empty.
+// Otherwise the onerror response handler will just call finishPluginLoading().
+function handlePluginsObject(path, moduleList, finishPluginLoading) {
+    // Now inject the scripts.
+    var scriptCounter = moduleList.length;
+
+    if (!scriptCounter) {
+        finishPluginLoading();
+        return;
+    }
+    function scriptLoadedCallback() {
+        if (!--scriptCounter) {
+            onScriptLoadingComplete(moduleList, finishPluginLoading);
+        }
+    }
+
+    for (var i = 0; i < moduleList.length; i++) {
+        injectScript(path + moduleList[i].file, scriptLoadedCallback);
+    }
+}
+
+function injectPluginScript(pathPrefix, finishPluginLoading) {
+    injectScript(pathPrefix + 'cordova_plugins.js', function(){
+        try {
+            var moduleList = require("cordova/plugin_list");
+            handlePluginsObject(pathPrefix, moduleList, finishPluginLoading);
+        } catch (e) {
+            // Error loading cordova_plugins.js, file not found or something
+            // this is an acceptable error, pre-3.0.0, so we just move on.
+            finishPluginLoading();
+        }
+    }, finishPluginLoading); // also, add script load error handler for file not found
+}
+
+function findCordovaPath() {
+    var path = null;
+    var scripts = document.getElementsByTagName('script');
+    var term = 'cordova.js';
+    for (var n = scripts.length-1; n>-1; n--) {
+        var src = scripts[n].src;
+        if (src.indexOf(term) == (src.length - term.length)) {
+            path = src.substring(0, src.length - term.length);
+            break;
+        }
+    }
+    return path;
+}
+
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+exports.load = function(callback) {
+    var pathPrefix = findCordovaPath();
+    if (pathPrefix === null) {
+        console.log('Could not find cordova.js script tag. Plugin loading may fail.');
+        pathPrefix = '';
+    }
+    injectPluginScript(pathPrefix, callback);
+};
+
+
+});
+
+// file: lib/common/urlutil.js
+define("cordova/urlutil", function(require, exports, module) {
+
+var urlutil = exports;
+var anchorEl = document.createElement('a');
+
+/**
+ * For already absolute URLs, returns what is passed in.
+ * For relative URLs, converts them to absolute ones.
+ */
+urlutil.makeAbsolute = function(url) {
+  anchorEl.href = url;
+  return anchorEl.href;
+};
+
+});
+
+// file: lib/common/utils.js
+define("cordova/utils", function(require, exports, module) {
+
+var utils = exports;
+
+/**
+ * Defines a property getter / setter for obj[key].
+ */
+utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
+    if (Object.defineProperty) {
+        var desc = {
+            get: getFunc,
+            configurable: true
+        };
+        if (opt_setFunc) {
+            desc.set = opt_setFunc;
+        }
+        Object.defineProperty(obj, key, desc);
+    } else {
+        obj.__defineGetter__(key, getFunc);
+        if (opt_setFunc) {
+            obj.__defineSetter__(key, opt_setFunc);
+        }
+    }
+};
+
+/**
+ * Defines a property getter for obj[key].
+ */
+utils.defineGetter = utils.defineGetterSetter;
+
+utils.arrayIndexOf = function(a, item) {
+    if (a.indexOf) {
+        return a.indexOf(item);
+    }
+    var len = a.length;
+    for (var i = 0; i < len; ++i) {
+        if (a[i] == item) {
+            return i;
+        }
+    }
+    return -1;
+};
+
+/**
+ * Returns whether the item was found in the array.
+ */
+utils.arrayRemove = function(a, item) {
+    var index = utils.arrayIndexOf(a, item);
+    if (index != -1) {
+        a.splice(index, 1);
+    }
+    return index != -1;
+};
+
+utils.typeName = function(val) {
+    return Object.prototype.toString.call(val).slice(8, -1);
+};
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+    return utils.typeName(a) == 'Array';
+};
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+    return utils.typeName(d) == 'Date';
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if(utils.isArray(obj)){
+        retVal = [];
+        for(i = 0; i < obj.length; ++i){
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrapped version of the function
+ */
+utils.close = function(context, func, params) {
+    if (typeof params == 'undefined') {
+        return function() {
+            return func.apply(context, arguments);
+        };
+    } else {
+        return function() {
+            return func.apply(context, params);
+        };
+    }
+};
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function() {
+    // proxy used to establish prototype chain
+    var F = function() {};
+    // extend Child from Parent
+    return function(Child, Parent) {
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+    if (window.alert) {
+        window.alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+
+//------------------------------------------------------------------------------
+function UUIDcreatePart(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+
+});
+
+window.cordova = require('cordova');
+// file: lib/scripts/bootstrap.js
+
+require('cordova/init');
+
+})();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js
new file mode 100644
index 0000000..b58b5dd
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js
@@ -0,0 +1,3 @@
+cordova.define('cordova/plugin_list', function(require, exports, module) {
+module.exports = []
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css
new file mode 100644
index 0000000..51daa79
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+* {
+    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
+    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
+    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
+    background-color:#E4E4E4;
+    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0, #A7A7A7),
+        color-stop(0.51, #E4E4E4)
+    );
+    background-attachment:fixed;
+    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+    font-size:12px;
+    height:100%;
+    margin:0px;
+    padding:0px;
+    text-transform:uppercase;
+    width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+    position:absolute;             /* position in the center of the screen */
+    left:50%;
+    top:50%;
+    height:50px;                   /* text area height */
+    width:225px;                   /* text area width */
+    text-align:center;
+    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
+    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
+                                   /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+    .app {
+        background-position:left center;
+        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
+        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
+                                      /* offset horizontal: half of image width and text area width */
+    }
+}
+
+h1 {
+    font-size:24px;
+    font-weight:normal;
+    margin:0px;
+    overflow:visible;
+    padding:0px;
+    text-align:center;
+}
+
+.event {
+    border-radius:4px;
+    -webkit-border-radius:4px;
+    color:#FFFFFF;
+    font-size:12px;
+    margin:0px 30px;
+    padding:2px 0px;
+}
+
+.event.listening {
+    background-color:#333333;
+    display:block;
+}
+
+.event.received {
+    background-color:#4B946A;
+    display:none;
+}
+
+@keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+@-webkit-keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+.blink {
+    animation:fade 3000ms infinite;
+    -webkit-animation:fade 3000ms infinite;
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png
new file mode 100644
index 0000000..9519e7d
Binary files /dev/null and b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html
new file mode 100644
index 0000000..bde5741
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <meta name="format-detection" content="telephone=no" />
+        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
+        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+        <link rel="stylesheet" type="text/css" href="css/index.css" />
+        <title>Hello World</title>
+    </head>
+    <body>
+        <div class="app">
+            <h1>Apache Cordova</h1>
+            <div id="deviceready" class="blink">
+                <p class="event listening">Connecting to Device</p>
+                <p class="event received">Device is Ready</p>
+            </div>
+        </div>
+        <script type="text/javascript" src="cordova.js"></script>
+        <script type="text/javascript" src="js/index.js"></script>
+        <script type="text/javascript">
+            app.initialize();
+        </script>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js
new file mode 100644
index 0000000..31d9064
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+var app = {
+    // Application Constructor
+    initialize: function() {
+        this.bindEvents();
+    },
+    // Bind Event Listeners
+    //
+    // Bind any events that are required on startup. Common events are:
+    // 'load', 'deviceready', 'offline', and 'online'.
+    bindEvents: function() {
+        document.addEventListener('deviceready', this.onDeviceReady, false);
+    },
+    // deviceready Event Handler
+    //
+    // The scope of 'this' is the event. In order to call the 'receivedEvent'
+    // function, we must explicity call 'app.receivedEvent(...);'
+    onDeviceReady: function() {
+        app.receivedEvent('deviceready');
+    },
+    // Update DOM on a Received Event
+    receivedEvent: function(id) {
+        var parentElement = document.getElementById(id);
+        var listeningElement = parentElement.querySelector('.listening');
+        var receivedElement = parentElement.querySelector('.received');
+
+        listeningElement.setAttribute('style', 'display:none;');
+        receivedElement.setAttribute('style', 'display:block;');
+
+        console.log('Received Event: ' + id);
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html
new file mode 100644
index 0000000..71f00de
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<html>
+    <head>
+        <title>Jasmine Spec Runner</title>
+
+        <!-- jasmine source -->
+        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
+        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
+
+        <!-- include source files here... -->
+        <script type="text/javascript" src="js/index.js"></script>
+
+        <!-- include spec files here... -->
+        <script type="text/javascript" src="spec/helper.js"></script>
+        <script type="text/javascript" src="spec/index.js"></script>
+
+        <script type="text/javascript">
+            (function() {
+                var jasmineEnv = jasmine.getEnv();
+                jasmineEnv.updateInterval = 1000;
+
+                var htmlReporter = new jasmine.HtmlReporter();
+
+                jasmineEnv.addReporter(htmlReporter);
+
+                jasmineEnv.specFilter = function(spec) {
+                    return htmlReporter.specFilter(spec);
+                };
+
+                var currentWindowOnload = window.onload;
+
+                window.onload = function() {
+                    if (currentWindowOnload) {
+                        currentWindowOnload();
+                    }
+                    execJasmine();
+                };
+
+                function execJasmine() {
+                    jasmineEnv.execute();
+                }
+            })();
+        </script>
+    </head>
+    <body>
+        <div id="stage" style="display:none;"></div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml
new file mode 100644
index 0000000..9674edf
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="TestBase" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build
new file mode 100755
index 0000000..7028eb8
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build
@@ -0,0 +1,35 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var build = require('./lib/build'),
+    reqs  = require('./lib/check_reqs'),
+    args  = process.argv;
+
+// Support basic help commands
+if(args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
+                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
+    build.help();
+} else if(reqs.run()) {
+    build.run(args[2]);
+    process.exit(0);
+} else {
+    process.exit(2);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs
new file mode 100755
index 0000000..4a8abee
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs
@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var check_reqs = require('./lib/check_reqs');
+
+if(!check_reqs.run()) {
+      process.exit(2);
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean
new file mode 100755
index 0000000..70c4ca8
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean
@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var clean = require('./lib/clean'),
+    reqs  = require('./lib/check_reqs'),
+    args  = process.argv;
+
+// Usage support for when args are given
+if(args.length > 2) {
+    clean.help();
+} else if(reqs.run()) {
+    clean.run();
+    process.exit(0);
+} else {
+    process.exit(2);
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml
new file mode 100644
index 0000000..24e5725
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<widget xmlns     = "http://www.w3.org/ns/widgets"
+        id        = "io.cordova.helloCordova"
+        version   = "2.0.0">
+    <name>Hello Cordova</name>
+
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+
+    <author href="http://cordova.io" email="dev@cordova.apache.org">
+        Apache Cordova Team
+    </author>
+
+    <access origin="*"/>
+
+    <!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
+    <content src="index.html" />
+
+    <preference name="loglevel" value="DEBUG" />
+    <!--
+      <preference name="splashscreen" value="resourceName" />
+      <preference name="backgroundColor" value="0xFFF" />
+      <preference name="loadUrlTimeoutValue" value="20000" />
+      <preference name="InAppBrowserStorageEnabled" value="true" />
+      <preference name="disallowOverscroll" value="true" />
+    -->
+    <!-- This is required for native Android hooks -->
+    <feature name="App">
+        <param name="android-package" value="org.apache.cordova.App" />
+    </feature>
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js
new file mode 100755
index 0000000..1f8ebe2
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js
@@ -0,0 +1,41 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var path = require('path');
+var fs = require('fs');
+var cachedAppInfo = null;
+
+function readAppInfoFromManifest() {
+    var manifestPath = path.join(__dirname, '..', '..', 'AndroidManifest.xml');
+    var manifestData = fs.readFileSync(manifestPath, {encoding:'utf8'});
+    var packageName = /\bpackage\s*=\s*"(.+?)"/.exec(manifestData);
+    if (!packageName) throw new Error('Could not find package name within ' + manifestPath);
+    var activityTag = /<activity\b[\s\S]*<\/activity>/.exec(manifestData);
+    if (!activityTag) throw new Error('Could not find <activity> within ' + manifestPath);
+    var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag);
+    if (!activityName) throw new Error('Could not find android:name within ' + manifestPath);
+
+    return packageName[1] + '/.' + activityName[1];
+}
+
+exports.getActivityName = function() {
+    return cachedAppInfo = cachedAppInfo || readAppInfoFromManifest();
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js
new file mode 100755
index 0000000..7bc33ca
--- /dev/null
+++ b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js
@@ -0,0 +1,89 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell   = require('shelljs'),
+    clean   = require('./clean'),
+    path    = require('path'),
+    fs      = require('fs'),
+    ROOT    = path.join(__dirname, '..', '..');
+
+/*
+ * Builds the project with ant.
+ */
+module.exports.run = function(build_type) {
+    //default build type
+    build_type = typeof build_type !== 'undefined' ? build_type : "--debug";
+    var cmd;
+    switch(build_type) {
+        case '--debug' :
+            clean.run();
+            cmd = 'ant debug -f ' + path.join(ROOT, 'build.xml');
+            break;
+        case '--release' :
+            clean.run();
+            cmd = 'ant release -f ' + path.join(ROOT, 'build.xml');
+            break;
+        case '--nobuild' :
+            console.log('Skipping build...');
+            break;
+        default :
+           console.error('Build option \'' + build_type + '\' not recognized.');
+           process.exit(2);
+           break;
+    }
+    if(cmd) {
+        var result = shell.exec(cmd, {silent:false, async:false});
+        if(result.code > 0) {
+            console.error('ERROR: Failed to build android project.');
+            console.error(result.output);
+            process.exit(2);
+        }
+    }
+}
+
+/*
+ * Gets the path to the apk file, if not such file exists then
+ * the script will error out. (should we error or just return undefined?)
+ */
+module.exports.get_apk = function() {
+    if(fs.existsSync(path.join(ROOT, 'bin'))) {
+        var bin_files = fs.readdirSync(path.join(ROOT, 'bin'));
+        for (file in bin_files) {
+            if(path.extname(bin_files[file]) == '.apk') {
+                return path.join(ROOT, 'bin', bin_files[file]);
+            }
+        }
+        console.error('ERROR : No .apk found in \'bin\' folder');
+        process.exit(2);
+    } else {
+        console.error('ERROR : unable to find project bin folder, could not locate .apk');
+        process.exit(2);
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'build')) + ' [build_type]');
+    console.log('Build Types : ');
+    console.log('    \'--debug\': Default build, will build project in using ant debug');
+    console.log('    \'--release\': will build project using ant release');
+    console.log('    \'--nobuild\': will skip build process (can be used with run command)');
+    process.exit(0);
+}


[23/24] git commit: Update package.json to use cordova-lib

Posted by ka...@apache.org.
Update package.json to use cordova-lib


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

Branch: refs/heads/cordova-lib
Commit: 89db69539a178fa1e633064668746ccdfc055d63
Parents: 5e3515a
Author: Mark Koudritsky <ka...@gmail.com>
Authored: Tue Apr 29 22:11:00 2014 -0400
Committer: Mark Koudritsky <ka...@gmail.com>
Committed: Wed Apr 30 18:14:27 2014 -0400

----------------------------------------------------------------------
 package.json | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/89db6953/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index cf82fb5..10a4329 100644
--- a/package.json
+++ b/package.json
@@ -28,18 +28,9 @@
     "cli"
   ],
   "dependencies": {
-    "elementtree": "0.1.5",
-    "plugman": "0.21.0",
-    "plist-with-patches": "0.5.x",
-    "xcode": "0.6.6",
-    "shelljs": "0.1.x",
-    "request": "~2.21.0",
-    "semver": "2.0.x",
-    "tar": "0.1.x",
-    "npmconf": "0.1.x",
+    "cordova-lib": "0.0.1",
     "q": "~0.9",
     "optimist": "0.6.0",
-    "mime": "~1.2.11",
     "underscore":"1.4.4"
   },
   "devDependencies": {


[07/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/templates/hooks-README.md
----------------------------------------------------------------------
diff --git a/cordova-lib/templates/hooks-README.md b/cordova-lib/templates/hooks-README.md
new file mode 100644
index 0000000..d2563ea
--- /dev/null
+++ b/cordova-lib/templates/hooks-README.md
@@ -0,0 +1,83 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+# Cordova Hooks
+
+This directory may contain scripts used to customize cordova commands. This
+directory used to exist at `.cordova/hooks`, but has now been moved to the
+project root. Any scripts you add to these directories will be executed before
+and after the commands corresponding to the directory name. Useful for
+integrating your own build systems or integrating with version control systems.
+
+__Remember__: Make your scripts executable.
+
+## Hook Directories
+The following subdirectories will be used for hooks:
+
+    after_build/
+    after_compile/
+    after_docs/
+    after_emulate/
+    after_platform_add/
+    after_platform_rm/
+    after_platform_ls/
+    after_plugin_add/
+    after_plugin_ls/
+    after_plugin_rm/
+    after_plugin_search/
+    after_prepare/
+    after_run/
+    after_serve/
+    before_build/
+    before_compile/
+    before_docs/
+    before_emulate/
+    before_platform_add/
+    before_platform_rm/
+    before_platform_ls/
+    before_plugin_add/
+    before_plugin_ls/
+    before_plugin_rm/
+    before_plugin_search/
+    before_prepare/
+    before_run/
+    before_serve/
+    pre_package/ <-- Windows 8 and Windows Phone only.
+
+## Script Interface
+
+All scripts are run from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables:
+
+* CORDOVA_VERSION - The version of the Cordova-CLI.
+* CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios).
+* CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer)
+* CORDOVA_HOOK - Path to the hook that is being executed.
+* CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate)
+
+If a script returns a non-zero exit code, then the parent cordova command will be aborted.
+
+
+## Writing hooks
+
+We highly recommend writting your hooks using Node.js so that they are
+cross-platform. Some good examples are shown here:
+
+[http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/)
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova.js
----------------------------------------------------------------------
diff --git a/cordova.js b/cordova.js
deleted file mode 100644
index 687392b..0000000
--- a/cordova.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_events = require('./src/events');
-var cordova_util = require('./src/util');
-
-var off = function() {
-    cordova_events.removeListener.apply(cordova_events, arguments);
-};
-
-var emit = function() {
-    cordova_events.emit.apply(cordova_events, arguments);
-};
-
-exports = module.exports = {
-    on:        function() {
-        cordova_events.on.apply(cordova_events, arguments);
-    },
-    off:       off,
-    removeListener:off,
-    removeAllListeners:function() {
-        cordova_events.removeAllListeners.apply(cordova_events, arguments);
-    },
-    emit:      emit,
-    trigger:   emit,
-    raw: {}
-};
-
-exports.findProjectRoot = function(opt_startDir) {
-    return cordova_util.isCordova(opt_startDir);
-}
-
-// Each of these APIs takes a final parameter that is a callback function.
-// The callback is passed the error object upon failure, or undefined upon success.
-// To use a promise instead, call the APIs via cordova.raw.FOO(), which returns
-// a promise instead of using a final-parameter-callback.
-var addModuleProperty = cordova_util.addModuleProperty;
-addModuleProperty(module, 'prepare', './src/prepare', true);
-addModuleProperty(module, 'build', './src/build', true);
-addModuleProperty(module, 'help', './src/help');
-addModuleProperty(module, 'config', './src/config');
-addModuleProperty(module, 'create', './src/create', true);
-addModuleProperty(module, 'emulate', './src/emulate', true);
-addModuleProperty(module, 'plugin', './src/plugin', true);
-addModuleProperty(module, 'plugins', './src/plugin', true);
-addModuleProperty(module, 'serve', './src/serve');
-addModuleProperty(module, 'platform', './src/platform', true);
-addModuleProperty(module, 'platforms', './src/platform', true);
-addModuleProperty(module, 'compile', './src/compile', true);
-addModuleProperty(module, 'run', './src/run', true);
-addModuleProperty(module, 'info', './src/info', true);
-
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/platforms.js
----------------------------------------------------------------------
diff --git a/platforms.js b/platforms.js
deleted file mode 100644
index 5bb82f1..0000000
--- a/platforms.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-module.exports = {
-    'ios' : {
-        hostos : ['darwin'],
-        parser : './src/metadata/ios_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ios.git',
-        version: '3.4.1'
-    }, 
-    'android' : {
-        parser : './src/metadata/android_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git',
-        version: '3.4.0'
-    }, 
-    'ubuntu' : {
-        hostos : ['linux'],
-        parser : './src/metadata/ubuntu_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ubuntu.git',
-        version: '3.4.0'
-    }, 
-     'amazon-fireos' : {
-        parser : './src/metadata/amazon_fireos_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-amazon-fireos.git',
-        version: '3.4.0'
-    },
-    'wp7' : {
-        hostos : ['win32'],
-        parser : './src/metadata/wp7_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',
-        version: '3.4.0',
-        subdirectory: 'wp7'
-    },
-    'wp8' : {
-        hostos : ['win32'],
-        parser : './src/metadata/wp8_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',
-        version: '3.4.0',
-        subdirectory: 'wp8'
-    },
-    'blackberry10' : {
-        parser : './src/metadata/blackberry10_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-blackberry.git',
-        version: '3.4.0',
-        subdirectory: 'blackberry10'
-    },
-    'www':{
-        hostos : [],
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-app-hello-world.git',
-        version: '3.4.0'
-    },
-    'firefoxos':{
-        parser: './src/metadata/firefoxos_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-firefoxos.git',
-        version: '3.4.0'
-    },
-    'windows8':{
-        hostos : ['win32'],
-        parser: './src/metadata/windows8_parser',
-        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-windows.git',
-        version: '3.4.0',
-        subdirectory: 'windows8'
-    }
-};
-
-var addModuleProperty = require('./src/util').addModuleProperty;
-Object.keys(module.exports).forEach(function(key) {
-    var obj = module.exports[key];
-    if (obj.parser) {
-        addModuleProperty(module, 'parser', obj.parser, false, obj);
-    }
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/ConfigParser.spec.js
----------------------------------------------------------------------
diff --git a/spec/ConfigParser.spec.js b/spec/ConfigParser.spec.js
deleted file mode 100644
index 1faec88..0000000
--- a/spec/ConfigParser.spec.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var path = require('path'),
-    fs = require('fs'),
-    ConfigParser = require('../src/ConfigParser'),
-    xml = path.join(__dirname, 'test-config.xml'),
-    xml_contents = fs.readFileSync(xml, 'utf-8');
-
-describe('config.xml parser', function () {
-    var readFile;
-    beforeEach(function() {
-        readFile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
-    });
-
-    it('should create an instance based on an xml file', function() {
-        var cfg;
-        expect(function () {
-            cfg = new ConfigParser(xml);
-        }).not.toThrow();
-        expect(cfg).toBeDefined();
-        expect(cfg.doc).toBeDefined();
-    });
-
-    describe('methods', function() {
-        var cfg;
-        beforeEach(function() {
-            cfg = new ConfigParser(xml);
-        });
-
-        describe('package name / id', function() {
-            it('should get the (default) packagename', function() {
-                expect(cfg.packageName()).toEqual('io.cordova.hellocordova');
-            });
-            it('should allow setting the packagename', function() {
-                cfg.setPackageName('this.is.bat.country');
-                expect(cfg.packageName()).toEqual('this.is.bat.country');
-            });
-        });
-
-        describe('version', function() {
-            it('should get the version', function() {
-                expect(cfg.version()).toEqual('0.0.1');
-            });
-            it('should allow setting the version', function() {
-                cfg.setVersion('2.0.1');
-                expect(cfg.version()).toEqual('2.0.1');
-            });
-        });
-
-        describe('app name', function() {
-            it('should get the (default) app name', function() {
-                expect(cfg.name()).toEqual('Hello Cordova');
-            });
-            it('should allow setting the app name', function() {
-                cfg.setName('this.is.bat.country');
-                expect(cfg.name()).toEqual('this.is.bat.country');
-            });
-        });
-        describe('preference', function() {
-            it('should get value of existing preference', function() {
-                expect(cfg.getPreference('fullscreen')).toEqual('true');
-            });
-            it('should get undefined as non existing preference', function() {
-                expect(cfg.getPreference('zimzooo!')).toEqual(undefined);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/build.spec.js
----------------------------------------------------------------------
diff --git a/spec/build.spec.js b/spec/build.spec.js
deleted file mode 100644
index 259c3d4..0000000
--- a/spec/build.spec.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    shell = require('shelljs'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    Q = require('q'),
-    util = require('../src/util');
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-describe('build command', function() {
-    var is_cordova, cd_project_root, list_platforms, fire;
-    var project_dir = '/some/path';
-    var prepare_spy, compile_spy;
-    var result;
-
-    function buildPromise(f) {
-        f.then(function() { result = true; }, function(err) { result = err; });
-    }
-
-    function wrapper(f, post) {
-        runs(function() {
-            buildPromise(f);
-        });
-        waitsFor(function() { return result; }, 'promise never resolved', 500);
-        runs(post);
-    }
-
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
-        compile_spy = spyOn(cordova.raw, 'compile').andReturn(Q());
-    });
-    describe('failure', function() {
-        it('should not run inside a project with no platforms', function(done) {
-            list_platforms.andReturn([]);
-            Q().then(cordova.raw.build).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual(
-                    'No platforms added to this project. Please use `cordova platform add <platform>`.'
-                )
-            }).fin(done);
-        });
-
-        it('should not run outside of a Cordova-based project', function(done) {
-            is_cordova.andReturn(false);
-
-            Q().then(cordova.raw.build).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual(
-                    'Current working directory is not a Cordova-based project.'
-                )
-            }).fin(done);
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and call both prepare and compile', function(done) {
-            cordova.raw.build(['android','ios']).then(function() {
-                var opts = {verbose: false, platforms: ['android', 'ios'], options: []};
-                expect(prepare_spy).toHaveBeenCalledWith(opts);
-                expect(compile_spy).toHaveBeenCalledWith(opts);
-                done();
-            });
-        });
-        it('should pass down options', function(done) {
-            cordova.raw.build({platforms: ['android'], options: ['--release']}).then(function() {
-                var opts = {platforms: ['android'], options: ["--release"], verbose: false};
-                expect(prepare_spy).toHaveBeenCalledWith(opts);
-                expect(compile_spy).toHaveBeenCalledWith(opts);
-                done();
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.build(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_build', {verbose: false, platforms:['android', 'ios'], options: []});
-                    done();
-                });
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.build('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_build', {verbose: false, platforms:['android'], options: []});
-                     done();
-                });
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.build).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(err.message).toEqual(
-                        'No platforms added to this project. Please use `cordova platform add <platform>`.'
-                    )
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/compile.spec.js
----------------------------------------------------------------------
diff --git a/spec/compile.spec.js b/spec/compile.spec.js
deleted file mode 100644
index c1fc8b9..0000000
--- a/spec/compile.spec.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    superspawn = require('../src/superspawn'),
-    util = require('../src/util'),
-    Q = require('q'),
-    os = require('os');
-
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-
-describe('compile command', function() {
-    var is_cordova, list_platforms, fire, result, cd_project_root;
-    var project_dir = '/some/path';
-
-    function wrapper(f, post) {
-        runs(function() {
-            Q().then(f).then(function() { result = true; }, function(err) { result = err; });
-        });
-        waitsFor(function() { return result; }, 'promise never resolved', 500);
-        runs(post);
-    }
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        spyOn(superspawn, 'spawn').andCallFake(function() { return Q() });
-    });
-    describe('failure', function() {
-        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() {
-            list_platforms.andReturn([]);
-            wrapper(cordova.raw.compile, function() {
-                expect('' + result).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            });
-        });
-        it('should not run outside of a Cordova-based project', function() {
-            is_cordova.andReturn(false);
-            wrapper(cordova.raw.compile, function() {
-                expect(result instanceof Error).toBe(true);
-            });
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and shell out to build', function(done) {
-            cordova.raw.compile(['android','ios']).then(function() {
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'build'), [], jasmine.any(Object));
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'build'), [], jasmine.any(Object));
-                done();
-            });
-        });
-
-        it('should pass down optional parameters', function (done) {
-            cordova.raw.compile({platforms:["blackberry10"], options:["--release"]}).then(function () {
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'build'), ['--release'], jasmine.any(Object));
-                done();
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.compile(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_compile', {verbose: false, platforms:['android', 'ios'], options: []});
-                    done();
-                });
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.compile('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_compile', {verbose: false, platforms:['android'], options: []});
-                     done();
-                });
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.compile).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(fire).not.toHaveBeenCalled();
-                    expect(err.message).toContain(
-                        'No platforms added to this project. Please use `cordova platform add <platform>`.'
-                    )
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/create.spec.js
----------------------------------------------------------------------
diff --git a/spec/create.spec.js b/spec/create.spec.js
deleted file mode 100644
index ebdfab5..0000000
--- a/spec/create.spec.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var helpers = require('./helpers'),
-    path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    Q = require('q'),
-    config = require('../src/config'),
-    events = require('../src/events'),
-    util = require('../src/util'),
-    ConfigParser = require('../src/ConfigParser'),
-    cordova = require('../cordova');
-
-// A utility function to generate all combinations of elements from 2 arrays.
-// crossConcat(['x', 'y'], ['1', '2', '3'])
-// -> [ 'x1', 'x2', 'x3', 'y1', 'y2', 'y3']
-var crossConcat = function(a, b, delimiter){
-    var result = [];
-    delimiter = delimiter || '';
-    for (var i = 0; i < a.length; i++) {
-        for (var j = 0; j < b.length; j++) {
-            result.push(a[i] + delimiter + b[j]);
-        }
-    }
-    return result;
-};
-
-var tmpDir = helpers.tmpDir('create_test');
-var appName = 'TestBase';
-var appId = 'org.testing';
-var project = path.join(tmpDir, appName);
-var cordovaDir = path.join(project, '.cordova');
-var configNormal = {
-      lib: {
-        www: {
-          uri: path.join(__dirname, 'fixtures', 'base', 'www'),
-          version: "testCordovaCreate",
-          id: appName
-        }
-      }
-    };
-var configSymlink = {
-      lib: {
-        www: {
-          uri: path.join(__dirname, 'fixtures', 'base'), // "create" should copy or link the www child of this dir and not the dir itself.
-          link: true
-        }
-      }
-    };
-
-
-describe('create end-to-end', function() {
-
-    beforeEach(function() {
-        shell.rm('-rf', project);
-    });
-    afterEach(function() {
-        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
-        shell.rm('-rf', tmpDir);
-    });
-
-    function checkProject() {
-        // Check if top level dirs exist.
-        var dirs = ['hooks', 'platforms', 'merges', 'plugins', 'www'];
-        dirs.forEach(function(d) {
-            expect(path.join(project, d)).toExist();
-        });
-
-        expect(path.join(project, 'hooks', 'README.md')).toExist();
-
-        // Check if config files exist.
-        expect(path.join(project, 'www', 'index.html')).toExist();
-
-        // Check that www/config.xml was updated.
-        var configXml = new ConfigParser(path.join(project, 'www', 'config.xml'));
-        expect(configXml.packageName()).toEqual(appId);
-
-        // TODO (kamrik): check somehow that we got the right config.xml from the fixture and not some place else.
-        // expect(configXml.name()).toEqual('TestBase');
-    }
-
-    var results;
-    events.on('results', function(res) { results = res; });
-
-    it('should successfully run with regular config', function(done) {
-        // Call cordova create with no args, should return help.
-        cordova.raw.create()
-        .then(function() {
-            expect(results).toMatch(/synopsis/gi);
-        })
-        .then(function() {
-            // Create a real project
-            return cordova.raw.create(project, appId, appName, configNormal);
-        })
-        .then(checkProject)
-        .fail(function(err) {
-            console.log(err);
-            expect(err).toBeUndefined();
-        })
-        .fin(done);
-    });
-
-    it('should successfully run with symlinked www', function(done) {
-        // Call cordova create with no args, should return help.
-        cordova.raw.create(project, appId, appName, configSymlink)
-        .then(checkProject)
-        .then(function() {
-            // Check that www is really a symlink
-            expect(fs.lstatSync(path.join(project, 'www')).isSymbolicLink()).toBe(true);
-        })
-        .fail(function(err) {
-            if(process.platform.slice(0, 3) == 'win') {
-                // Allow symlink error if not in admin mode
-                expect(err.message).toBe("Symlinks on Windows require Administrator privileges");
-            } else {
-                expect(err).toBeUndefined();
-            }
-        })
-        .fin(done);
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/emulate.spec.js
----------------------------------------------------------------------
diff --git a/spec/emulate.spec.js b/spec/emulate.spec.js
deleted file mode 100644
index 8435535..0000000
--- a/spec/emulate.spec.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    superspawn = require('../src/superspawn'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    Q = require('q'),
-    util = require('../src/util'),
-    os = require('os');
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-describe('emulate command', function() {
-    var is_cordova, cd_project_root, list_platforms, fire, result;
-    var project_dir = '/some/path';
-    var prepare_spy;
-
-    function wrapper(f, post) {
-        runs(function() {
-            Q().then(f).then(function() { result = true; }, function(err) { result = err; });
-        });
-        waitsFor(function() { return result; }, 'promise never resolved', 500);
-        runs(post);
-    }
-
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
-        spyOn(superspawn, 'spawn').andCallFake(Q);
-    });
-    describe('failure', function() {
-        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() {
-            list_platforms.andReturn([]);
-            wrapper(cordova.raw.emulate, function() {
-                expect(''+ result).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            });
-        });
-        it('should not run outside of a Cordova-based project', function() {
-            is_cordova.andReturn(false);
-            wrapper(cordova.raw.emulate, function() {
-                expect(result instanceof Error).toBe(true);
-            });
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the emulate script', function(done) {
-            cordova.raw.emulate(['android','ios']).then(function(err) {
-                expect(prepare_spy).toHaveBeenCalledWith(['android', 'ios']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), ['--emulator'], jasmine.any(Object));
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator'], jasmine.any(Object));
-
-                done();
-            });
-        });
-        it('should pass down options', function(done) {
-            cordova.raw.emulate({platforms: ['ios'], options:["--optionTastic"]}).then(function(err) {
-                expect(prepare_spy).toHaveBeenCalledWith(['ios']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator', '--optionTastic'], jasmine.any(Object));
-
-                done();
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.emulate(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_emulate', {verbose: false, platforms:['android', 'ios'], options: []});
-                    done();
-                });
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.emulate('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_emulate', {verbose: false, platforms:['android'], options: []});
-                     done();
-                });
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.emulate).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(fire).not.toHaveBeenCalled();
-                    expect(''+err).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.')
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/.cordova/config.json
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/.cordova/config.json b/spec/fixtures/base/.cordova/config.json
deleted file mode 100644
index 662fc9d..0000000
--- a/spec/fixtures/base/.cordova/config.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "id": "org.testing",
-  "name":"TestBase",
-  "lib": {
-    "android": {
-      "uri": "/some/junk/path",
-      "version": "dev",
-      "id": "cordova-android-dev"
-    },
-    "ios": {
-      "uri": "/some/junk/path",
-      "version": "dev",
-      "id": "cordova-ios-dev"
-    },
-    "wp8": {
-      "uri": "/some/junk/path",
-      "version": "dev",
-      "id": "cordova-wp8-dev"
-    }
-  }
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/merges/.svn
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/merges/.svn b/spec/fixtures/base/merges/.svn
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/plugins/.svn
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/plugins/.svn b/spec/fixtures/base/plugins/.svn
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/www/config.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/www/config.xml b/spec/fixtures/base/www/config.xml
deleted file mode 100644
index 9e7b9e0..0000000
--- a/spec/fixtures/base/www/config.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <name>TestBase</name>
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-    <author email="dev@cordova.apache.org" href="http://cordova.io">
-        Apache Cordova Team
-    </author>
-    <content src="index.html" />
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/www/css/index.css
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/www/css/index.css b/spec/fixtures/base/www/css/index.css
deleted file mode 100644
index 51daa79..0000000
--- a/spec/fixtures/base/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-* {
-    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
-}
-
-body {
-    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
-    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
-    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
-    background-color:#E4E4E4;
-    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-gradient(
-        linear,
-        left top,
-        left bottom,
-        color-stop(0, #A7A7A7),
-        color-stop(0.51, #E4E4E4)
-    );
-    background-attachment:fixed;
-    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
-    font-size:12px;
-    height:100%;
-    margin:0px;
-    padding:0px;
-    text-transform:uppercase;
-    width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
-    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
-    position:absolute;             /* position in the center of the screen */
-    left:50%;
-    top:50%;
-    height:50px;                   /* text area height */
-    width:225px;                   /* text area width */
-    text-align:center;
-    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
-    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
-                                   /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
-    .app {
-        background-position:left center;
-        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
-        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
-                                      /* offset horizontal: half of image width and text area width */
-    }
-}
-
-h1 {
-    font-size:24px;
-    font-weight:normal;
-    margin:0px;
-    overflow:visible;
-    padding:0px;
-    text-align:center;
-}
-
-.event {
-    border-radius:4px;
-    -webkit-border-radius:4px;
-    color:#FFFFFF;
-    font-size:12px;
-    margin:0px 30px;
-    padding:2px 0px;
-}
-
-.event.listening {
-    background-color:#333333;
-    display:block;
-}
-
-.event.received {
-    background-color:#4B946A;
-    display:none;
-}
-
-@keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-@-webkit-keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-.blink {
-    animation:fade 3000ms infinite;
-    -webkit-animation:fade 3000ms infinite;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/www/img/logo.png
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/www/img/logo.png b/spec/fixtures/base/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
Binary files a/spec/fixtures/base/www/img/logo.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/www/index.html
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/www/index.html b/spec/fixtures/base/www/index.html
deleted file mode 100644
index bde5741..0000000
--- a/spec/fixtures/base/www/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <meta name="format-detection" content="telephone=no" />
-        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
-        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
-        <link rel="stylesheet" type="text/css" href="css/index.css" />
-        <title>Hello World</title>
-    </head>
-    <body>
-        <div class="app">
-            <h1>Apache Cordova</h1>
-            <div id="deviceready" class="blink">
-                <p class="event listening">Connecting to Device</p>
-                <p class="event received">Device is Ready</p>
-            </div>
-        </div>
-        <script type="text/javascript" src="cordova.js"></script>
-        <script type="text/javascript" src="js/index.js"></script>
-        <script type="text/javascript">
-            app.initialize();
-        </script>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/www/js/index.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/www/js/index.js b/spec/fixtures/base/www/js/index.js
deleted file mode 100644
index 31d9064..0000000
--- a/spec/fixtures/base/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-var app = {
-    // Application Constructor
-    initialize: function() {
-        this.bindEvents();
-    },
-    // Bind Event Listeners
-    //
-    // Bind any events that are required on startup. Common events are:
-    // 'load', 'deviceready', 'offline', and 'online'.
-    bindEvents: function() {
-        document.addEventListener('deviceready', this.onDeviceReady, false);
-    },
-    // deviceready Event Handler
-    //
-    // The scope of 'this' is the event. In order to call the 'receivedEvent'
-    // function, we must explicity call 'app.receivedEvent(...);'
-    onDeviceReady: function() {
-        app.receivedEvent('deviceready');
-    },
-    // Update DOM on a Received Event
-    receivedEvent: function(id) {
-        var parentElement = document.getElementById(id);
-        var listeningElement = parentElement.querySelector('.listening');
-        var receivedElement = parentElement.querySelector('.received');
-
-        listeningElement.setAttribute('style', 'display:none;');
-        receivedElement.setAttribute('style', 'display:block;');
-
-        console.log('Received Event: ' + id);
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/base/www/spec.html
----------------------------------------------------------------------
diff --git a/spec/fixtures/base/www/spec.html b/spec/fixtures/base/www/spec.html
deleted file mode 100644
index 71f00de..0000000
--- a/spec/fixtures/base/www/spec.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <title>Jasmine Spec Runner</title>
-
-        <!-- jasmine source -->
-        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
-        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
-
-        <!-- include source files here... -->
-        <script type="text/javascript" src="js/index.js"></script>
-
-        <!-- include spec files here... -->
-        <script type="text/javascript" src="spec/helper.js"></script>
-        <script type="text/javascript" src="spec/index.js"></script>
-
-        <script type="text/javascript">
-            (function() {
-                var jasmineEnv = jasmine.getEnv();
-                jasmineEnv.updateInterval = 1000;
-
-                var htmlReporter = new jasmine.HtmlReporter();
-
-                jasmineEnv.addReporter(htmlReporter);
-
-                jasmineEnv.specFilter = function(spec) {
-                    return htmlReporter.specFilter(spec);
-                };
-
-                var currentWindowOnload = window.onload;
-
-                window.onload = function() {
-                    if (currentWindowOnload) {
-                        currentWindowOnload();
-                    }
-                    execJasmine();
-                };
-
-                function execJasmine() {
-                    jasmineEnv.execute();
-                }
-            })();
-        </script>
-    </head>
-    <body>
-        <div id="stage" style="display:none;"></div>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_bat/fail/fail.bat
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_bat/fail/fail.bat b/spec/fixtures/hooks_bat/fail/fail.bat
deleted file mode 100644
index a89b4c8..0000000
--- a/spec/fixtures/hooks_bat/fail/fail.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@ECHO OFF
-EXIT /B 1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_bat/test/.dotted.bat
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_bat/test/.dotted.bat b/spec/fixtures/hooks_bat/test/.dotted.bat
deleted file mode 100644
index ada7136..0000000
--- a/spec/fixtures/hooks_bat/test/.dotted.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@ECHO OFF
-ECHO "Dotted files in hook dirs should not be called" > dotted_hook_should_not_fire.txt
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_bat/test/07.bat
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_bat/test/07.bat b/spec/fixtures/hooks_bat/test/07.bat
deleted file mode 100644
index a88c8c5..0000000
--- a/spec/fixtures/hooks_bat/test/07.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@ECHO OFF
-rem ECHO this is script 0 in %~dp0
-ECHO b >> hooks_order.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_bat/test/1.bat
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_bat/test/1.bat b/spec/fixtures/hooks_bat/test/1.bat
deleted file mode 100644
index be004c5..0000000
--- a/spec/fixtures/hooks_bat/test/1.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-@ECHO OFF
-rem ECHO this is script 1 in %~dp0
-ECHO a >> hooks_order.txt
-ECHO %1 > hooks_params.txt
-node -e "console.log(JSON.stringify(process.env, null, 2))" > hooks_env.json

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_sh/fail/fail.sh
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_sh/fail/fail.sh b/spec/fixtures/hooks_sh/fail/fail.sh
deleted file mode 100755
index 379a4c9..0000000
--- a/spec/fixtures/hooks_sh/fail/fail.sh
+++ /dev/null
@@ -1 +0,0 @@
-exit 1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_sh/test/.dotted.sh
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_sh/test/.dotted.sh b/spec/fixtures/hooks_sh/test/.dotted.sh
deleted file mode 100755
index e5fa07f..0000000
--- a/spec/fixtures/hooks_sh/test/.dotted.sh
+++ /dev/null
@@ -1 +0,0 @@
-echo "Dotted files in hook dirs should not be called" > dotted_hook_should_not_fire.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_sh/test/07.sh
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_sh/test/07.sh b/spec/fixtures/hooks_sh/test/07.sh
deleted file mode 100755
index f410ee2..0000000
--- a/spec/fixtures/hooks_sh/test/07.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#echo "this is script 0 in `pwd`";
-echo b >> hooks_order.txt

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/hooks_sh/test/1.sh
----------------------------------------------------------------------
diff --git a/spec/fixtures/hooks_sh/test/1.sh b/spec/fixtures/hooks_sh/test/1.sh
deleted file mode 100755
index 892869d..0000000
--- a/spec/fixtures/hooks_sh/test/1.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#echo "this is script 1 in `pwd`";
-echo a >> hooks_order.txt
-echo $1 > hooks_params.txt
-node -e "console.log(JSON.stringify(process.env, null, 2))" > hooks_env.json

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android-lib/VERSION
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android-lib/VERSION b/spec/fixtures/platforms/android-lib/VERSION
deleted file mode 100644
index 15a2799..0000000
--- a/spec/fixtures/platforms/android-lib/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-3.3.0

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android-lib/framework/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android-lib/framework/assets/www/cordova.js b/spec/fixtures/platforms/android-lib/framework/assets/www/cordova.js
deleted file mode 100644
index 91c51fc..0000000
--- a/spec/fixtures/platforms/android-lib/framework/assets/www/cordova.js
+++ /dev/null
@@ -1 +0,0 @@
-This is a placeholder file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/AndroidManifest.xml b/spec/fixtures/platforms/android/AndroidManifest.xml
deleted file mode 100644
index be3f245..0000000
--- a/spec/fixtures/platforms/android/AndroidManifest.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" android:windowSoftInputMode="adjustPan" package="org.testing" xmlns:android="http://schemas.android.com/apk/res/android">
-    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <application android:debuggable="true" android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
-        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="TestBase" android:theme="@android:style/Theme.Black.NoTitleBar">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
-</manifest>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/fixtures/platforms/android/assets/www/config.xml
----------------------------------------------------------------------
diff --git a/spec/fixtures/platforms/android/assets/www/config.xml b/spec/fixtures/platforms/android/assets/www/config.xml
deleted file mode 100644
index 9e7b9e0..0000000
--- a/spec/fixtures/platforms/android/assets/www/config.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <name>TestBase</name>
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-    <author email="dev@cordova.apache.org" href="http://cordova.io">
-        Apache Cordova Team
-    </author>
-    <content src="index.html" />
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-</widget>


[08/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/metadata/wp8_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/metadata/wp8_parser.js b/cordova-lib/src/cordova/metadata/wp8_parser.js
new file mode 100644
index 0000000..b5f0326
--- /dev/null
+++ b/cordova-lib/src/cordova/metadata/wp8_parser.js
@@ -0,0 +1,287 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs            = require('fs'),
+    path          = require('path'),
+    et            = require('elementtree'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    child_process = require('child_process'),
+    Q             = require('q'),
+    ConfigParser  = require('../ConfigParser'),
+    CordovaError  = require('../CordovaError'),
+    xml           = require('../xml-helpers'),
+    config        = require('../config'),
+    hooker        = require('../hooker');
+
+module.exports = function wp8_parser(project) {
+    try {
+        // TODO : Check that it's not a wp8 project?
+        var csproj_file   = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
+        if (!csproj_file) throw new CordovaError('No .csproj file in "'+project+'"');
+        this.wp8_proj_dir = project;
+        this.csproj_path  = path.join(this.wp8_proj_dir, csproj_file);
+        this.sln_path     = path.join(this.wp8_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
+    } catch(e) {
+        throw new CordovaError('The provided path "' + project + '" is not a Windows Phone 8 project. ' + e);
+    }
+    this.manifest_path  = path.join(this.wp8_proj_dir, 'Properties', 'WMAppManifest.xml');
+};
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root) {
+    events.emit('log', 'Checking wp8 requirements...');
+    var lib_path = path.join(util.libDirectory, 'wp', 'cordova', require('../../platforms').wp8.version, 'wp8');
+    var custom_path = config.has_custom_path(project_root, 'wp8');
+    if (custom_path) {
+        lib_path = path.join(custom_path, 'wp8');
+    }
+    var command = '"' + path.join(lib_path, 'bin', 'check_reqs') + '"';
+    events.emit('verbose', 'Running "' + command + '" (output to follow)');
+    var d = Q.defer();
+    child_process.exec(command, function(err, output, stderr) {
+        events.emit('verbose', output);
+        if (err) {
+            d.reject(new CordovaError('Requirements check failed: ' + output + stderr));
+        } else {
+            d.resolve();
+        }
+    });
+    return d.promise;
+};
+
+module.exports.prototype = {
+    update_from_config:function(config) {
+        //check config parser
+        if (config instanceof ConfigParser) {
+        } else throw new Error('update_from_config requires a ConfigParser object');
+
+        //Get manifest file
+        var manifest = xml.parseElementtreeSync(this.manifest_path);
+
+        //Update app version
+        var version = config.version();
+        manifest.find('.//App').attrib.Version = version;
+
+        // Update app name by editing app title in Properties\WMAppManifest.xml
+        var name = config.name();
+        var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
+        if(prev_name != name) {
+            //console.log("Updating app name from " + prev_name + " to " + name);
+            manifest.find('.//App').attrib.Title = name;
+            manifest.find('.//App').attrib.Publisher = name + " Publisher";
+            manifest.find('.//App').attrib.Author = name + " Author";
+            manifest.find('.//PrimaryToken').attrib.TokenID = name;
+            //update name of sln and csproj.
+            name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
+            prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
+            // TODO: might return .sln.user? (generated file)
+            var sln_name = fs.readdirSync(this.wp8_proj_dir).filter(function(e) { return e.match(/\.sln$/i); })[0];
+            var sln_path = path.join(this.wp8_proj_dir, sln_name);
+            var sln_file = fs.readFileSync(sln_path, 'utf-8');
+            var name_regex = new RegExp(prev_name, "g");
+            fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
+            shell.mv('-f', this.csproj_path, path.join(this.wp8_proj_dir, name + '.csproj'));
+            this.csproj_path = path.join(this.wp8_proj_dir, name + '.csproj');
+            shell.mv('-f', sln_path, path.join(this.wp8_proj_dir, name + '.sln'));
+            this.sln_path    = path.join(this.wp8_proj_dir, name + '.sln');
+        }
+
+        // Update package name by changing:
+        /*  - CordovaAppProj.csproj
+         *  - MainPage.xaml
+         *  - MainPage.xaml.cs
+         *  - App.xaml
+         *  - App.xaml.cs
+         */
+         var pkg = config.packageName();
+         var csproj = xml.parseElementtreeSync(this.csproj_path);
+         prev_name = csproj.find('.//RootNamespace').text;
+         if(prev_name != pkg) {
+            //console.log("Updating package name from " + prev_name + " to " + pkg);
+            //CordovaAppProj.csproj
+            csproj.find('.//RootNamespace').text = pkg;
+            csproj.find('.//AssemblyName').text = pkg;
+            csproj.find('.//XapFilename').text = pkg + '.xap';
+            csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
+            fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
+            //MainPage.xaml
+            var mainPageXAML = xml.parseElementtreeSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'));
+            mainPageXAML.getroot().attrib['x:Class'] = pkg + '.MainPage';
+            fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
+            //MainPage.xaml.cs
+            var mainPageCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
+            var namespaceRegEx = new RegExp('namespace ' + prev_name);
+            fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+            //App.xaml
+            var appXAML = xml.parseElementtreeSync(path.join(this.wp8_proj_dir, 'App.xaml'));
+            appXAML.getroot().attrib['x:Class'] = pkg + '.App';
+            fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
+            //App.xaml.cs
+            var appCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), 'utf-8');
+            fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+         }
+
+         //Write out manifest
+         fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
+
+        // Update icons
+        var icons = config.getIcons('wp8');
+        var platformRoot = this.wp8_proj_dir;
+        var appRoot = util.isCordova(platformRoot);
+
+        // icons, that should be added to platform
+        // @param dest {string} Path to copy icon to, relative to platform root
+        var platformIcons = [
+            {dest: "ApplicationIcon.png", width: 99, height: 99},
+            {dest: "Background.png", width: 159, height: 159},
+        ];
+
+        platformIcons.forEach(function (item) {
+            icon = icons.getIconBySize(item.width, item.height) || icons.getDefault();
+            if (icon){
+                var src = path.join(appRoot, icon.src),
+                    dest = path.join(platformRoot, item.dest);
+                events.emit('verbose', 'Copying icon from ' + src + ' to ' + dest);
+                shell.cp('-f', src, dest);
+            }
+        });
+
+    },
+    // Returns the platform-specific www directory.
+    www_dir:function() {
+        return path.join(this.wp8_proj_dir, 'www');
+    },
+    config_xml:function() {
+        return path.join(this.wp8_proj_dir, 'config.xml');
+    },
+    // copy files from merges directory to actual www dir
+    copy_merges:function(merges_sub_path) {
+        var merges_path = path.join(util.appDir(util.isCordova(this.wp8_proj_dir)), 'merges', merges_sub_path);
+        if (fs.existsSync(merges_path)) {
+            var overrides = path.join(merges_path, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    // Used for creating platform_www in projects created by older versions.
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, '..', 'common', 'www', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    // Replace the www dir with contents of platform_www and app www and updates the csproj file.
+    update_www:function() {
+        var projectRoot = util.isCordova(this.wp8_proj_dir);
+        var app_www = util.projectWww(projectRoot);
+        var platform_www = path.join(this.wp8_proj_dir, 'platform_www');
+
+        // Clear the www dir
+        shell.rm('-rf', this.www_dir());
+        shell.mkdir(this.www_dir());
+        // Copy over all app www assets
+        shell.cp('-rf', path.join(app_www, '*'), this.www_dir());
+
+        // Copy all files from merges directories - wp generic first, then wp8 specific.
+        this.copy_merges('wp');
+        this.copy_merges('wp8');
+
+        // Copy over stock platform www assets (cordova.js)
+        shell.cp('-rf', path.join(platform_www, '*'), this.www_dir());
+    },
+
+    // updates the csproj file to explicitly list all www content.
+    update_csproj:function() {
+        var csproj_xml = xml.parseElementtreeSync(this.csproj_path);
+        // remove any previous references to the www files
+        var item_groups = csproj_xml.findall('ItemGroup');
+        for (var i = 0, l = item_groups.length; i < l; i++) {
+            var group = item_groups[i];
+            var files = group.findall('Content');
+            for (var j = 0, k = files.length; j < k; j++) {
+                var file = files[j];
+                if (file.attrib.Include.substr(0, 3) == 'www') {
+                    // remove file reference
+                    group.remove(0, file);
+                    // remove ItemGroup if empty
+                    var new_group = group.findall('Content');
+                    if(new_group.length < 1) {
+                        csproj_xml.getroot().remove(0, group);
+                    }
+                }
+            }
+        }
+
+        // now add all www references back in from the root www folder
+        var www_files = this.folder_contents('www', this.www_dir());
+        for(file in www_files) {
+            var item = new et.Element('ItemGroup');
+            var content = new et.Element('Content');
+            content.attrib.Include = www_files[file];
+            item.append(content);
+            csproj_xml.getroot().append(item);
+        }
+        // save file
+        fs.writeFileSync(this.csproj_path, csproj_xml.write({indent:4}), 'utf-8');
+    },
+    // Returns an array of all the files in the given directory with relative paths
+    // - name     : the name of the top level directory (i.e all files will start with this in their path)
+    // - dir     : the directory whos contents will be listed under 'name' directory
+    folder_contents:function(name, dir) {
+        var results = [];
+        var folder_dir = fs.readdirSync(dir);
+        for(item in folder_dir) {
+            var stat = fs.statSync(path.join(dir, folder_dir[item]));
+
+            if(stat.isDirectory()) {
+                var sub_dir = this.folder_contents(path.join(name, folder_dir[item]), path.join(dir, folder_dir[item]));
+                //Add all subfolder item paths
+                for(sub_item in sub_dir) {
+                    results.push(sub_dir[sub_item]);
+                }
+            }
+            else if(stat.isFile()) {
+                results.push(path.join(name, folder_dir[item]));
+            }
+            // else { it is a FIFO, or a Socket or something ... }
+        }
+        return results;
+    },
+
+    // calls the nessesary functions to update the wp8 project
+    // Returns a promise.
+    update_project:function(cfg) {
+        try {
+            this.update_from_config(cfg);
+        } catch(e) {
+            return Q.reject(e);
+        }
+
+        // trigger an event in case anyone needs to modify the contents of the www folder before we package it.
+        var that = this;
+        var projectRoot = util.isCordova(process.cwd());
+
+        var hooks = new hooker(projectRoot);
+        return hooks.fire('pre_package', { wwwPath:this.www_dir(), platforms: ['wp8']  })
+        .then(function() {
+            that.update_csproj();
+            util.deleteSvnFolders(that.www_dir());
+        });
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/platform.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/platform.js b/cordova-lib/src/cordova/platform.js
new file mode 100644
index 0000000..bd20780
--- /dev/null
+++ b/cordova-lib/src/cordova/platform.js
@@ -0,0 +1,399 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var config            = require('./config'),
+    cordova           = require('../cordova'),
+    cordova_util      = require('./util'),
+    ConfigParser     = require('./ConfigParser'),
+    util              = require('util'),
+    fs                = require('fs'),
+    os                = require('os'),
+    path              = require('path'),
+    hooker            = require('./hooker'),
+    events            = require('./events'),
+    lazy_load         = require('./lazy_load'),
+    CordovaError      = require('./CordovaError'),
+    Q                 = require('q'),
+    platforms         = require('../platforms'),
+    superspawn        = require('./superspawn'),
+    semver            = require('semver'),
+    shell             = require('shelljs');
+
+function getVersionFromScript(script, defaultValue) {
+    var versionPromise = Q(defaultValue);
+    if (fs.existsSync(script)) {
+        versionPromise = superspawn.spawn(script);
+    } else {
+        /* if you are here, it's probably because you're in Jasmine: fix your existsSync stub */
+        versionPromise = Q(defaultValue);
+    }
+    return versionPromise;
+}
+
+function add(hooks, projectRoot, targets, opts) {
+    var xml = cordova_util.projectConfig(projectRoot);
+    var cfg = new ConfigParser(xml);
+    if (!targets || !targets.length) {
+        return Q.reject(new CordovaError('No platform specified. Please specify a platform to add. See "platform list".'));
+    }
+    var config_json = config.read(projectRoot);
+    var platformsDir = path.join(projectRoot, 'platforms');
+
+    // The "platforms" dir is safe to delete, it's almost equivalent to
+    // cordova platfrom rm <list of all platforms>
+    if ( !fs.existsSync(platformsDir)) {
+        shell.mkdir('-p', platformsDir);
+    }
+
+    return hooks.fire('before_platform_add', opts)
+    .then(function() {
+        return targets.reduce(function(soFar, t) {
+            return soFar.then(function() {
+                return lazy_load.based_on_config(projectRoot, t)
+                .then(function(libDir) {
+                    var template = config_json.lib && config_json.lib[t] && config_json.lib[t].template || null;
+                    var copts = null;
+                    if ('spawnoutput' in opts) {
+                        copts = opts.spawnoutput;
+                    }
+                    return call_into_create(t, projectRoot, cfg, libDir, template, copts);
+                }, function(err) {
+                    throw new CordovaError('Unable to fetch platform ' + t + ': ' + err);
+                });
+            });
+        }, Q());
+    })
+    .then(function() {
+        return hooks.fire('after_platform_add', opts);
+    });
+};
+
+function remove(hooks, projectRoot, targets, opts) {
+    if (!targets || !targets.length) {
+        return Q.reject(new CordovaError('No platform[s] specified. Please specify platform[s] to remove. See "platform list".'));
+    }
+    return hooks.fire('before_platform_rm', opts)
+    .then(function() {
+        targets.forEach(function(target) {
+            shell.rm('-rf', path.join(projectRoot, 'platforms', target));
+            var plugins_json = path.join(projectRoot, 'plugins', target + '.json');
+            if (fs.existsSync(plugins_json)) shell.rm(plugins_json);
+        });
+    }).then(function() {
+        return hooks.fire('after_platform_rm', opts);
+    });
+}
+
+function update(hooks, projectRoot, targets, opts) {
+    // Shell out to the update script provided by the named platform.
+    if (!targets || !targets.length) {
+        return Q.reject(new CordovaError('No platform specified. Please specify a platform to update. See "platform list".'));
+    } else if (targets.length > 1) {
+        return Q.reject(new CordovaError('Platform update can only be executed on one platform at a time.'));
+    } else {
+        var plat = targets[0];
+        var platformPath = path.join(projectRoot, 'platforms', plat);
+        var installed_platforms = cordova_util.listPlatforms(projectRoot);
+        if (installed_platforms.indexOf(plat) < 0) {
+            return Q.reject(new CordovaError('Platform "' + plat + '" is not installed. See "platform list".'));
+        }
+
+        function copyCordovaJs() {
+            var parser = new platforms[plat].parser(platformPath);
+            var platform_www = path.join(platformPath, 'platform_www');
+            shell.mkdir('-p', platform_www);
+            shell.cp('-f', path.join(parser.www_dir(), 'cordova.js'), path.join(platform_www, 'cordova.js'));
+        }
+
+        // First, lazy_load the latest version.
+        return hooks.fire('before_platform_update', opts)
+        .then(function() {
+            return lazy_load.based_on_config(projectRoot, plat);
+        }).then(function(libDir) {
+            // Call the platform's update script.
+            var script = path.join(libDir, 'bin', 'update');
+            return superspawn.spawn(script, [platformPath], { stdio: 'inherit' })
+            .then(function() {
+                // Copy the new cordova.js from www -> platform_www.
+                copyCordovaJs();
+                // Leave it to the update script to log out "updated to v FOO".
+            });
+        });
+    }
+}
+
+function check(hooks, projectRoot) {
+    var platformsText = [],
+        platforms_on_fs = cordova_util.listPlatforms(projectRoot),
+        scratch = path.join(os.tmpdir(), "cordova-platform-check-"+Date.now()),
+        listeners = events._events;
+        events._events = {};
+    var result = Q.defer();
+    cordova.raw.create(scratch)
+    .then(function () {
+        var h = new hooker(scratch);
+        // Acquire the version number of each platform we have installed, and output that too.
+        Q.all(platforms_on_fs.map(function(p) {
+            var d = Q.defer();
+            add(h, scratch, [p], {spawnoutput: {stdio: 'ignore'}})
+            .then(function() {
+                var d_avail = Q.defer(),
+                    d_cur = Q.defer();
+                getVersionFromScript(path.join(scratch, 'platforms', p, 'cordova', 'version'), null)
+                .then(function(avail) {
+                    if (!avail) {
+                        /* Platform version script was silent, we can't work with this */
+                        d_avail.resolve('');
+                    } else {
+                        d_avail.resolve(avail);
+                    }
+                })
+                .catch(function () {
+                    /* Platform version script failed, we can't work with this */
+                    d_avail.resolve('');
+                });
+                getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
+                .catch(function () {
+                    d_cur.resolve('broken');
+                }).then(function(v) {
+                    d_cur.resolve(v || '');
+                });
+                Q.all([d_avail.promise, d_cur.promise]).spread(function (avail, v) {
+                    var m;
+                    if (avail && (!v || v == 'broken' || semver.gt(avail, v))) {
+                        m = p + ' @ ' + (v || 'unknown') + ' could be updated to: ' + avail;
+                        platformsText.push(m);
+                    }
+                    d.resolve(m);
+                })
+                .catch(function () {
+                    return '?';
+                })
+                .done();
+            })
+            .catch(function () {
+                /* If a platform doesn't install, then we can't realistically suggest updating */
+                d.resolve();
+            });
+            return d.promise;
+        })).then(function() {
+            var results = '';
+            events._events = listeners;
+            shell.rm('-rf', scratch);
+            if (platformsText) {
+                results = platformsText.filter(function (p) {return !!p}).sort().join('\n');
+            }
+            if (!results) {
+                results = 'All platforms are up-to-date.';
+            }
+            events.emit('results', results);
+            result.resolve();
+        })
+        .done();
+    }).catch(function (){
+        events._events = listeners;
+        shell.rm('-rf', scratch);
+    })
+    .done();
+    return result.promise;
+}
+
+function list(hooks, projectRoot) {
+    var platforms_on_fs = cordova_util.listPlatforms(projectRoot);
+    return hooks.fire('before_platform_ls')
+    .then(function() {
+        // Acquire the version number of each platform we have installed, and output that too.
+        return Q.all(platforms_on_fs.map(function(p) {
+            return getVersionFromScript(path.join(projectRoot, 'platforms', p, 'cordova', 'version'), null)
+            .then(function(v) {
+                if (!v) return p;
+                return p + ' ' + v;
+            }, function(v) {
+                return p + ' broken';
+            });
+        }));
+    }).then(function(platformsText) {
+        var results = 'Installed platforms: ' + platformsText.sort().join(', ') + '\n';
+        var available = Object.getOwnPropertyNames(platforms).filter(function(p) {
+            var platform = platforms[p] || {},
+                hostos = platform.hostos || null;
+            if (!hostos)
+                return true;
+            if (hostos.indexOf('*') >= 0)
+                return true;
+            if (hostos.indexOf(process.platform) >= 0)
+                return true;
+            return false;
+        });
+
+        available = available.filter(function(p) {
+            return platforms_on_fs.indexOf(p) < 0; // Only those not already installed.
+        });
+        results += 'Available platforms: ' + available.sort().join(', ');
+
+        events.emit('results', results);
+    }).then(function() {
+        return hooks.fire('after_platform_ls');
+    });
+}
+
+// Returns a promise.
+module.exports = function platform(command, targets) {
+    var projectRoot = cordova_util.cdProjectRoot();
+
+    var hooks = new hooker(projectRoot);
+
+    if (arguments.length === 0) command = 'ls';
+    if (targets) {
+        if (!(targets instanceof Array)) targets = [targets];
+        var err;
+        targets.forEach(function(t) {
+            if (!(t in platforms)) {
+                err = new CordovaError('Platform "' + t + '" not recognized as a core cordova platform. See "platform list".');
+            }
+        });
+        if (err) return Q.reject(err);
+    } else {
+        if (command == 'add' || command == 'rm') {
+            return Q.reject(new CordovaError('You need to qualify `add` or `remove` with one or more platforms!'));
+        }
+    }
+
+    var opts = {
+        platforms:targets
+    };
+    switch(command) {
+        case 'add':
+            return add(hooks, projectRoot, targets, opts);
+        case 'rm':
+        case 'remove':
+            return remove(hooks, projectRoot, targets, opts);
+        case 'update':
+        case 'up':
+            return update(hooks, projectRoot, targets, opts);
+        case 'check':
+            return check(hooks, projectRoot);
+        case 'ls':
+        case 'list':
+        default:
+            return list(hooks, projectRoot);
+    }
+};
+
+/**
+ * Check Platform Support.
+ *
+ *   - {String} `name` of the platform to test.
+ *   - Returns a promise, which shows any errors.
+ *
+ */
+
+function supports(project_root, name) {
+    // required parameters
+    if (!name) return Q.reject(new CordovaError('requires a platform name parameter'));
+
+    // check if platform exists
+    var platform = platforms[name];
+    if (!platform) {
+        return Q.reject(new CordovaError(util.format('"%s" platform does not exist', name)));
+    }
+
+    // look up platform meta-data parser
+    var platformParser = platforms[name].parser;
+    if (!platformParser) {
+        return Q.reject(new Error(util.format('"%s" platform parser does not exist', name)));
+    }
+
+    // check for platform support
+    return platformParser.check_requirements(project_root);
+};
+
+// Expose the platform parsers on top of this command
+for (var p in platforms) {
+    module.exports[p] = platforms[p];
+}
+function createOverrides(projectRoot, target) {
+    shell.mkdir('-p', path.join(cordova_util.appDir(projectRoot), 'merges', target));
+};
+
+// Returns a promise.
+function call_into_create(target, projectRoot, cfg, libDir, template_dir, opts) {
+    var output = path.join(projectRoot, 'platforms', target);
+
+    // Check if output directory already exists.
+    if (fs.existsSync(output)) {
+        return Q.reject(new CordovaError('Platform ' + target + ' already added'));
+    } else {
+        // Make sure we have minimum requirements to work with specified platform
+        events.emit('verbose', 'Checking if platform "' + target + '" passes minimum requirements...');
+        /* XXX this is calling the public symbol so that Jasmine Spy can attack it */
+        return module.exports.supports(projectRoot, target)
+        .then(function() {
+            events.emit('log', 'Creating ' + target + ' project...');
+            var bin = path.join(libDir, 'bin', 'create');
+            var args = [];
+            if (target == 'android') {
+                var platformVersion = fs.readFileSync(path.join(libDir, 'VERSION'), 'UTF-8').trim();
+                if (semver.gt(platformVersion, '3.3.0')) {
+                    args.push('--cli');
+                }
+            } else if (target == 'ios') {
+                var platformVersion = fs.readFileSync(path.join(libDir, 'CordovaLib', 'VERSION'), 'UTF-8').trim();
+                args.push('--arc');
+                if (semver.gt(platformVersion, '3.3.0')) {
+                    args.push('--cli');
+                }
+            }
+
+            var pkg = cfg.packageName().replace(/[^\w.]/g,'_');
+            var name = cfg.name();
+            args.push(output, pkg, name);
+            if (template_dir) {
+                args.push(template_dir);
+            }
+            return superspawn.spawn(bin, args, opts || { stdio: 'inherit' })
+            .then(function() {
+                return require('../cordova').raw.prepare(target);
+            })
+            .then(function() {
+                createOverrides(projectRoot, target);
+                // Install all currently installed plugins into this new platform.
+                var plugins_dir = path.join(projectRoot, 'plugins');
+                var plugins = cordova_util.findPlugins(plugins_dir);
+                var parser = new platforms[target].parser(output);
+                if (!plugins) return Q();
+
+                var plugman = require('plugman');
+                // Install them serially.
+                return plugins.reduce(function(soFar, plugin) {
+                    return soFar.then(function() {
+                        events.emit('verbose', 'Installing plugin "' + plugin + '" following successful platform add of ' + target);
+                        return plugman.raw.install(target, output, path.basename(plugin), plugins_dir);
+                    });
+                }, Q());
+            });
+        });
+    }
+}
+
+module.exports.add = add;
+module.exports.remove = remove;
+module.exports.update = update;
+module.exports.check = check;
+module.exports.list = list;
+module.exports.supports = supports;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/platforms.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/platforms.js b/cordova-lib/src/cordova/platforms.js
new file mode 100644
index 0000000..5bb82f1
--- /dev/null
+++ b/cordova-lib/src/cordova/platforms.js
@@ -0,0 +1,88 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+module.exports = {
+    'ios' : {
+        hostos : ['darwin'],
+        parser : './src/metadata/ios_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ios.git',
+        version: '3.4.1'
+    }, 
+    'android' : {
+        parser : './src/metadata/android_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git',
+        version: '3.4.0'
+    }, 
+    'ubuntu' : {
+        hostos : ['linux'],
+        parser : './src/metadata/ubuntu_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ubuntu.git',
+        version: '3.4.0'
+    }, 
+     'amazon-fireos' : {
+        parser : './src/metadata/amazon_fireos_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-amazon-fireos.git',
+        version: '3.4.0'
+    },
+    'wp7' : {
+        hostos : ['win32'],
+        parser : './src/metadata/wp7_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',
+        version: '3.4.0',
+        subdirectory: 'wp7'
+    },
+    'wp8' : {
+        hostos : ['win32'],
+        parser : './src/metadata/wp8_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',
+        version: '3.4.0',
+        subdirectory: 'wp8'
+    },
+    'blackberry10' : {
+        parser : './src/metadata/blackberry10_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-blackberry.git',
+        version: '3.4.0',
+        subdirectory: 'blackberry10'
+    },
+    'www':{
+        hostos : [],
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-app-hello-world.git',
+        version: '3.4.0'
+    },
+    'firefoxos':{
+        parser: './src/metadata/firefoxos_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-firefoxos.git',
+        version: '3.4.0'
+    },
+    'windows8':{
+        hostos : ['win32'],
+        parser: './src/metadata/windows8_parser',
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-windows.git',
+        version: '3.4.0',
+        subdirectory: 'windows8'
+    }
+};
+
+var addModuleProperty = require('./src/util').addModuleProperty;
+Object.keys(module.exports).forEach(function(key) {
+    var obj = module.exports[key];
+    if (obj.parser) {
+        addModuleProperty(module, 'parser', obj.parser, false, obj);
+    }
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/plugin.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/plugin.js b/cordova-lib/src/cordova/plugin.js
new file mode 100644
index 0000000..f0e01f7
--- /dev/null
+++ b/cordova-lib/src/cordova/plugin.js
@@ -0,0 +1,210 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+// Returns a promise.
+module.exports = function plugin(command, targets, opts) {
+    var cordova_util  = require('./util'),
+        path          = require('path'),
+        hooker        = require('./hooker'),
+        config        = require('./config'),
+        Q             = require('q'),
+        CordovaError  = require('./CordovaError'),
+        events        = require('./events');
+
+    var projectRoot = cordova_util.cdProjectRoot(),
+        err;
+
+    // Dance with all the possible call signatures we've come up over the time. They can be:
+    // 1. plugin() -> list the plugins
+    // 2. plugin(command, Array of targets, maybe opts object)
+    // 3. plugin(command, target1, target2, target3 ... )
+    // The targets are not really targets, they can be a mixture of plugins and options to be passed to plugman.
+
+    command = command || 'ls';
+    targets = targets || [];
+    opts = opts || {};
+    if ( opts.length ) {
+        // This is the case with multiple targes as separate arguments and opts is not opts but another target.
+        targets = Array.prototype.slice.call(arguments, 1);
+        opts = {};
+    }
+    if ( !Array.isArray(targets) ) {
+        // This means we had a single target given as string.
+        targets = [targets];
+    }
+    opts.options = [];
+    opts.plugins = [];
+
+    var hooks = new hooker(projectRoot);
+    var platformList = cordova_util.listPlatforms(projectRoot);
+
+    // Massage plugin name(s) / path(s)
+    var pluginPath, plugins;
+    pluginPath = path.join(projectRoot, 'plugins');
+    plugins = cordova_util.findPlugins(pluginPath);
+    if (!targets || !targets.length) {
+        if (command == 'add' || command == 'rm') {
+            return Q.reject(new CordovaError('You need to qualify `add` or `remove` with one or more plugins!'));
+        } else {
+            targets = [];
+        }
+    }
+
+    //Split targets between plugins and options
+    //Assume everything after a token with a '-' is an option
+    var i;
+    for (i = 0; i < targets.length; i++) {
+        if (targets[i].match(/^-/)) {
+            opts.options = targets.slice(i);
+            break;
+        } else {
+            opts.plugins.push(targets[i]);
+        }
+    }
+
+    switch(command) {
+        case 'add':
+            if (!targets || !targets.length) {
+                return Q.reject(new CordovaError('No plugin specified. Please specify a plugin to add. See "plugin search".'));
+            }
+
+            var config_json = config(projectRoot, {});
+            var searchPath = config_json.plugin_search_path || [];
+            if (typeof opts.searchpath == 'string') {
+                searchPath = opts.searchpath.split(path.delimiter).concat(searchPath);
+            } else if (opts.searchpath) {
+                searchPath = opts.searchpath.concat(searchPath);
+            }
+            // Blank it out to appease unit tests.
+            if (searchPath.length === 0) {
+                searchPath = undefined;
+            }
+
+            return hooks.fire('before_plugin_add', opts)
+            .then(function() {
+                return opts.plugins.reduce(function(soFar, target) {
+                    var pluginsDir = path.join(projectRoot, 'plugins');
+                    return soFar.then(function() {
+                        if (target[target.length - 1] == path.sep) {
+                            target = target.substring(0, target.length - 1);
+                        }
+
+                        // Fetch the plugin first.
+                        events.emit('verbose', 'Calling plugman.fetch on plugin "' + target + '"');
+                        var plugman = require('plugman');
+                        return plugman.raw.fetch(target, pluginsDir, { searchpath: searchPath});
+                    })
+                    .then(function(dir) {
+                        // Iterate (in serial!) over all platforms in the project and install the plugin.
+                        return platformList.reduce(function(soFar, platform) {
+                            return soFar.then(function() {
+                                var platforms = require('../platforms');
+                                var platformRoot = path.join(projectRoot, 'platforms', platform),
+                                    parser = new platforms[platform].parser(platformRoot),
+                                    options = {
+                                        cli_variables: {},
+                                        searchpath: searchPath
+                                    },
+                                    tokens,
+                                    key,
+                                    i;
+                                //parse variables into cli_variables
+                                for (i=0; i< opts.options.length; i++) {
+                                    if (opts.options[i] === "--variable" && typeof opts.options[++i] === "string") {
+                                        tokens = opts.options[i].split('=');
+                                        key = tokens.shift().toUpperCase();
+                                        if (/^[\w-_]+$/.test(key)) {
+                                            options.cli_variables[key] = tokens.join('=');
+                                        }
+                                    }
+                                }
+
+                                events.emit('verbose', 'Calling plugman.install on plugin "' + dir + '" for platform "' + platform + '" with options "' + JSON.stringify(options)  + '"');
+                                return plugman.raw.install(platform, platformRoot, path.basename(dir), pluginsDir, options);
+                            });
+                        }, Q());
+                    });
+                }, Q()); // end Q.all
+            }).then(function() {
+                return hooks.fire('after_plugin_add', opts);
+            });
+            break;
+        case 'rm':
+        case 'remove':
+            if (!targets || !targets.length) {
+                return Q.reject(new CordovaError('No plugin specified. Please specify a plugin to remove. See "plugin list".'));
+            }
+            return hooks.fire('before_plugin_rm', opts)
+            .then(function() {
+                return opts.plugins.reduce(function(soFar, target) {
+                    // Check if we have the plugin.
+                    if (plugins.indexOf(target) < 0) {
+                        return Q.reject(new CordovaError('Plugin "' + target + '" is not present in the project. See "plugin list".'));
+                    }
+
+                    var targetPath = path.join(pluginPath, target);
+                    // Iterate over all installed platforms and uninstall.
+                    // If this is a web-only or dependency-only plugin, then
+                    // there may be nothing to do here except remove the
+                    // reference from the platform's plugin config JSON.
+                    var plugman = require('plugman');
+                    return platformList.reduce(function(soFar, platform) {
+                        return soFar.then(function() {
+                            var platformRoot = path.join(projectRoot, 'platforms', platform);
+                            var platforms = require('../platforms');
+                            var parser = new platforms[platform].parser(platformRoot);
+                            events.emit('verbose', 'Calling plugman.uninstall on plugin "' + target + '" for platform "' + platform + '"');
+                            return plugman.raw.uninstall.uninstallPlatform(platform, platformRoot, target, path.join(projectRoot, 'plugins'));
+                        });
+                    }, Q())
+                    .then(function() {
+                        return plugman.raw.uninstall.uninstallPlugin(target, path.join(projectRoot, 'plugins'));
+                    });
+                }, Q());
+            }).then(function() {
+                return hooks.fire('after_plugin_rm', opts);
+            });
+            break;
+        case 'search':
+            return hooks.fire('before_plugin_search')
+            .then(function() {
+                var plugman = require('plugman');
+                return plugman.raw.search(opts.plugins);
+            }).then(function(plugins) {
+                for(var plugin in plugins) {
+                    events.emit('results', plugins[plugin].name, '-', plugins[plugin].description || 'no description provided');
+                }
+            }).then(function() {
+                return hooks.fire('after_plugin_search');
+            });
+            break;
+        case 'ls':
+        case 'list':
+        default:
+            return hooks.fire('before_plugin_ls')
+            .then(function() {
+                events.emit('results', (plugins.length ? plugins : 'No plugins added. Use `cordova plugin add <plugin>`.'));
+                return hooks.fire('after_plugin_ls')
+                .then(function() {
+                    return plugins;
+                });
+            });
+            break;
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/plugin_parser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/plugin_parser.js b/cordova-lib/src/cordova/plugin_parser.js
new file mode 100644
index 0000000..d3099c0
--- /dev/null
+++ b/cordova-lib/src/cordova/plugin_parser.js
@@ -0,0 +1,30 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var xml = require('./xml-helpers'),
+    fs  = require('fs');
+
+function plugin_parser(xmlPath) {
+    this.path = xmlPath;
+    this.doc = xml.parseElementtreeSync(xmlPath);
+    this.platforms = this.doc.findall('platform').map(function(p) {
+        return p.attrib.name;
+    });
+}
+
+module.exports = plugin_parser;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/prepare.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/prepare.js b/cordova-lib/src/cordova/prepare.js
new file mode 100644
index 0000000..eef0123
--- /dev/null
+++ b/cordova-lib/src/cordova/prepare.js
@@ -0,0 +1,187 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova_util      = require('./util'),
+    ConfigParser = require('./ConfigParser'),
+    path              = require('path'),
+    platforms         = require('../platforms'),
+    platform          = require('./platform'),
+    fs                = require('fs'),
+    shell             = require('shelljs'),
+    et                = require('elementtree'),
+    hooker            = require('./hooker'),
+    lazy_load         = require('./lazy_load'),
+    events            = require('./events'),
+    Q                 = require('q'),
+    plugman           = require('plugman'),
+    util              = require('util');
+
+// Returns a promise.
+exports = module.exports = function prepare(options) {
+    var projectRoot = cordova_util.cdProjectRoot();
+
+    if (!options) {
+        options = {
+            verbose: false,
+            platforms: [],
+            options: []
+        };
+    }
+
+    options = cordova_util.preProcessOptions(options);
+
+    var xml = cordova_util.projectConfig(projectRoot);
+    var paths = options.platforms.map(function(p) {
+        var platform_path = path.join(projectRoot, 'platforms', p);
+        var parser = (new platforms[p].parser(platform_path));
+        return parser.www_dir();
+    });
+    options.paths = paths;
+
+    var hooks = new hooker(projectRoot);
+    return hooks.fire('before_prepare', options)
+    .then(function() {
+        var cfg = new ConfigParser(xml);
+
+        // Iterate over each added platform
+        return Q.all(options.platforms.map(function(platform) {
+            var platformPath = path.join(projectRoot, 'platforms', platform);
+            return lazy_load.based_on_config(projectRoot, platform)
+            .then(function(libDir) {
+                var parser = new platforms[platform].parser(platformPath),
+                    defaults_xml_path = path.join(platformPath, "cordova", "defaults.xml");
+                //If defaults.xml is present, overwrite platform config.xml with it
+                //Otherwise save whatever is there as defaults so it can be restored
+                //or copy project config into platform if none exists
+                if (fs.existsSync(defaults_xml_path)) {
+                    shell.cp("-f", defaults_xml_path, parser.config_xml());
+                    events.emit('verbose', 'Generating config.xml from defaults for platform "' + platform + '"');
+                } else {
+                    if(fs.existsSync(parser.config_xml())){
+                        shell.cp("-f", parser.config_xml(), defaults_xml_path);
+                    }else{
+                        shell.cp("-f",xml,parser.config_xml());
+                    }
+                }
+
+                var stagingPath = path.join(platformPath, '.staging');
+                if (fs.existsSync(stagingPath)) {
+                    events.emit('log', 'Deleting now-obsolete intermediate directory: ' + stagingPath);
+                    shell.rm('-rf', stagingPath);
+                }
+
+                var platform_www = path.join(platformPath, 'platform_www');
+                // Create platfom_www if project was created with older version.
+                if (!fs.existsSync(platform_www)) {
+                    shell.mkdir(platform_www);
+                    shell.cp(parser.cordovajs_path(libDir), path.join(platform_www, 'cordova.js'));
+                }
+
+                // Replace the existing web assets with the app master versions
+                parser.update_www();
+
+                // Call plugman --prepare for this platform. sets up js-modules appropriately.
+                var plugins_dir = path.join(projectRoot, 'plugins');
+                events.emit('verbose', 'Calling plugman.prepare for platform "' + platform + '"');
+                plugman.prepare(platformPath, platform, plugins_dir);
+
+                // Make sure that config changes for each existing plugin is in place
+                var munger = new plugman.config_changes.PlatformMunger(platform, platformPath, plugins_dir);
+                munger.reapply_global_munge();
+                munger.save_all();
+
+                // Update platform config.xml based on top level config.xml
+                var platform_cfg = new ConfigParser(parser.config_xml());
+                exports._mergeXml(cfg.doc.getroot(), platform_cfg.doc.getroot(), platform, true);
+                platform_cfg.write();
+
+                return parser.update_project(cfg);
+            });
+        })).then(function() {
+            return hooks.fire('after_prepare', options);
+        });
+    });
+};
+
+var BLACKLIST = ["platform"];
+var SINGLETONS = ["content", "author"];
+function mergeXml(src, dest, platform, clobber) {
+    if (BLACKLIST.indexOf(src.tag) === -1) {
+        //Handle attributes
+        Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
+            if (clobber || !dest.attrib[attribute]) {
+                dest.attrib[attribute] = src.attrib[attribute];
+            }
+        });
+        //Handle text
+        if (src.text && (clobber || !dest.text)) {
+            dest.text = src.text;
+        }
+        //Handle platform
+        if (platform) {
+            src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
+                platformElement.getchildren().forEach(mergeChild);
+            });
+        }
+
+        //Handle children
+        src.getchildren().forEach(mergeChild);
+
+        function mergeChild (srcChild) {
+            var srcTag = srcChild.tag,
+                destChild = new et.Element(srcTag),
+                foundChild,
+                query = srcTag + "",
+                shouldMerge = true;
+
+            if (BLACKLIST.indexOf(srcTag) === -1) {
+                if (SINGLETONS.indexOf(srcTag) !== -1) {
+                    foundChild = dest.find(query);
+                    if (foundChild) {
+                        destChild = foundChild;
+                        dest.remove(0, destChild);
+                    }
+                } else {
+                    //Check for an exact match and if you find one don't add
+                    Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
+                        query += "[@" + attribute + '="' + srcChild.attrib[attribute] + '"]';
+                    });
+                    foundChild = dest.find(query);
+                    if (foundChild && textMatch(srcChild, foundChild)) {
+                        destChild = foundChild;
+                        dest.remove(0, destChild);
+                        shouldMerge = false;
+                    }
+                }
+
+                mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
+                dest.append(destChild);
+            }
+        }
+
+        function textMatch(elm1, elm2) {
+            var text1 = elm1.text ? elm1.text.replace(/\s+/, "") : "",
+                text2 = elm2.text ? elm2.text.replace(/\s+/, "") : "";
+            return (text1 === "" || text1 === text2);
+        }
+    }
+}
+
+// Expose for testing.
+exports._mergeXml = mergeXml;
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/run.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/run.js b/cordova-lib/src/cordova/run.js
new file mode 100644
index 0000000..5de3031
--- /dev/null
+++ b/cordova-lib/src/cordova/run.js
@@ -0,0 +1,48 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+/*global require: true, module: true, process: true*/
+/*jslint sloppy: true, white: true, newcap: true */
+
+var cordova_util      = require('./util'),
+    path              = require('path'),
+    hooker            = require('./hooker'),
+    superspawn        = require('./superspawn'),
+    Q                 = require('q');
+
+// Returns a promise.
+module.exports = function run(options) {
+    var projectRoot = cordova_util.cdProjectRoot(),
+    options = cordova_util.preProcessOptions(options);
+
+    var hooks = new hooker(projectRoot);
+    return hooks.fire('before_run', options)
+    .then(function() {
+        // Run a prepare first, then shell out to run
+        return require('../cordova').raw.prepare(options.platforms)
+    }).then(function() {
+        // Deploy in parallel (output gets intermixed though...)
+        return Q.all(options.platforms.map(function(platform) {
+            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'run');
+            return superspawn.spawn(cmd, options.options, { printCommand: true, stdio: 'inherit' });
+        }));
+    }).then(function() {
+        return hooks.fire('after_run', options);
+    });
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/serve.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/serve.js b/cordova-lib/src/cordova/serve.js
new file mode 100644
index 0000000..bd17fa3
--- /dev/null
+++ b/cordova-lib/src/cordova/serve.js
@@ -0,0 +1,224 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova_util = require('./util'),
+    crypto = require('crypto'),
+    path = require('path'),
+    shell = require('shelljs'),
+    platforms     = require('../platforms'),
+    ConfigParser = require('./ConfigParser'),
+    hooker        = require('./hooker'),
+    fs = require('fs'),
+    http = require("http"),
+    url = require("url"),
+    mime = require("mime"),
+    zlib = require("zlib");
+
+function launchServer(projectRoot, port) {
+    var server = http.createServer(function(request, response) {
+        function do404() {
+            console.log('404 ' + request.url);
+            response.writeHead(404, {"Content-Type": "text/plain"});
+            response.write("404 Not Found\n");
+            response.end();
+        }
+        function do302(where) {
+            console.log('302 ' + request.url);
+            response.setHeader("Location", where);
+            response.writeHead(302, {"Content-Type": "text/plain"});
+            response.end();
+        }
+        function doRoot() {
+            response.writeHead(200, {"Content-Type": "text/html"});
+            var config = new ConfigParser(cordova_util.projectConfig(projectRoot));
+            response.write("<html><head><title>"+config.name()+"</title></head><body>");
+            response.write("<table border cellspacing=0><thead><caption><h3>Package Metadata</h3></caption></thead><tbody>");
+            for (var c in {"name": true, "packageName": true, "version": true}) {
+                response.write("<tr><th>"+c+"</th><td>"+config[c]()+"</td></tr>");
+            }
+            response.write("</tbody></table>");
+            response.write("<h3>Platforms</h3><ul>");
+            var installed_platforms = cordova_util.listPlatforms(projectRoot);
+            for (var p in platforms) {
+                if (installed_platforms.indexOf(p) >= 0) {
+                    response.write("<li><a href='"+p+"/'>"+p+"</a></li>\n");
+                } else {
+                    response.write("<li><em>"+p+"</em></li>\n");
+                }
+            }
+            response.write("</ul>");
+            response.write("<h3>Plugins</h3><ul>");
+            var pluginPath = path.join(projectRoot, 'plugins');
+            var plugins = cordova_util.findPlugins(pluginPath);
+            for (var p in plugins) {
+                response.write("<li>"+plugins[p]+"</li>\n");
+            }
+            response.write("</ul>");
+            response.write("</body></html>");
+            response.end();
+        }
+        var urlPath = url.parse(request.url).pathname;
+        var firstSegment = /\/(.*?)\//.exec(urlPath);
+        if (!firstSegment) {
+            return doRoot();
+        }
+        var platformId = firstSegment[1];
+        if (!platforms[platformId]) {
+            return do404();
+        }
+        // Strip the platform out of the path.
+        urlPath = urlPath.slice(platformId.length + 1);
+
+        try {
+            var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
+        } catch (e) {
+            return do404();
+        }
+        var filePath = null;
+
+        if (urlPath == '/config.xml') {
+            filePath = parser.config_xml();
+        } else if (urlPath == '/project.json') {
+            processAddRequest(request, response, platformId, projectRoot);
+            return;
+        } else if (/^\/www\//.test(urlPath)) {
+            filePath = path.join(parser.www_dir(), urlPath.slice(5));
+        } else if (/^\/+[^\/]*$/.test(urlPath)) {
+            return do302("/" + platformId + "/www/");
+        } else {
+            return do404();
+        }
+
+        fs.exists(filePath, function(exists) {
+            if (exists) {
+                if (fs.statSync(filePath).isDirectory()) {
+                    index = path.join(filePath, "index.html");
+                    try {
+                        if (fs.statSync(index)) {
+                            filePath = index;
+                        }
+                    } catch (e) {}
+                }
+                if (fs.statSync(filePath).isDirectory()) {
+                    if (!/\/$/.test(urlPath)) {
+                        return do302("/" + platformId + urlPath + "/");
+                    }
+                    console.log('200 ' + request.url);
+                    response.writeHead(200, {"Content-Type": "text/html"});
+                    response.write("<html><head><title>Directory listing of "+ urlPath + "</title></head>");
+                    response.write("<h3>Items in this directory</h3>");
+                    var items = fs.readdirSync(filePath);
+                    response.write("<ul>");
+                    for (var i in items) {
+                        var file = items[i];
+                        if (file) {
+                            response.write('<li><a href="'+file+'">'+file+'</a></li>\n');
+                        }
+                    }
+                    response.write("</ul>");
+                    response.end();
+                } else {
+                    var mimeType = mime.lookup(filePath);
+                    var respHeaders = {
+                      'Content-Type': mimeType
+                    };
+                    var readStream = fs.createReadStream(filePath);
+
+                    var acceptEncoding = request.headers['accept-encoding'] || '';
+                    if (acceptEncoding.match(/\bgzip\b/)) {
+                        respHeaders['content-encoding'] = 'gzip';
+                        readStream = readStream.pipe(zlib.createGzip());
+                    } else if (acceptEncoding.match(/\bdeflate\b/)) {
+                        respHeaders['content-encoding'] = 'deflate';
+                        readStream = readStream.pipe(zlib.createDeflate());
+                    }
+                    console.log('200 ' + request.url);
+                    response.writeHead(200, respHeaders);
+                    readStream.pipe(response);
+                }
+            } else {
+                return do404();
+            }
+        });
+    }).on('listening', function () {
+        console.log("Static file server running on port " + port + " (i.e. http://localhost:" + port + ")\nCTRL + C to shut down");
+    }).on('error', function (e) {
+        if (e && e.toString().indexOf('EADDRINUSE') !== -1) {
+            port++;
+            server.listen(port);
+        } else {
+            console.log("An error occured starting static file server: " + e);
+        }
+    }).listen(port);
+    return server;
+}
+
+function calculateMd5(fileName) {
+    var BUF_LENGTH = 64*1024,
+        buf = new Buffer(BUF_LENGTH),
+        bytesRead = BUF_LENGTH,
+        pos = 0,
+        fdr = fs.openSync(fileName, 'r');
+
+    try {
+        var md5sum = crypto.createHash('md5');
+        while (bytesRead === BUF_LENGTH) {
+            bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
+            pos += bytesRead;
+            md5sum.update(buf.slice(0, bytesRead));
+        }
+    } finally {
+        fs.closeSync(fdr);
+    }
+    return md5sum.digest('hex');
+}
+
+function processAddRequest(request, response, platformId, projectRoot) {
+    var parser = new platforms[platformId].parser(path.join(projectRoot, 'platforms', platformId));
+    var wwwDir = parser.www_dir();
+    var payload = {
+        'configPath': '/' + platformId + '/config.xml',
+        'wwwPath': '/' + platformId + '/www',
+        'wwwFileList': shell.find(wwwDir)
+            .filter(function(a) { return !fs.statSync(a).isDirectory() && !/(^\.)|(\/\.)/.test(a) })
+            .map(function(a) { return {'path': a.slice(wwwDir.length), 'etag': '' + calculateMd5(a)}; })
+    };
+    console.log('200 ' + request.url);
+    response.writeHead(200, {
+        'Content-Type': 'application/json',
+        'Cache-Control': 'no-cache'
+    });
+    response.write(JSON.stringify(payload));
+    response.end();
+}
+
+module.exports = function server(port) {
+    var projectRoot = cordova_util.cdProjectRoot();
+    port = +port || 8000;
+
+    var hooks = new hooker(projectRoot);
+    return hooks.fire('before_serve')
+    .then(function() {
+        // Run a prepare first!
+        return require('../cordova').raw.prepare([]);
+    }).then(function() {
+        launchServer(projectRoot, port);
+        return hooks.fire('after_serve');
+    });
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/superspawn.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/superspawn.js b/cordova-lib/src/cordova/superspawn.js
new file mode 100644
index 0000000..60c9fdc
--- /dev/null
+++ b/cordova-lib/src/cordova/superspawn.js
@@ -0,0 +1,139 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var child_process = require('child_process');
+var fs = require('fs');
+var path = require('path');
+var _ = require('underscore');
+var Q = require('q');
+var shell = require('shelljs');
+var events = require('./events');
+var iswin32 = process.platform == 'win32';
+
+// On Windows, spawn() for batch files requires absolute path & having the extension.
+function resolveWindowsExe(cmd) {
+    var winExtensions = ['.exe', '.cmd', '.bat', '.js', '.vbs'];
+    function isValidExe(c) {
+        return winExtensions.indexOf(path.extname(c)) !== -1 && fs.existsSync(c);
+    }
+    if (isValidExe(cmd)) {
+        return cmd;
+    }
+    cmd = shell.which(cmd) || cmd;
+    if (!isValidExe(cmd)) {
+        winExtensions.some(function(ext) {
+            if (fs.existsSync(cmd + ext)) {
+                cmd = cmd + ext;
+                return true;
+            }
+        });
+    }
+    return cmd;
+}
+
+function maybeQuote(a) {
+    if (a.indexOf(' ') != -1) {
+        a = '"' + a + '"';
+    }
+    return a;
+}
+
+// opts:
+//   printCommand: Whether to log the command (default: false)
+//   stdio: 'default' is to capture output and returning it as a string to success (same as exec)
+//          'ignore' means don't bother capturing it
+//          'inherit' means pipe the input & output. This is required for anything that prompts.
+//   env: Map of extra environment variables.
+//   cwd: Working directory for the command.
+// Returns a promise that succeeds only for return code = 0.
+exports.spawn = function(cmd, args, opts) {
+    args = args || [];
+    opts = opts || {};
+    var spawnOpts = {};
+    var d = Q.defer();
+
+    if (iswin32) {
+        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' && cmd.indexOf(' ') != -1) {
+            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
+            args = [['/s', '/c', '"'+[cmd].concat(args).map(function(a){if (/^[^"].* .*[^"]/.test(a)) return '"'+a+'"'; return a;}).join(" ")+'"'].join(" ")];
+            cmd = 'cmd';
+            spawnOpts.windowsVerbatimArguments = true;
+        } else if (!fs.existsSync(cmd)) {
+            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
+            args = ['/s', '/c', cmd].concat(args);
+        }
+    }
+
+    if (opts.stdio == 'ignore') {
+        spawnOpts.stdio = 'ignore';
+    } else if (opts.stdio == 'inherit') {
+        spawnOpts.stdio = 'inherit';
+    }
+    if (opts.cwd) {
+        spawnOpts.cwd = opts.cwd;
+    }
+    if (opts.env) {
+        spawnOpts.env = _.extend(_.extend({}, process.env), opts.env);
+    }
+
+    events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' '));
+
+    var child = child_process.spawn(cmd, args, spawnOpts);
+    var capturedOut = '';
+    var capturedErr = '';
+
+    if (child.stdout) {
+        child.stdout.setEncoding('utf8');
+        child.stdout.on('data', function(data) {
+            capturedOut += data;
+        });
+
+        child.stderr.setEncoding('utf8');
+        child.stderr.on('data', function(data) {
+            capturedErr += data;
+        });
+    }
+
+    child.on('close', whenDone);
+    child.on('error', whenDone);
+    function whenDone(arg) {
+        child.removeListener('close', whenDone);
+        child.removeListener('error', whenDone);
+        var code = typeof arg == 'number' ? arg : arg && arg.code;
+
+        events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args);
+        if (code === 0) {
+            d.resolve(capturedOut.trim());
+        } else {
+            var errMsg = cmd + ': Command failed with exit code ' + code;
+            if (capturedErr) {
+                errMsg += ' Error output:\n' + capturedErr.trim();
+            }
+            var err = new Error(errMsg);
+            err.code = code;
+            d.reject(err);
+        }
+    }
+
+    return d.promise;
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/util.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/util.js b/cordova-lib/src/cordova/util.js
new file mode 100644
index 0000000..2d3b12a
--- /dev/null
+++ b/cordova-lib/src/cordova/util.js
@@ -0,0 +1,214 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var fs            = require('fs'),
+    path          = require('path'),
+    CordovaError  = require('./CordovaError'),
+    shell         = require('shelljs');
+
+// Global configuration paths
+var HOME = process.env[(process.platform.slice(0, 3) == 'win') ? 'USERPROFILE' : 'HOME'];
+var global_config_path = path.join(HOME, '.cordova');
+var lib_path = path.join(global_config_path, 'lib');
+shell.mkdir('-p', lib_path);
+
+function isRootDir(dir) {
+    if (fs.existsSync(path.join(dir, 'www'))) {
+        if (fs.existsSync(path.join(dir, 'config.xml'))) {
+            // For sure is.
+            if (fs.existsSync(path.join(dir, 'platforms'))) {
+                return 2;
+            } else {
+                return 1;
+            }
+        }
+        // Might be (or may be under platforms/).
+        if (fs.existsSync(path.join(dir, 'www', 'config.xml'))) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+exports = module.exports = {
+    globalConfig:global_config_path,
+    libDirectory:lib_path,
+    // 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.
+    isCordova: 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) {
+                return this.isCordova(pwd) || this.isCordova(cwd);
+            }
+            return this.isCordova(cwd);
+        }
+        var bestReturnValueSoFar = false;
+        for (var i = 0; i < 1000; ++i) {
+            var result = isRootDir(dir);
+            if (result === 2) {
+                return dir;
+            }
+            if (result === 1) {
+                bestReturnValueSoFar = dir;
+            }
+            var parentDir = path.normalize(path.join(dir, '..'));
+            // Detect fs root.
+            if (parentDir == dir) {
+                return bestReturnValueSoFar;
+            }
+            dir = parentDir;
+        }
+        console.error('Hit an unhandled case in util.isCordova');
+        return false;
+    },
+    // Cd to project root dir and return its path. Throw CordovaError if not in a Corodva project.
+    cdProjectRoot: function() {
+        var projectRoot = this.isCordova();
+        if (!projectRoot) {
+            throw new CordovaError('Current working directory is not a Cordova-based project.');
+        }
+        process.chdir(projectRoot);
+        return projectRoot;
+    },
+    // Recursively deletes .svn folders from a target path
+    deleteSvnFolders:function(dir) {
+        var contents = fs.readdirSync(dir);
+        contents.forEach(function(entry) {
+            var fullpath = path.join(dir, entry);
+            if (fs.statSync(fullpath).isDirectory()) {
+                if (entry == '.svn') {
+                    shell.rm('-rf', fullpath);
+                } else module.exports.deleteSvnFolders(fullpath);
+            }
+        });
+    },
+    listPlatforms:function(project_dir) {
+        var core_platforms = require('../platforms');
+        var platforms_dir = path.join(project_dir, 'platforms');
+        if ( !fs.existsSync(platforms_dir)) {
+            return [];
+        }
+        var subdirs = fs.readdirSync(platforms_dir);
+        return subdirs.filter(function(p) {
+            return Object.keys(core_platforms).indexOf(p) > -1;
+        });
+    },
+    // list the directories in the path, ignoring any files
+    findPlugins:function(pluginPath) {
+        var plugins = [],
+            stats;
+
+        if (fs.existsSync(pluginPath)) {
+            plugins = fs.readdirSync(pluginPath).filter(function (fileName) {
+               stats = fs.statSync(path.join(pluginPath, fileName));
+               return fileName != '.svn' && fileName != 'CVS' && stats.isDirectory();
+            });
+        }
+
+        return plugins;
+    },
+    appDir: function(projectDir) {
+        return projectDir;
+    },
+    projectWww: function(projectDir) {
+        return path.join(projectDir, 'www');
+    },
+    projectConfig: function(projectDir) {
+        var rootPath = path.join(projectDir, 'config.xml');
+        var wwwPath = path.join(projectDir, 'www', 'config.xml');
+        if (fs.existsSync(rootPath)) {
+            return rootPath;
+        } else if (fs.existsSync(wwwPath)) {
+            return wwwPath;
+        }
+        return rootPath;
+    },
+    preProcessOptions: function (inputOptions) {
+        /**
+         * Current Desired Arguments
+         * options: {verbose: boolean, platforms: [String], options: [String]}
+         * Accepted Arguments
+         * platformList: [String] -- assume just a list of platforms
+         * platform: String -- assume this is a platform
+         */
+        var result = inputOptions || {};
+        if (Array.isArray(inputOptions)) {
+            result = { platforms: inputOptions };
+        } else if (typeof inputOptions === 'string') {
+            result = { platforms: [inputOptions] };
+        }
+        result.verbose = result.verbose || false;
+        result.platforms = result.platforms || [];
+        result.options = result.options || [];
+
+        var projectRoot = this.isCordova();
+
+        if (!projectRoot) {
+            throw new CordovaError('Current working directory is not a Cordova-based project.');
+        }
+        var projectPlatforms = this.listPlatforms(projectRoot);
+        if (projectPlatforms.length === 0) {
+            throw new CordovaError('No platforms added to this project. Please use `cordova platform add <platform>`.');
+        }
+        if (result.platforms.length === 0) {
+            result.platforms = projectPlatforms;
+        }
+
+        return result;
+    }
+};
+
+// opt_wrap is a boolean: True means that a callback-based wrapper for the promise-based function
+// should be created.
+function addModuleProperty(module, symbol, modulePath, opt_wrap, opt_obj) {
+    var val = null;
+    if (opt_wrap) {
+        module.exports[symbol] = function() {
+            val = val || module.require(modulePath);
+            if (arguments.length && typeof arguments[arguments.length - 1] === 'function') {
+                // If args exist and the last one is a function, it's the callback.
+                var args = Array.prototype.slice.call(arguments);
+                var cb = args.pop();
+                val.apply(module.exports, args).done(function(result) {cb(undefined, result)}, cb);
+            } else {
+                val.apply(module.exports, arguments).done(null, function(err) { throw err; });
+            }
+        };
+    } else {
+        Object.defineProperty(opt_obj || module.exports, symbol, {
+            get : function() { return val = val || module.require(modulePath); },
+            set : function(v) { val = v; }
+        });
+    }
+
+    // Add the module.raw.foo as well.
+    if(module.exports.raw) {
+        Object.defineProperty(module.exports.raw, symbol, {
+            get : function() { return val = val || module.require(modulePath); },
+            set : function(v) { val = v; }
+        });
+    }
+}
+
+addModuleProperty(module, 'plugin_parser', './plugin_parser');
+
+exports.addModuleProperty = addModuleProperty;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/xml-helpers.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/xml-helpers.js b/cordova-lib/src/cordova/xml-helpers.js
new file mode 100644
index 0000000..70ec96b
--- /dev/null
+++ b/cordova-lib/src/cordova/xml-helpers.js
@@ -0,0 +1,171 @@
+/*
+ *
+ * Copyright 2013 Anis Kadri
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/**
+ * contains XML utility functions, some of which are specific to elementtree
+ */
+
+var fs = require('fs')
+  , path = require('path')
+  , et = require('elementtree');
+
+module.exports = {
+    // Returns a promise.
+    moveProjFile: function(origFile, projPath) {
+        var src = path.resolve(projPath, origFile)
+          , dest = src.replace('.orig', '');
+
+        var d = Q.defer();
+        fs.createReadStream(src)
+            .pipe(fs.createWriteStream(dest))
+            .on('close', d.resolve)
+            .on('error', d.reject);
+        return d.promise;
+    },
+
+    // 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) {
+            return false;
+        } else if (one.text.trim() != two.text.trim()) {
+            return false;
+        } else if (one._children.length != two._children.length) {
+            return false;
+        }
+
+        var oneAttribKeys = Object.keys(one.attrib),
+            twoAttribKeys = Object.keys(two.attrib),
+            i = 0, attribName;
+
+        if (oneAttribKeys.length != twoAttribKeys.length) {
+            return false;
+        }
+
+        for (i; i < oneAttribKeys.length; i++) {
+            attribName = oneAttribKeys[i];
+
+            if (one.attrib[attribName] != two.attrib[attribName]) {
+                return false;
+            }
+        }
+
+        for (i; i < one._children.length; i++) {
+            if (!module.exports.equalNodes(one._children[i], two._children[i])) {
+                return false;
+            }
+        }
+
+        return true;
+    },
+
+    // adds node to doc at selector
+    graftXML: function(doc, nodes, selector) {
+        var parent = resolveParent(doc, selector);
+        if (!parent) return false;
+
+        nodes.forEach(function (node) {
+            // check if child is unique first
+            if (uniqueChild(node, parent)) {
+                parent.append(node);
+            }
+        });
+
+        return true;
+    },
+
+    // removes node from doc at selector
+    pruneXML: function(doc, nodes, selector) {
+        var parent = resolveParent(doc, selector);
+        if (!parent) return false;
+
+        nodes.forEach(function (node) {
+            var matchingKid = null;
+            if ((matchingKid = findChild(node, parent)) != null) {
+                // stupid elementtree takes an index argument it doesn't use
+                // and does not conform to the python lib
+                parent.remove(0, matchingKid);
+            }
+        });
+
+        return true;
+    },
+
+    parseElementtreeSync: function (filename) {
+        var contents = fs.readFileSync(filename, 'utf-8');
+        if(contents) {
+            contents = contents.substring(contents.indexOf("<")); //Windows is the BOM
+        }
+        return new et.ElementTree(et.XML(contents));
+    }
+};
+
+function findChild(node, parent) {
+    var matchingKids = parent.findall(node.tag)
+      , i, j;
+
+    for (i = 0, j = matchingKids.length ; i < j ; i++) {
+        if (module.exports.equalNodes(node, matchingKids[i])) {
+            return matchingKids[i];
+        }
+    }
+    return null;
+}
+
+function uniqueChild(node, parent) {
+    var matchingKids = parent.findall(node.tag)
+      , i = 0;
+
+    if (matchingKids.length == 0) {
+        return true;
+    } else  {
+        for (i; i < matchingKids.length; i++) {
+            if (module.exports.equalNodes(node, matchingKids[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+
+var ROOT = /^\/([^\/]*)/,
+    ABSOLUTE = /^\/([^\/]*)\/(.*)/;
+function resolveParent(doc, selector) {
+    var parent, tagName, subSelector;
+
+    // handle absolute selector (which elementtree doesn't like)
+    if (ROOT.test(selector)) {
+        tagName = selector.match(ROOT)[1];
+        // test for wildcard "any-tag" root selector
+        if (tagName == '*' || tagName === doc._root.tag) {
+            parent = doc._root;
+
+            // could be an absolute path, but not selecting the root
+            if (ABSOLUTE.test(selector)) {
+                subSelector = selector.match(ABSOLUTE)[2];
+                parent = parent.find(subSelector)
+            }
+        } else {
+            return false;
+        }
+    } else {
+        parent = doc.find(selector)
+    }
+    return parent;
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/templates/config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/templates/config.xml b/cordova-lib/templates/config.xml
new file mode 100644
index 0000000..4a9a4d8
--- /dev/null
+++ b/cordova-lib/templates/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns     = "http://www.w3.org/ns/widgets"
+        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
+        id        = "io.cordova.hellocordova"
+        version   = "0.0.1">
+    <name>Hello Cordova</name>
+
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+
+    <author href="http://cordova.io" email="dev@cordova.apache.org">
+        Apache Cordova Team
+    </author>
+
+    <content src="index.html" />
+
+    <access origin="*" />
+</widget>


[03/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/plugin_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/plugin_parser.spec.js b/spec/plugin_parser.spec.js
deleted file mode 100644
index 9a63154..0000000
--- a/spec/plugin_parser.spec.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    path = require('path'),
-    fs = require('fs'),
-    plugin_parser = require('../src/plugin_parser'),
-    et = require('elementtree'),
-    xml = path.join(__dirname, 'fixtures', 'plugins', 'test', 'plugin.xml');
-
-var xml_contents = fs.readFileSync(xml, 'utf-8');
-
-describe('plugin.xml parser', function () {
-    var readfile;
-    beforeEach(function() {
-        readfile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
-    });
-
-    it('should read a proper plugin.xml file', function() {
-        var cfg;
-        expect(function () {
-            cfg = new plugin_parser(xml);
-        }).not.toThrow();
-        expect(cfg).toBeDefined();
-        expect(cfg.doc).toBeDefined();
-    });
-    it('should be able to figure out which platforms the plugin supports', function() {
-        var cfg = new plugin_parser(xml);
-        expect(cfg.platforms.length).toBe(1);
-        expect(cfg.platforms.indexOf('ios') > -1).toBe(true);
-    });
-});
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/prepare.spec.js
----------------------------------------------------------------------
diff --git a/spec/prepare.spec.js b/spec/prepare.spec.js
deleted file mode 100644
index eac225d..0000000
--- a/spec/prepare.spec.js
+++ /dev/null
@@ -1,290 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    shell = require('shelljs'),
-    plugman = require('plugman'),
-    path = require('path'),
-    fs = require('fs'),
-    util = require('../src/util'),
-    prepare = require('../src/prepare'),
-    lazy_load = require('../src/lazy_load'),
-    ConfigParser = require('../src/ConfigParser'),
-    platforms = require('../platforms'),
-    hooker = require('../src/hooker'),
-    xmlHelpers = require('../src/xml-helpers'),
-    fixtures = path.join(__dirname, 'fixtures'),
-    et = require('elementtree'),
-    Q = require('q'),
-    hooks = path.join(fixtures, 'hooks');
-
-var project_dir = '/some/path';
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-var supported_platforms_paths = supported_platforms.map(function(p) { return path.join(project_dir, 'platforms', p, 'www'); });
-
-var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
-    '<widget xmlns     = "http://www.w3.org/ns/widgets"\n' +
-    '        xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
-    '        id        = "io.cordova.hellocordova"\n' +
-    '        version   = "0.0.1">\n' +
-    '    <name>Hello Cordova</name>\n' +
-    '    <description>\n' +
-    '        A sample Apache Cordova application that responds to the deviceready event.\n' +
-    '    </description>\n' +
-    '    <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
-    '        Apache Cordova Team\n' +
-    '    </author>\n' +
-    '    <content src="index.html" />\n' +
-    '    <access origin="*" />\n' +
-    '    <preference name="fullscreen" value="true" />\n' +
-    '    <preference name="webviewbounce" value="true" />\n' +
-    '</widget>\n';
-
-describe('prepare command', function() {
-    var is_cordova,
-        cd_project_root,
-        list_platforms,
-        fire,
-        parsers = {},
-        plugman_prepare,
-        find_plugins,
-        plugman_get_json,
-        cp,
-        mkdir,
-        load;
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        supported_platforms.forEach(function(p) {
-            parsers[p] = jasmine.createSpy(p + ' update_project').andReturn(Q());
-            spyOn(platforms[p], 'parser').andReturn({
-                update_project:parsers[p],
-                update_www: jasmine.createSpy(p + ' update_www'),
-                cordovajs_path: function(libDir) { return 'path/to/cordova.js/in/.cordova/lib';},
-                www_dir:function() { return path.join(project_dir, 'platforms', p, 'www'); },
-                config_xml: function () { return path.join(project_dir, "platforms", p, "www", "config.xml");}
-            });
-        });
-        plugman_prepare = spyOn(plugman, 'prepare').andReturn(Q());
-        find_plugins = spyOn(util, 'findPlugins').andReturn([]);
-        plugman_get_json = spyOn(plugman.config_changes, 'get_platform_json').andReturn({
-            prepare_queue:{installed:[], uninstalled:[]},
-            config_munge:{},
-            installed_plugins:{},
-            dependent_plugins:{}
-        });
-        load = spyOn(lazy_load, 'based_on_config').andReturn(Q());
-        cp = spyOn(shell, 'cp').andReturn(true);
-        mkdir = spyOn(shell, 'mkdir');
-        spyOn(prepare, '_mergeXml');
-        spyOn(ConfigParser.prototype, 'write');
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function() {
-            return new et.ElementTree(et.XML(TEST_XML));
-        });
-    });
-
-    describe('failure', function() {
-        it('should not run outside of a cordova-based project by calling util.isCordova', function(done) {
-            is_cordova.andReturn(false);
-            Q().then(prepare).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect('' + err).toContain('Current working directory is not a Cordova-based project.');
-            }).fin(done);
-        });
-        it('should not run inside a cordova-based project with no platforms', function(done) {
-            list_platforms.andReturn([]);
-            Q().then(prepare).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect('' + err).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            }).fin(done);
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project by calling util.isCordova', function(done) {
-            prepare().then(function() {
-                expect(is_cordova).toHaveBeenCalled();
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should invoke each platform\'s parser\'s update_project method', function(done) {
-            prepare().then(function() {
-                supported_platforms.forEach(function(p) {
-                    expect(parsers[p]).toHaveBeenCalled();
-                });
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should invoke lazy_load for each platform to make sure platform libraries are loaded', function(done) {
-            prepare().then(function() {
-                supported_platforms.forEach(function(p) {
-                    expect(load).toHaveBeenCalledWith(project_dir, p);
-                });
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        describe('plugman integration', function() {
-            it('should invoke plugman.prepare after update_project', function(done) {
-                prepare().then(function() {
-                    var plugins_dir = path.join(project_dir, 'plugins');
-                    supported_platforms.forEach(function(p) {
-                        var platform_path = path.join(project_dir, 'platforms', p);
-                        expect(plugman_prepare).toHaveBeenCalledWith(platform_path, (p=='blackberry'?'blackberry10':p), plugins_dir);
-                    });
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module, and pass in platforms and paths as data object', function(done) {
-                prepare().then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_prepare', {verbose: false, platforms:supported_platforms, options: [], paths:supported_platforms_paths});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-            it('should fire after hooks through the hooker module, and pass in platforms and paths as data object', function(done) {
-                prepare('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_prepare', {verbose: false, platforms:['android'], options: [], paths:[path.join(project_dir, 'platforms', 'android', 'www')]});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-
-        describe('with no platforms added', function() {
-            beforeEach(function() {
-                list_platforms.andReturn([]);
-            });
-            it('should not fire the hooker', function(done) {
-                Q().then(prepare).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(err).toEqual(jasmine.any(Error));
-                    expect(fire).not.toHaveBeenCalledWith('before_prepare');
-                    expect(fire).not.toHaveBeenCalledWith('after_prepare');
-                }).fin(done);
-            });
-        });
-    });
-});
-
-describe('prepare._mergeXml', function () {
-    var dstXml;
-    beforeEach(function() {
-        dstXml = et.XML(TEST_XML);
-    });
-    it("should merge attributes and text of the root element without clobbering", function () {
-        var testXml = et.XML("<widget foo='bar' id='NOTANID'>TEXT</widget>");
-        prepare._mergeXml(testXml, dstXml);
-        expect(dstXml.attrib.foo).toEqual("bar");
-        expect(dstXml.attrib.id).not.toEqual("NOTANID");
-        expect(dstXml.text).not.toEqual("TEXT");
-    });
-
-    it("should merge attributes and text of the root element with clobbering", function () {
-        var testXml = et.XML("<widget foo='bar' id='NOTANID'>TEXT</widget>");
-        prepare._mergeXml(testXml, dstXml, "foo", true);
-        expect(dstXml.attrib.foo).toEqual("bar");
-        expect(dstXml.attrib.id).toEqual("NOTANID");
-        expect(dstXml.text).toEqual("TEXT");
-    });
-
-    it("should not merge platform tags with the wrong platform", function () {
-        var testXml = et.XML("<widget><platform name='bar'><testElement testAttrib='value'>testTEXT</testElement></platform></widget>"),
-            origCfg = et.tostring(dstXml);
-
-        prepare._mergeXml(testXml, dstXml, "foo", true);
-        expect(et.tostring(dstXml)).toEqual(origCfg);
-    });
-
-    it("should merge platform tags with the correct platform", function () {
-        var testXml = et.XML("<widget><platform name='bar'><testElement testAttrib='value'>testTEXT</testElement></platform></widget>"),
-            origCfg = et.tostring(dstXml);
-
-        prepare._mergeXml(testXml, dstXml, "bar", true);
-        expect(et.tostring(dstXml)).not.toEqual(origCfg);
-        var testElement = dstXml.find("testElement");
-        expect(testElement).toBeDefined();
-        expect(testElement.attrib.testAttrib).toEqual("value");
-        expect(testElement.text).toEqual("testTEXT");
-    });
-
-    it("should merge singelton children without clobber", function () {
-        var testXml = et.XML("<widget><author testAttrib='value' href='http://www.nowhere.com'>SUPER_AUTHOR</author></widget>");
-
-        prepare._mergeXml(testXml, dstXml);
-        var testElements = dstXml.findall("author");
-        expect(testElements).toBeDefined();
-        expect(testElements.length).toEqual(1);
-        expect(testElements[0].attrib.testAttrib).toEqual("value");
-        expect(testElements[0].attrib.href).toEqual("http://cordova.io");
-        expect(testElements[0].attrib.email).toEqual("dev@cordova.apache.org");
-        expect(testElements[0].text).toContain("Apache Cordova Team");
-    });
-
-    it("should clobber singelton children with clobber", function () {
-        var testXml = et.XML("<widget><author testAttrib='value' href='http://www.nowhere.com'>SUPER_AUTHOR</author></widget>");
-
-        prepare._mergeXml(testXml, dstXml, '', true);
-        var testElements = dstXml.findall("author");
-        expect(testElements).toBeDefined();
-        expect(testElements.length).toEqual(1);
-        expect(testElements[0].attrib.testAttrib).toEqual("value");
-        expect(testElements[0].attrib.href).toEqual("http://www.nowhere.com");
-        expect(testElements[0].attrib.email).toEqual("dev@cordova.apache.org");
-        expect(testElements[0].text).toEqual("SUPER_AUTHOR");
-    });
-
-    it("should append non singelton children", function () {
-        var testXml = et.XML("<widget><preference num='1'/> <preference num='2'/></widget>");
-
-        prepare._mergeXml(testXml, dstXml, '', true);
-        var testElements = dstXml.findall("preference");
-        expect(testElements.length).toEqual(4);
-    });
-
-    it("should handle namespaced elements", function () {
-        var testXml = et.XML("<widget><foo:bar testAttrib='value'>testText</foo:bar></widget>");
-
-        prepare._mergeXml(testXml, dstXml, 'foo', true);
-        var testElement = dstXml.find("foo:bar");
-        expect(testElement).toBeDefined();
-        expect(testElement.attrib.testAttrib).toEqual("value");
-        expect(testElement.text).toEqual("testText");
-    });
-
-    it("should not append duplicate non singelton children", function () {
-        var testXml = et.XML("<widget><preference name='fullscreen' value='true'/></widget>");
-
-        prepare._mergeXml(testXml, dstXml, '', true);
-        var testElements = dstXml.findall("preference");
-        expect(testElements.length).toEqual(2);
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/run.spec.js
----------------------------------------------------------------------
diff --git a/spec/run.spec.js b/spec/run.spec.js
deleted file mode 100644
index bfaf3f8..0000000
--- a/spec/run.spec.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    platforms = require('../platforms'),
-    superspawn = require('../src/superspawn'),
-    path = require('path'),
-    fs = require('fs'),
-    hooker = require('../src/hooker'),
-    Q = require('q'),
-    util = require('../src/util');
-
-var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
-
-describe('run command', function() {
-    var is_cordova, cd_project_root, list_platforms, fire;
-    var project_dir = '/some/path';
-    var prepare_spy;
-
-    beforeEach(function() {
-        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
-        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
-        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
-        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
-        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
-        spyOn(superspawn, 'spawn').andReturn(Q);
-    });
-    describe('failure', function() {
-        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function(done) {
-            list_platforms.andReturn([]);
-            Q().then(cordova.raw.run).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual('No platforms added to this project. Please use `cordova platform add <platform>`.');
-            }).fin(done);
-        });
-        it('should not run outside of a Cordova-based project', function(done) {
-            var msg = 'Dummy message about not being in a cordova dir.';
-            cd_project_root.andThrow(new Error(msg));
-            is_cordova.andReturn(false);
-            Q().then(cordova.raw.run).then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(err.message).toEqual(msg);
-            }).fin(done);
-        });
-    });
-
-    describe('success', function() {
-        it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the run script', function(done) {
-            cordova.raw.run(['android','ios']).then(function() {
-                expect(prepare_spy).toHaveBeenCalledWith(['android', 'ios']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), [], jasmine.any(Object));
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), [], jasmine.any(Object));
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should pass down parameters', function(done) {
-            cordova.raw.run({platforms: ['blackberry10'], options:['--password', '1q1q']}).then(function() {
-                expect(prepare_spy).toHaveBeenCalledWith(['blackberry10']);
-                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'run'), ['--password', '1q1q'], jasmine.any(Object));
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-    });
-
-    describe('hooks', function() {
-        describe('when platforms are added', function() {
-            it('should fire before hooks through the hooker module', function(done) {
-                cordova.raw.run(['android', 'ios']).then(function() {
-                    expect(fire).toHaveBeenCalledWith('before_run', {verbose: false, platforms:['android', 'ios'], options: []});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-            it('should fire after hooks through the hooker module', function(done) {
-                cordova.raw.run('android').then(function() {
-                     expect(fire).toHaveBeenCalledWith('after_run', {verbose: false, platforms:['android'], options: []});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-
-        describe('with no platforms added', function() {
-            it('should not fire the hooker', function(done) {
-                list_platforms.andReturn([]);
-                Q().then(cordova.raw.run).then(function() {
-                    expect('this call').toBe('fail');
-                }, function(err) {
-                    expect(fire).not.toHaveBeenCalled();
-                    expect(err.message).toEqual('No platforms added to this project. Please use `cordova platform add <platform>`.');
-                }).fin(done);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/serve.spec.js
----------------------------------------------------------------------
diff --git a/spec/serve.spec.js b/spec/serve.spec.js
deleted file mode 100644
index 75eec4f..0000000
--- a/spec/serve.spec.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    util = require('../src/util'),
-    hooker = require('../src/hooker'),
-    tempDir = path.join(__dirname, '..', 'temp'),
-    http = require('http'),
-    android_parser = require('../src/metadata/android_parser'),
-    ios_parser = require('../src/metadata/ios_parser'),
-    blackberry_parser = require('../src/metadata/blackberry10_parser'),
-    wp7_parser        = require('../src/metadata/wp7_parser'),
-    wp8_parser        = require('../src/metadata/wp8_parser');
-
-var cwd = process.cwd();
-
-xdescribe('serve command', function() {
-    beforeEach(function() {
-        // Make a temp directory
-        shell.rm('-rf', tempDir);
-        shell.mkdir('-p', tempDir);
-    });
-    it('should not run outside of a Cordova-based project', function() {
-        this.after(function() {
-            process.chdir(cwd);
-        });
-
-        process.chdir(tempDir);
-
-        expect(function() {
-            cordova.serve('android');
-        }).toThrow();
-    });
-
-
-    describe('`serve`', function() {
-        var payloads = {
-            android: 'This is the Android test file.',
-            ios: 'This is the iOS test file.'
-        };
-
-        beforeEach(function() {
-            cordova.raw.create(tempDir);
-            process.chdir(tempDir);
-            cordova.raw.platform('add', 'android');
-            cordova.raw.platform('add', 'ios');
-
-            // Write testing HTML files into the directory.
-            fs.writeFileSync(path.join(tempDir, 'platforms', 'android', 'assets', 'www', 'test.html'), payloads.android);
-            fs.writeFileSync(path.join(tempDir, 'platforms', 'ios', 'www', 'test.html'), payloads.ios);
-        });
-
-        afterEach(function() {
-            process.chdir(cwd);
-        });
-
-        function test_serve(platform, path, expectedContents, port) {
-            return function() {
-                var ret;
-                runs(function() {
-                    ret = port ? cordova.serve(platform, port) : cordova.serve(platform);
-                });
-
-                waitsFor(function() {
-                    return ret.server;
-                }, 'the server should start', 1000);
-
-                var done, errorCB;
-                runs(function() {
-                    expect(ret.server).toBeDefined();
-                    errorCB = jasmine.createSpy();
-                    http.get({
-                        host: 'localhost',
-                        port: port || 8000,
-                        path: path
-                    }).on('response', function(res) {
-                        var response = '';
-                        res.on('data', function(data) {
-                            response += data;
-                        });
-                        res.on('end', function() {
-                            expect(res.statusCode).toEqual(200);
-                            expect(response).toEqual(expectedContents);
-                            done = true;
-                        });
-                    }).on('error', errorCB);
-                });
-
-                waitsFor(function() {
-                    return done;
-                }, 'the HTTP request should complete', 1000);
-
-                runs(function() {
-                    expect(done).toBeTruthy();
-                    expect(errorCB).not.toHaveBeenCalled();
-
-                    ret.server.close();
-                });
-            };
-        };
-
-        it('should serve from top-level www if the file exists there', function() {
-            var payload = 'This is test file.';
-            fs.writeFileSync(path.join(util.projectWww(tempDir), 'test.html'), payload);
-            test_serve('android', '/test.html', payload)();
-        });
-
-        it('should fall back to assets/www on Android', test_serve('android', '/test.html', payloads.android));
-        it('should fall back to www on iOS', test_serve('ios', '/test.html', payloads.ios));
-
-        it('should honour a custom port setting', test_serve('android', '/test.html', payloads.android, 9001));
-    });
-});
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/test-config.xml
----------------------------------------------------------------------
diff --git a/spec/test-config.xml b/spec/test-config.xml
deleted file mode 100644
index 5e01e48..0000000
--- a/spec/test-config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
-        id        = "io.cordova.hellocordova"
-        version   = "0.0.1">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <content src="index.html" />
-
-    <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
-    <icon id="icon" src="icon.png" />
-    <icon id="logo" src="logo.png" width="255" height="255" />
-    <platform name="android">
-        <icon src="logo-android.png" width="255" height="255" density="mdpi" />
-    </platform>    
-</widget>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/util.spec.js
----------------------------------------------------------------------
diff --git a/spec/util.spec.js b/spec/util.spec.js
deleted file mode 100644
index cb24f53..0000000
--- a/spec/util.spec.js
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova = require('../cordova'),
-    shell = require('shelljs'),
-    path = require('path'),
-    fs = require('fs'),
-    util = require('../src/util'),
-    temp = path.join(__dirname, '..', 'temp'),
-    fixtures = path.join(__dirname, 'fixtures');
-
-var cwd = process.cwd();
-var home = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
-var origPWD = process.env['PWD'];
-
-describe('util module', function() {
-    describe('isCordova method', function() {
-        afterEach(function() {
-            process.env['PWD'] = origPWD;
-            process.chdir(cwd);
-        });
-        it('should return false if it hits the home directory', function() {
-            var somedir = path.join(home, 'somedir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir(somedir);
-            expect(util.isCordova(somedir)).toEqual(false);
-        });
-        it('should return false if it cannot find a .cordova directory up the directory tree', function() {
-            var somedir = path.join(home, '..');
-            expect(util.isCordova(somedir)).toEqual(false);
-        });
-        it('should return the first directory it finds with a .cordova folder in it', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
-            expect(util.isCordova(somedir)).toEqual(somedir);
-        });
-        it('should ignore PWD when its undefined', function() {
-            delete process.env['PWD'];
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www'));
-            shell.mkdir('-p', path.join(somedir, 'config.xml'));
-            process.chdir(anotherdir);
-            expect(util.isCordova()).toEqual(somedir);
-        });
-        it('should use PWD when available', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
-            process.env['PWD'] = anotherdir;
-            process.chdir(path.sep);
-            expect(util.isCordova()).toEqual(somedir);
-        });
-        it('should use cwd as a fallback when PWD is not a cordova dir', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
-            process.env['PWD'] = path.sep;
-            process.chdir(anotherdir);
-            expect(util.isCordova()).toEqual(somedir);
-        });
-        it('should ignore platform www/config.xml', function() {
-            var somedir = path.join(home,'somedir');
-            var anotherdir = path.join(somedir, 'anotherdir');
-            this.after(function() {
-                shell.rm('-rf', somedir);
-            });
-            shell.mkdir('-p', anotherdir);
-            shell.mkdir('-p', path.join(anotherdir, 'www', 'config.xml'));
-            shell.mkdir('-p', path.join(somedir, 'www'));
-            shell.mkdir('-p', path.join(somedir, 'config.xml'));
-            expect(util.isCordova(anotherdir)).toEqual(somedir);
-        });
-    });
-    describe('deleteSvnFolders method', function() {
-        afterEach(function() {
-            shell.rm('-rf', temp);
-        });
-        it('should delete .svn folders in any subdirectory of specified dir', function() {
-            var one = path.join(temp, 'one');
-            var two = path.join(temp, 'two');
-            var one_svn = path.join(one, '.svn');
-            var two_svn = path.join(two, '.svn');
-            shell.mkdir('-p', one_svn);
-            shell.mkdir('-p', two_svn);
-            util.deleteSvnFolders(temp);
-            expect(fs.existsSync(one_svn)).toEqual(false);
-            expect(fs.existsSync(two_svn)).toEqual(false);
-        });
-    });
-    describe('listPlatforms method', function() {
-        afterEach(function() {
-            shell.rm('-rf', temp);
-        });
-        it('should only return supported platform directories present in a cordova project dir', function() {
-            var platforms = path.join(temp, 'platforms');
-            var android = path.join(platforms, 'android');
-            var ios = path.join(platforms, 'ios');
-            var wp7 = path.join(platforms, 'wp7');
-            var atari = path.join(platforms, 'atari');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', wp7);
-            shell.mkdir('-p', atari);
-            var res = util.listPlatforms(temp);
-            expect(res.length).toEqual(3);
-            expect(res.indexOf('atari')).toEqual(-1);
-        });
-    });
-    describe('findPlugins method', function() {
-        afterEach(function() {
-            shell.rm('-rf', temp);
-        });
-        it('should only return plugin directories present in a cordova project dir', function() {
-            var plugins = path.join(temp, 'plugins');
-            var android = path.join(plugins, 'android');
-            var ios = path.join(plugins, 'ios');
-            var wp7 = path.join(plugins, 'wp7');
-            var atari = path.join(plugins, 'atari');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', wp7);
-            shell.mkdir('-p', atari);
-            var res = util.findPlugins(plugins);
-            expect(res.length).toEqual(4);
-        });
-        it('should not return ".svn" directories', function() {
-            var plugins = path.join(temp, 'plugins');
-            var android = path.join(plugins, 'android');
-            var ios = path.join(plugins, 'ios');
-            var svn = path.join(plugins, '.svn');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', svn);
-            var res = util.findPlugins(plugins);
-            expect(res.length).toEqual(2);
-            expect(res.indexOf('.svn')).toEqual(-1);
-        });
-        it('should not return "CVS" directories', function() {
-            var plugins = path.join(temp, 'plugins');
-            var android = path.join(plugins, 'android');
-            var ios = path.join(plugins, 'ios');
-            var cvs = path.join(plugins, 'CVS');
-            shell.mkdir('-p', android);
-            shell.mkdir('-p', ios);
-            shell.mkdir('-p', cvs);
-            var res = util.findPlugins(plugins);
-            expect(res.length).toEqual(2);
-            expect(res.indexOf('CVS')).toEqual(-1);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/wrappers.spec.js
----------------------------------------------------------------------
diff --git a/spec/wrappers.spec.js b/spec/wrappers.spec.js
deleted file mode 100644
index 2afbe9b..0000000
--- a/spec/wrappers.spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var Q = require('q'),
-    cordova = require('../cordova');
-
-describe('callback wrapper', function() {
-    var calls = ['prepare', 'build', 'create', 'emulate', 'plugin', 'platform', 'compile', 'run'];
-    for (var i = 0; i < calls.length; i++) {
-        var call = calls[i];
-
-        describe('`' + call + '`', function() {
-            var raw;
-            beforeEach(function() {
-                raw = spyOn(cordova.raw, call);
-            });
-
-            it('should work with no callback and success', function() {
-                raw.andReturn(Q());
-                cordova[call]();
-                expect(raw).toHaveBeenCalled();
-            });
-
-            it('should call the callback on success', function(done) {
-                raw.andReturn(Q());
-                cordova[call](function(err) {
-                    expect(err).toBeUndefined();
-                    done();
-                });
-            });
-
-            it('should call the callback with the error on failure', function(done) {
-                var err = new Error('junk');
-                raw.andReturn(Q.reject(err));
-                cordova[call](function(e) {
-                    expect(e).toEqual(err);
-                    done();
-                });
-            });
-        });
-    }
-});
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/spec/xml-helpers.spec.js
----------------------------------------------------------------------
diff --git a/spec/xml-helpers.spec.js b/spec/xml-helpers.spec.js
deleted file mode 100644
index 6af8c4b..0000000
--- a/spec/xml-helpers.spec.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var path = require('path')
-  , xml_helpers = require('../src/xml-helpers')
-  , et = require('elementtree')
-
-  , title = et.XML('<title>HELLO</title>')
-  , usesNetworkOne = et.XML('<uses-permission ' +
-            'android:name="PACKAGE_NAME.permission.C2D_MESSAGE"/>')
-  , usesNetworkTwo = et.XML("<uses-permission android:name=\
-            \"PACKAGE_NAME.permission.C2D_MESSAGE\" />")
-  , usesReceive = et.XML("<uses-permission android:name=\
-            \"com.google.android.c2dm.permission.RECEIVE\"/>")
-  , helloTagOne = et.XML("<h1>HELLO</h1>")
-  , goodbyeTag = et.XML("<h1>GOODBYE</h1>")
-  , helloTagTwo = et.XML("<h1>  HELLO  </h1>");
-
-
-describe('xml-helpers', function(){
-    describe('parseElementtreeSync', function() {
-        it('should parse xml with a byte order mark', function() {
-            var xml_path = path.join(__dirname, 'fixtures', 'projects', 'windows', 'bom_test.xml');
-            expect(function() {
-                xml_helpers.parseElementtreeSync(xml_path);
-            }).not.toThrow();
-        })
-    });
-    describe('equalNodes', function() {
-        it('should return false for different tags', function(){
-            expect(xml_helpers.equalNodes(usesNetworkOne, title)).toBe(false);
-        });
-
-        it('should return true for identical tags', function(){
-            expect(xml_helpers.equalNodes(usesNetworkOne, usesNetworkTwo)).toBe(true);
-        });
-
-        it('should return false for different attributes', function(){
-            expect(xml_helpers.equalNodes(usesNetworkOne, usesReceive)).toBe(false);
-        });
-
-        it('should distinguish between text', function(){
-            expect(xml_helpers.equalNodes(helloTagOne, goodbyeTag)).toBe(false);
-        });
-
-        it('should ignore whitespace in text', function(){
-            expect(xml_helpers.equalNodes(helloTagOne, helloTagTwo)).toBe(true);
-        });
-
-        describe('should compare children', function(){
-            it('by child quantity', function(){
-                var one = et.XML('<i><b>o</b></i>'),
-                    two = et.XML('<i><b>o</b><u></u></i>');
-
-                expect(xml_helpers.equalNodes(one, two)).toBe(false);
-            });
-
-            it('by child equality', function(){
-                var one = et.XML('<i><b>o</b></i>'),
-                    two = et.XML('<i><u></u></i>'),
-                    uno = et.XML('<i>\n<b>o</b>\n</i>');
-
-                expect(xml_helpers.equalNodes(one, uno)).toBe(true);
-                expect(xml_helpers.equalNodes(one, two)).toBe(false);
-            });
-        });
-    });
-    describe('pruneXML', function() {
-        var config_xml;
-
-        beforeEach(function() {
-            config_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'projects', 'android', 'res', 'xml', 'config.xml'));
-        });
-
-        it('should remove any children that match the specified selector', function() {
-            var children = config_xml.findall('plugins/plugin');
-            xml_helpers.pruneXML(config_xml, children, 'plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
-        });
-        it('should do nothing if the children cannot be found', function() {
-            var children = [title];
-            xml_helpers.pruneXML(config_xml, children, 'plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(17);
-        });
-        it('should be able to handle absolute selectors', function() {
-            var children = config_xml.findall('plugins/plugin');
-            xml_helpers.pruneXML(config_xml, children, '/cordova/plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
-        });
-        it('should be able to handle absolute selectors with wildcards', function() {
-            var children = config_xml.findall('plugins/plugin');
-            xml_helpers.pruneXML(config_xml, children, '/*/plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
-        });
-    });
-
-    describe('graftXML', function() {
-        var config_xml, plugin_xml;
-
-        beforeEach(function() {
-            config_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'projects', 'android', 'res', 'xml', 'config.xml'));
-            plugin_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'plugins', 'ChildBrowser', 'plugin.xml'));
-        });
-
-        it('should add children to the specified selector', function() {
-            var children = plugin_xml.find('config-file').getchildren();
-            xml_helpers.graftXML(config_xml, children, 'plugins');
-            expect(config_xml.find('plugins').getchildren().length).toEqual(19);
-        });
-        it('should be able to handle absolute selectors', function() {
-            var children = plugin_xml.find('config-file').getchildren();
-            xml_helpers.graftXML(config_xml, children, '/cordova');
-            expect(config_xml.findall('access').length).toEqual(3);
-        });
-        it('should be able to handle absolute selectors with wildcards', function() {
-            var children = plugin_xml.find('config-file').getchildren();
-            xml_helpers.graftXML(config_xml, children, '/*');
-            expect(config_xml.findall('access').length).toEqual(3);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/ConfigParser.js
----------------------------------------------------------------------
diff --git a/src/ConfigParser.js b/src/ConfigParser.js
deleted file mode 100644
index 067c30f..0000000
--- a/src/ConfigParser.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var et = require('elementtree'),
-    xml= require('./xml-helpers'),
-    CordovaError = require('./CordovaError'),
-    fs = require('fs');
-
-/** Wraps a config.xml file */
-function ConfigParser(path) {
-    this.path = path;
-    try {
-        this.doc = xml.parseElementtreeSync(path);
-    } catch (e) {
-        console.error('Parsing '+path+' failed');
-        throw e;
-    }
-    var r = this.doc.getroot();
-    if (r.tag !== 'widget') {
-        throw new CordovaError(path + ' has incorrect root node name (expected "widget", was "' + r.tag + '")');
-    }
-}
-
-function getNodeTextSafe(el) {
-    return el && el.text && el.text.trim();
-}
-
-function findOrCreate(doc, name) {
-    var ret = doc.find(name);
-    if (!ret) {
-        ret = new et.Element(name);
-        doc.getroot().append(content);
-    }
-    return ret;
-}
-
-ConfigParser.prototype = {
-    packageName: function(id) {
-        return this.doc.getroot().attrib['id'];
-    },
-    setPackageName: function(id) {
-        this.doc.getroot().attrib['id'] = id;
-    },
-    name: function() {
-        return getNodeTextSafe(this.doc.find('name'));
-    },
-    setName: function(name) {
-        var el = findOrCreate(this.doc, 'name');
-        el.text = name;
-    },
-    description: function() {
-        return this.doc.find('description').text.trim();
-    },
-    setDescription: function() {
-        this.doc.find('description').text = name;
-        var el = findOrCreate(this.doc, 'description');
-    },
-    version: function() {
-        return this.doc.getroot().attrib['version'];
-    },
-    android_versionCode: function() {
-        return this.doc.getroot().attrib['android-versionCode'];
-    },
-    ios_CFBundleVersion: function() {
-        return this.doc.getroot().attrib['ios-CFBundleVersion'];
-    },
-    setVersion: function(value) {
-        this.doc.getroot().attrib['version'] = value;
-    },
-    author: function() {
-        return getNodeTextSafe(this.doc.find('author'));
-    },
-    getPreference: function(name) {
-        var preferences = this.doc.findall('preference');
-        var ret = null;
-        preferences.forEach(function (preference) {
-            // Take the last one that matches.
-            if (preference.attrib.name.toLowerCase() === name.toLowerCase()) {
-                ret = preference.attrib.value;
-            }
-        });
-        return ret;
-    },
-    /**
-     * Returns all icons for the platform specified.
-     * @param  {String} platform The platform.
-     * @return {Array} Icons for the platform specified.
-     */
-    getIcons: function(platform) {
-        var ret = [];
-            iconElements = [];
-
-        if (platform) { // platform specific icons
-            this.doc.findall('platform[@name=\'' + platform + '\']/icon').forEach(function(elt){
-                elt.platform = platform; // mark as platform specific icon
-                iconElements.push(elt)
-            });
-        }
-        // root level icons
-        iconElements = iconElements.concat(this.doc.findall('icon'));
-        // parse icon elements
-        iconElements.forEach(function (elt) {
-            var icon = {};
-            icon.src = elt.attrib.src;
-            icon.density = elt.attrib['density'] || elt.attrib['cdv:density'] || elt.attrib['gap:density'];
-            icon.platform = elt.platform || null; // null means icon represents default icon (shared between platforms)
-            icon.width = elt.attrib.width;
-            icon.height = elt.attrib.height;
-            // If one of width or Height is undefined, assume they are equal.
-            icon.width = icon.width || icon.height;
-            icon.height = icon.height || icon.width;
-
-            // default icon
-            if (!icon.width && !icon.height && !icon.density) {
-                ret.defaultIcon = icon;
-            }
-            ret.push(icon);
-        });
-
-        /**
-         * Returns icon with specified width and height
-         * @param  {number} w  Width of icon
-         * @param  {number} h  Height of icon
-         * @return {Icon}      Icon object or null if not found
-         */
-        ret.getIconBySize = function(w, h){
-            // If only one of width and height is given
-            // then we assume that they are equal.
-            var width = w || h, height = h || w;
-            for (var idx in this) {
-                var icon = this[idx];
-                if (width == icon.width && height == icon.width) return icon;
-            }
-            return null;
-        };
-        /** Returns default icons */
-        ret.getDefault = function() {
-            return ret.defaultIcon;
-        }
-
-        return ret;
-    },
-    write:function() {
-        fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
-    }
-};
-
-module.exports = ConfigParser;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/CordovaError.js
----------------------------------------------------------------------
diff --git a/src/CordovaError.js b/src/CordovaError.js
deleted file mode 100644
index 5576e06..0000000
--- a/src/CordovaError.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-
-// A derived exception class. See usage example in cli.js
-// Based on:
-// stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/8460753#8460753
-function CordovaError(message) {
-    Error.captureStackTrace(this, this.constructor);
-    this.name = this.constructor.name;
-    this.message = message;
-}
-CordovaError.prototype.__proto__ = Error.prototype;
-
-module.exports = CordovaError;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/build.js
----------------------------------------------------------------------
diff --git a/src/build.js b/src/build.js
deleted file mode 100644
index 5a0f0d3..0000000
--- a/src/build.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var cordova_util      = require('./util'),
-    Q                 = require('q'),
-    hooker            = require('./hooker');
-
-// Returns a promise.
-module.exports = function build(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-
-    if (!options) {
-        options = {
-            verbose: false,
-            platforms: [],
-            options: []
-        };
-    }
-
-    options = cordova_util.preProcessOptions(options);
-
-    // fire build hooks
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_build', options)
-    .then(function() {
-        return require('../cordova').raw.prepare(options);
-    }).then(function() {
-        return require('../cordova').raw.compile(options);
-    }).then(function() {
-        return hooks.fire('after_build', options);
-    });
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/compile.js
----------------------------------------------------------------------
diff --git a/src/compile.js b/src/compile.js
deleted file mode 100644
index 857c3a5..0000000
--- a/src/compile.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-/*global require: true, module: true, process: true*/
-/*jslint sloppy: true, white: true, newcap: true */
-
-var path              = require('path'),
-    cordova_util      = require('./util'),
-    hooker            = require('./hooker'),
-    superspawn        = require('./superspawn');
-
-// Returns a promise.
-module.exports = function compile(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-    options = cordova_util.preProcessOptions(options);
-
-    var hooks = new hooker(projectRoot);
-    var ret = hooks.fire('before_compile', options);
-    options.platforms.forEach(function(platform) {
-        ret = ret.then(function() {
-            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'build');
-            return superspawn.spawn(cmd, options.options, { stdio: 'inherit', printCommand: true });
-        });
-    });
-    ret = ret.then(function() {
-        return hooks.fire('after_compile', options);
-    });
-    return ret;
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/config.js
----------------------------------------------------------------------
diff --git a/src/config.js b/src/config.js
deleted file mode 100644
index d0c8d9a..0000000
--- a/src/config.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var path          = require('path'),
-    fs            = require('fs'),
-    url           = require('url'),
-    shell         = require('shelljs');
-
-// Map of project_root -> JSON
-var configCache = {};
-var autoPersist = true;
-
-function config(project_root, opts) {
-    var json = config.read(project_root);
-    for (var p in opts) {
-        json[p] = opts[p];
-    }
-    if (autoPersist) {
-        config.write(project_root, json);
-    } else {
-        configCache[project_root] = JSON.stringify(json);
-    }
-    return json;
-};
-
-config.setAutoPersist = function(value) {
-    autoPersist = value;
-};
-
-config.read = function get_config(project_root) {
-    var data = configCache[project_root];
-    if (data === undefined) {
-        var configPath = path.join(project_root, '.cordova', 'config.json');
-        if (!fs.existsSync(configPath)) {
-            data = '{}';
-        } else {
-            data = fs.readFileSync(configPath, 'utf-8');
-        }
-    }
-    configCache[project_root] = data;
-    return JSON.parse(data);
-};
-
-config.write = function set_config(project_root, json) {
-    var configPath = path.join(project_root, '.cordova', 'config.json');
-    var contents = JSON.stringify(json, null, 4);
-    configCache[project_root] = contents;
-    // Don't write the file for an empty config.
-    if (contents != '{}' || fs.existsSync(configPath)) {
-        shell.mkdir('-p', path.join(project_root, '.cordova'));
-        fs.writeFileSync(configPath, contents, 'utf-8');
-    }
-    return json;
-};
-
-config.has_custom_path = function(project_root, platform) {
-    var json = config.read(project_root);
-    if (json.lib && json.lib[platform]) {
-        var uri = url.parse(json.lib[platform].uri);
-        if (!(uri.protocol)) return uri.path;
-        else if (uri.protocol && uri.protocol[1] ==':') return uri.href;
-    }
-    return false;
-};
-
-module.exports = config;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/create.js
----------------------------------------------------------------------
diff --git a/src/create.js b/src/create.js
deleted file mode 100644
index 025e56b..0000000
--- a/src/create.js
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var path          = require('path'),
-    fs            = require('fs'),
-    shell         = require('shelljs'),
-    platforms     = require('../platforms'),
-    help          = require('./help'),
-    events        = require('./events'),
-    config        = require('./config'),
-    lazy_load     = require('./lazy_load'),
-    Q             = require('q'),
-    CordovaError  = require('./CordovaError'),
-    ConfigParser = require('./ConfigParser'),
-    util          = require('./util');
-
-var DEFAULT_NAME = "HelloCordova",
-    DEFAULT_ID   = "io.cordova.hellocordova";
-
-/**
- * Usage:
- * @dir - directory where the project will be created. Required.
- * @id - app id. Optional, default is DEFAULT_ID.
- * @name - app name. Optional, default is DEFAULT_NAME.
- * @cfg - extra config to be saved in .cordova/config.json
- **/
-// Returns a promise.
-module.exports = create;
-function create(dir, id, name, cfg) {
-    if (!dir ) {
-        return Q(help());
-    }
-
-    // Massage parameters
-    if (typeof cfg == 'string') {
-        cfg = JSON.parse(cfg);
-    }
-    cfg = cfg || {};
-    id = id || cfg.id || DEFAULT_ID;
-    name = name || cfg.name || DEFAULT_NAME;
-
-    // Make absolute.
-    dir = path.resolve(dir);
-
-    events.emit('log', 'Creating a new cordova project with name "' + name + '" and id "' + id + '" at location "' + dir + '"');
-
-    var www_dir = path.join(dir, 'www');
-
-    // dir must be either empty or not exist at all.
-
-    // dir must be either empty except for .cordova config file or not exist at all..
-    var sanedircontents = function (d) {
-        var contents = fs.readdirSync(d);
-        if (contents.length === 0) {
-            return true;
-        } else if (contents.length == 1) {
-            if (contents[0] == '.cordova') {
-                return true;
-            }
-        }
-        return false;
-    };
-
-    if (fs.existsSync(dir) && !sanedircontents(dir)) {
-        return Q.reject(new CordovaError('Path already exists and is not empty: ' + dir));
-    }
-
-    // Read / Write .cordova/config.json file if necessary.
-    var config_json = config(dir, cfg);
-
-    var p;
-    var symlink = false; // Whether to symlink the www dir instead of copying.
-    var www_parent_dir;
-    var custom_config_xml;
-    var custom_merges;
-    var custom_hooks;
-
-    if (config_json.lib && config_json.lib.www) {
-        events.emit('log', 'Using custom www assets from '+config_json.lib.www.uri);
-        // TODO (kamrik): extend lazy_load for retrieval without caching to allow net urls for --src.
-        var www_version = config_json.lib.www.version || 'not_versioned';
-        var www_id = config_json.lib.www.id || 'dummy_id';
-        symlink  = !!config_json.lib.www.link;
-        if ( www_dir.indexOf(path.resolve(config_json.lib.www.uri)) === 0 ) {
-            throw new CordovaError(
-                'Project must not be created inside the www assets dir.' +
-                '\n    project dir:\t' + dir +
-                '\n    www assets dir:\t' + config_json.lib.www.uri
-            );
-        }
-        if(symlink) {
-            p = Q(config_json.lib.www.uri);
-            events.emit('verbose', 'Symlinking custom www assets into "' + www_dir + '"');
-        } else {
-            p = lazy_load.custom(config_json.lib.www.uri, www_id, 'www', www_version)
-            .then(function(d) {
-                events.emit('verbose', 'Copying custom www assets into "' + www_dir + '"');
-                return d;
-            });
-        }
-    } else {
-        // No custom www - use stock cordova-hello-world-app.
-        events.emit('verbose', 'Using stock cordova hello-world application.');
-        p = lazy_load.cordova('www')
-        .then(function(d) {
-            events.emit('verbose', 'Copying stock Cordova www assets into "' + www_dir + '"');
-            return d;
-        });
-    }
-
-    return p.then(function(www_lib) {
-        if (!fs.existsSync(www_lib)) {
-            throw new CordovaError('Could not find directory: '+www_lib);
-        }
-        // Keep going into child "www" folder if exists in stock app package.
-        while (fs.existsSync(path.join(www_lib, 'www'))) {
-            www_parent_dir = www_lib;
-            www_lib = path.join(www_lib, 'www');
-        }
-
-        // Find if we also have custom merges and config.xml as siblings of custom www.
-        if (www_parent_dir && config_json.lib && config_json.lib.www) {
-            custom_config_xml = path.join(www_parent_dir, 'config.xml');
-            if ( !fs.existsSync(custom_config_xml) ) {
-                custom_config_xml = null;
-            }
-            custom_merges = path.join(www_parent_dir, 'merges');
-            if ( !fs.existsSync(custom_merges) ) {
-                custom_merges = null;
-            }
-            custom_hooks = path.join(www_parent_dir, 'hooks');
-            if ( !fs.existsSync(custom_hooks) ) {
-                custom_hooks = null;
-            }
-        }
-
-        var dirAlreadyExisted = fs.existsSync(dir);
-        if (!dirAlreadyExisted) {
-            shell.mkdir(dir);
-        }
-        if (symlink) {
-            try {
-                fs.symlinkSync(www_lib, www_dir, 'dir');
-                if (custom_merges) {
-                    fs.symlinkSync(custom_merges, path.join(dir, 'merges'), 'dir');
-                }
-                if (custom_hooks) {
-                    fs.symlinkSync(custom_hooks, path.join(dir, 'hooks'), 'dir');
-                }
-                if (custom_config_xml) {
-                    fs.symlinkSync(custom_config_xml, path.join(dir, 'config.xml'));
-                }
-            } catch (e) {
-                if (!dirAlreadyExisted) {
-                    fs.rmdirSync(dir);
-                }
-                if (process.platform.slice(0, 3) == 'win' && e.code == 'EPERM')  {
-                    throw new CordovaError('Symlinks on Windows require Administrator privileges');
-                }
-                throw e;
-            }
-        } else {
-            shell.mkdir(www_dir);
-            shell.cp('-R', path.join(www_lib, '*'), www_dir);
-            if (custom_merges) {
-                var merges_dir = path.join(dir, 'merges');
-                shell.mkdir(merges_dir);
-                shell.cp('-R', path.join(custom_merges, '*'), merges_dir);
-            }
-            if (custom_hooks) {
-                var hooks_dir = path.join(dir, 'hooks');
-                shell.mkdir(hooks_dir);
-                shell.cp('-R', path.join(custom_hooks, '*'), hooks_dir);
-            }
-            if (custom_config_xml) {
-                shell.cp(custom_config_xml, path.join(dir, 'config.xml'));
-            }
-
-        }
-
-        // Create basic project structure.
-        shell.mkdir(path.join(dir, 'platforms'));
-        if ( !custom_merges) {
-            shell.mkdir(path.join(dir, 'merges'));
-        }
-        shell.mkdir(path.join(dir, 'plugins'));
-        shell.mkdir(path.join(dir, 'hooks'));
-
-        // Add hooks README.md
-        shell.cp(path.join(__dirname, '..', 'templates', 'hooks-README.md'), path.join(dir, 'hooks', 'README.md'));
-
-        var configPath = util.projectConfig(dir);
-        // Add template config.xml for apps that are missing it
-        if (!fs.existsSync(configPath)) {
-            var template_config_xml = path.join(__dirname, '..', 'templates', 'config.xml');
-            shell.cp(template_config_xml, configPath);
-            // Write out id and name to config.xml
-            var config = new ConfigParser(configPath);
-            config.setPackageName(id);
-            config.setName(name);
-            config.write();
-        }
-    });
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/emulate.js
----------------------------------------------------------------------
diff --git a/src/emulate.js b/src/emulate.js
deleted file mode 100644
index c1d3a10..0000000
--- a/src/emulate.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-/*global require: true, module: true, process: true*/
-/*jslint sloppy: true, white: true, newcap: true */
-
-var cordova_util      = require('./util'),
-    path              = require('path'),
-    hooker            = require('./hooker'),
-    superspawn        = require('./superspawn'),
-    Q                 = require('q');
-
-// Returns a promise.
-module.exports = function emulate(options) {
-    var projectRoot = cordova_util.cdProjectRoot();
-    options = cordova_util.preProcessOptions(options);
-
-    var hooks = new hooker(projectRoot);
-    return hooks.fire('before_emulate', options)
-    .then(function() {
-        // Run a prepare first!
-        return require('../cordova').raw.prepare(options.platforms);
-    }).then(function() {
-        // Deploy in parallel (output gets intermixed though...)
-        return Q.all(options.platforms.map(function(platform) {
-            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'run');
-            var args = ['--emulator'].concat(options.options);
-
-            return superspawn.spawn(cmd, args, {stdio: 'inherit', printCommand: true});
-        }));
-    }).then(function() {
-        return hooks.fire('after_emulate', options);
-    });
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/events.js
----------------------------------------------------------------------
diff --git a/src/events.js b/src/events.js
deleted file mode 100644
index be40fec..0000000
--- a/src/events.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var events = require('events');
-
-var emitter = new events.EventEmitter();
-
-module.exports = emitter;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/hooker.js
----------------------------------------------------------------------
diff --git a/src/hooker.js b/src/hooker.js
deleted file mode 100644
index e4ccaff..0000000
--- a/src/hooker.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var util  = require('./util'),
-    fs    = require('fs'),
-    os    = require('os'),
-    events= require('./events'),
-    superspawn = require('./superspawn'),
-    CordovaError = require('./CordovaError'),
-    Q     = require('q'),
-    path  = require('path'),
-    _ = require('underscore');
-
-module.exports = function hooker(root) {
-    var r = util.isCordova(root);
-    if (!r) throw new CordovaError('Not a Cordova project ("'+root+'"), can\'t use hooks.');
-    else this.root = r;
-};
-
-// Returns a promise.
-module.exports.fire = function global_fire(hook, opts) {
-    opts = opts || {};
-    var handlers = events.listeners(hook);
-    return execute_handlers_serially(handlers, opts);
-};
-
-function compareNumbers(a, b) {
-    return isNaN (parseInt(a))
-        ? a.toLowerCase().localeCompare(b.toLowerCase ? b.toLowerCase(): b)
-        : parseInt(a) > parseInt(b) ? 1 : parseInt(a) < parseInt(b) ? -1 : 0;
-}
-
-module.exports.prototype = {
-    // Returns a promise.
-    fire:function fire(hook, opts) {
-        var root = this.root;
-        opts = opts || {};
-        opts.root = root;
-
-        function fireHooksInDir(dir) {
-            if (!(fs.existsSync(dir))) {
-                return Q();
-            } else {
-                var scripts = fs.readdirSync(dir).sort(compareNumbers).filter(function(s) {
-                    return s[0] != '.';
-                });
-                return execute_scripts_serially(scripts, root, dir, opts);
-            }
-        }
-        // Fire JS hook for the event
-        // These ones need to "serialize" events, that is, each handler attached to the event needs to finish processing (if it "opted in" to the callback) before the next one will fire.
-        var handlers = events.listeners(hook);
-        return execute_handlers_serially(handlers, opts)
-        .then(function() {
-            return fireHooksInDir(path.join(root, '.cordova', 'hooks', hook));
-        }).then(function() {
-            return fireHooksInDir(path.join(root, 'hooks', hook));
-        });
-    }
-};
-
-function extractSheBangInterpreter(fullpath) {
-    var hookFd = fs.openSync(fullpath, "r");
-    try {
-        // this is a modern cluster size. no need to read less
-        var fileData = new Buffer (4096);
-        var octetsRead = fs.readSync(hookFd, fileData, 0, 4096, 0);
-        var fileChunk = fileData.toString();
-    } finally {
-        fs.closeSync(hookFd);
-    }
-
-    var hookCmd, shMatch;
-    // Filter out /usr/bin/env so that "/usr/bin/env node" works like "node".
-    var shebangMatch = fileChunk.match(/^#!(?:\/usr\/bin\/env )?([^\r\n]+)/m);
-    if (octetsRead == 4096 && !fileChunk.match(/[\r\n]/))
-        events.emit('warn', 'shebang is too long for "' + fullpath + '"');
-    if (shebangMatch)
-        hookCmd = shebangMatch[1];
-    // Likewise, make /usr/bin/bash work like "bash".
-    if (hookCmd)
-        shMatch = hookCmd.match(/bin\/((?:ba)?sh)$/)
-    if (shMatch)
-        hookCmd = shMatch[1]
-    return hookCmd;
-}
-
-// Returns a promise.
-function execute_scripts_serially(scripts, root, dir, opts) {
-    opts = opts || {};
-    var isWindows = os.platform().slice(0, 3) === 'win';
-    if (scripts.length) {
-        var s = scripts.shift();
-        var fullpath = path.join(dir, s);
-        if (fs.statSync(fullpath).isDirectory()) {
-            events.emit('verbose', 'skipped directory "' + fullpath + '" within hook directory');
-            return execute_scripts_serially(scripts, root, dir, opts); // skip directories if they're in there.
-        } else {
-            var command = fullpath;
-            var args = [root];
-            if (os.platform().slice(0, 3) == 'win') {
-                // TODO: Make shebang sniffing a setting (not everyone will want this).
-                var interpreter = extractSheBangInterpreter(fullpath);
-                // we have shebang, so try to run this script using correct interpreter
-                if (interpreter) {
-                    args.unshift(command);
-                    command = interpreter;
-                }
-            }
-
-            var execOpts = {cwd: root, printCommand: true, stdio: 'inherit'};
-            execOpts.env = {};
-            execOpts.env.CORDOVA_VERSION = require('../package').version;
-            execOpts.env.CORDOVA_PLATFORMS = opts.platforms ? opts.platforms.join() : '';
-            execOpts.env.CORDOVA_PLUGINS = opts.plugins?opts.plugins.join():'';
-            execOpts.env.CORDOVA_HOOK = fullpath;
-            execOpts.env.CORDOVA_CMDLINE = process.argv.join(' ');
-
-            return superspawn.spawn(command, args, execOpts)
-            .catch(function(err) {
-                // Don't treat non-executable files as errors. They could be READMEs, or Windows-only scripts.
-                if (!isWindows && err.code == 'EACCES') {
-                    events.emit('verbose', 'skipped non-executable file: ' + fullpath);
-                } else {
-                    throw new CordovaError('Hook failed with error code ' + err.code + ': ' + fullpath);
-                }
-            }).then(function() {
-                return execute_scripts_serially(scripts, root, dir, opts);
-            });
-        }
-    } else {
-        return Q(); // Nothing to do.
-    }
-}
-
-// Returns a promise.
-function execute_handlers_serially(handlers, opts) {
-    if (handlers.length) {
-        // Chain the handlers in series.
-        return handlers.reduce(function(soFar, f) {
-            return soFar.then(function() { return f(opts) });
-        }, Q());
-    } else {
-        return Q(); // Nothing to do.
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/src/info.js
----------------------------------------------------------------------
diff --git a/src/info.js b/src/info.js
deleted file mode 100644
index c8b8e24..0000000
--- a/src/info.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-'License'); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
- */
-
-/*
-A utility funciton to help output the information needed
-when submitting a help request.
-Outputs to a file
- */
-var cordova_util = require('./util'),
-    superspawn   = require('./superspawn'),
-    package      = require('../package'),
-    path         = require('path'),
-    fs           = require('fs'),
-    Q            = require('q');
-
-// Execute using a child_process exec, for any async command
-function execSpawn(command, args, resultMsg, errorMsg) {
-    return superspawn.spawn(command, args).then(function(result) {
-        return resultMsg + result;
-    }, function(error) {
-        return errorMsg + error;
-    });
-}
-
-function getPlatformInfo(platform, projectRoot) {
-    switch (platform) {
-    case 'ios':
-        return execSpawn('xcodebuild', ['-version'], 'iOS platform:\n\n', 'Error retrieving iOS platform information: ');
-    case 'android':
-        return execSpawn('android', ['list', 'target'], 'Android platform:\n\n', 'Error retrieving Android platform information: ');
-    }
-}
-
-
-module.exports = function info() {
-    //Get projectRoot
-    var projectRoot = cordova_util.cdProjectRoot();
-    var output = '';
-    if (!projectRoot) {
-        return Q.reject(new Error('Current working directory is not a Cordova-based project.'));
-    }
-
-    //Array of functions, Q.allSettled
-    console.log('Collecting Data...\n\n');
-    return Q.allSettled([
-            //Get Node version
-            Q('Node version: ' + process.version),
-            //Get Cordova version
-            Q('Cordova version: ' + package.version),
-            //Get project config.xml file using ano
-            getProjectConfig(projectRoot),
-            //Get list of plugins
-            listPlugins(projectRoot),
-            //Get Platforms information
-            getPlatforms(projectRoot)
-        ]).then(function(promises) {
-        promises.forEach(function(p) {
-            output += p.state === 'fulfilled' ? p.value + '\n\n' : p.reason + '\n\n';
-        });
-        console.info(output);
-        fs.writeFile(path.join(projectRoot, 'info.txt'), output, 'utf-8', function (err) {
-            if (err)
-                throw err;
-        });
-    });
-};
-
-function getPlatforms(projectRoot) {
-    var platforms = cordova_util.listPlatforms(projectRoot);
-    if (platforms.length) {
-        return Q.all(platforms.map(function(p) {
-            return getPlatformInfo(p, projectRoot);
-        })).then(function(outs) {
-          return outs.join('\n\n');
-        });
-    }
-    return Q.reject('No Platforms Currently Installed');
-}
-
-function listPlugins(projectRoot) {
-    var pluginPath = path.join(projectRoot, 'plugins'),
-        plugins    = cordova_util.findPlugins(pluginPath);
-
-    if (!plugins.length) {
-        return Q.reject('No Plugins Currently Installed');
-    }
-    return Q('Plugins: \n\n' + plugins);
-}
-
-function getProjectConfig(projectRoot) {
-    if (!fs.existsSync(projectRoot)  ) {
-        return Q.reject('Config.xml file not found');
-    }
-    return Q('Config.xml file: \n\n' + (fs.readFileSync(cordova_util.projectConfig(projectRoot), 'utf-8')));
-}


[10/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/plugin.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/plugin.spec.js b/cordova-lib/spec-cordova/plugin.spec.js
new file mode 100644
index 0000000..2ad7b08
--- /dev/null
+++ b/cordova-lib/spec-cordova/plugin.spec.js
@@ -0,0 +1,68 @@
+
+var helpers = require('./helpers'),
+    path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    Q = require('q'),
+    events = require('../src/events'),
+    cordova = require('../cordova');
+
+var tmpDir = helpers.tmpDir('plugin_test');
+var project = path.join(tmpDir, 'project');
+var pluginsDir = path.join(__dirname, 'fixtures', 'plugins');
+var pluginId = 'org.apache.cordova.fakeplugin1';
+
+describe('plugin end-to-end', function() {
+    var results;
+
+    beforeEach(function() {
+        shell.rm('-rf', project);
+    });
+    afterEach(function() {
+        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
+        shell.rm('-rf', tmpDir);
+    });
+
+    // The flow tested is: ls, add, ls, rm, ls.
+    // Plugin dependencies are not tested as that should be corvered in plugman tests.
+    // TODO (kamrik): Test the 'plugin search' command.
+    it('should successfully run', function(done) {
+        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
+        // Using /* doesn't work because of hidden files.
+        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
+        shell.mv(path.join(tmpDir, 'base'), project);
+        // Copy some platform to avoid working on a project with no platforms.
+        shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform), path.join(project, 'platforms'));
+        process.chdir(project);
+
+        events.on('results', function(res) { results = res; });
+
+        // Check there are no plugins yet.
+        cordova.raw.plugin('list').then(function() {
+            expect(results).toMatch(/No plugins added/gi);
+        }).then(function() {
+            // Add a fake plugin from fixtures.
+            return cordova.raw.plugin('add', path.join(pluginsDir, 'fake1'));
+        }).then(function() {
+           expect(path.join(project, 'plugins', pluginId, 'plugin.xml')).toExist();
+        }).then(function() {
+            return cordova.raw.plugin('ls');
+        }).then(function() {
+            expect(results).toContain(pluginId);
+            expect(results.length).toEqual(1);
+        }).then(function() {
+            // And now remove it.
+            return cordova.raw.plugin('rm', pluginId);
+        }).then(function() {
+            // The whole dir should be gone.
+            expect(path.join(project, 'plugins', pluginId)).not.toExist();
+        }).then(function() {
+            return cordova.raw.plugin('ls');
+        }).then(function() {
+            expect(results).toMatch(/No plugins added/gi);
+        }).fail(function(err) {
+            console.log(err);
+            expect(err).toBeUndefined();
+        }).fin(done);
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/plugin_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/plugin_parser.spec.js b/cordova-lib/spec-cordova/plugin_parser.spec.js
new file mode 100644
index 0000000..9a63154
--- /dev/null
+++ b/cordova-lib/spec-cordova/plugin_parser.spec.js
@@ -0,0 +1,48 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    path = require('path'),
+    fs = require('fs'),
+    plugin_parser = require('../src/plugin_parser'),
+    et = require('elementtree'),
+    xml = path.join(__dirname, 'fixtures', 'plugins', 'test', 'plugin.xml');
+
+var xml_contents = fs.readFileSync(xml, 'utf-8');
+
+describe('plugin.xml parser', function () {
+    var readfile;
+    beforeEach(function() {
+        readfile = spyOn(fs, 'readFileSync').andReturn(xml_contents);
+    });
+
+    it('should read a proper plugin.xml file', function() {
+        var cfg;
+        expect(function () {
+            cfg = new plugin_parser(xml);
+        }).not.toThrow();
+        expect(cfg).toBeDefined();
+        expect(cfg.doc).toBeDefined();
+    });
+    it('should be able to figure out which platforms the plugin supports', function() {
+        var cfg = new plugin_parser(xml);
+        expect(cfg.platforms.length).toBe(1);
+        expect(cfg.platforms.indexOf('ios') > -1).toBe(true);
+    });
+});
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/prepare.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/prepare.spec.js b/cordova-lib/spec-cordova/prepare.spec.js
new file mode 100644
index 0000000..eac225d
--- /dev/null
+++ b/cordova-lib/spec-cordova/prepare.spec.js
@@ -0,0 +1,290 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    shell = require('shelljs'),
+    plugman = require('plugman'),
+    path = require('path'),
+    fs = require('fs'),
+    util = require('../src/util'),
+    prepare = require('../src/prepare'),
+    lazy_load = require('../src/lazy_load'),
+    ConfigParser = require('../src/ConfigParser'),
+    platforms = require('../platforms'),
+    hooker = require('../src/hooker'),
+    xmlHelpers = require('../src/xml-helpers'),
+    fixtures = path.join(__dirname, 'fixtures'),
+    et = require('elementtree'),
+    Q = require('q'),
+    hooks = path.join(fixtures, 'hooks');
+
+var project_dir = '/some/path';
+var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
+var supported_platforms_paths = supported_platforms.map(function(p) { return path.join(project_dir, 'platforms', p, 'www'); });
+
+var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
+    '<widget xmlns     = "http://www.w3.org/ns/widgets"\n' +
+    '        xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
+    '        id        = "io.cordova.hellocordova"\n' +
+    '        version   = "0.0.1">\n' +
+    '    <name>Hello Cordova</name>\n' +
+    '    <description>\n' +
+    '        A sample Apache Cordova application that responds to the deviceready event.\n' +
+    '    </description>\n' +
+    '    <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
+    '        Apache Cordova Team\n' +
+    '    </author>\n' +
+    '    <content src="index.html" />\n' +
+    '    <access origin="*" />\n' +
+    '    <preference name="fullscreen" value="true" />\n' +
+    '    <preference name="webviewbounce" value="true" />\n' +
+    '</widget>\n';
+
+describe('prepare command', function() {
+    var is_cordova,
+        cd_project_root,
+        list_platforms,
+        fire,
+        parsers = {},
+        plugman_prepare,
+        find_plugins,
+        plugman_get_json,
+        cp,
+        mkdir,
+        load;
+    beforeEach(function() {
+        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
+        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
+        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
+        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
+        supported_platforms.forEach(function(p) {
+            parsers[p] = jasmine.createSpy(p + ' update_project').andReturn(Q());
+            spyOn(platforms[p], 'parser').andReturn({
+                update_project:parsers[p],
+                update_www: jasmine.createSpy(p + ' update_www'),
+                cordovajs_path: function(libDir) { return 'path/to/cordova.js/in/.cordova/lib';},
+                www_dir:function() { return path.join(project_dir, 'platforms', p, 'www'); },
+                config_xml: function () { return path.join(project_dir, "platforms", p, "www", "config.xml");}
+            });
+        });
+        plugman_prepare = spyOn(plugman, 'prepare').andReturn(Q());
+        find_plugins = spyOn(util, 'findPlugins').andReturn([]);
+        plugman_get_json = spyOn(plugman.config_changes, 'get_platform_json').andReturn({
+            prepare_queue:{installed:[], uninstalled:[]},
+            config_munge:{},
+            installed_plugins:{},
+            dependent_plugins:{}
+        });
+        load = spyOn(lazy_load, 'based_on_config').andReturn(Q());
+        cp = spyOn(shell, 'cp').andReturn(true);
+        mkdir = spyOn(shell, 'mkdir');
+        spyOn(prepare, '_mergeXml');
+        spyOn(ConfigParser.prototype, 'write');
+        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function() {
+            return new et.ElementTree(et.XML(TEST_XML));
+        });
+    });
+
+    describe('failure', function() {
+        it('should not run outside of a cordova-based project by calling util.isCordova', function(done) {
+            is_cordova.andReturn(false);
+            Q().then(prepare).then(function() {
+                expect('this call').toBe('fail');
+            }, function(err) {
+                expect('' + err).toContain('Current working directory is not a Cordova-based project.');
+            }).fin(done);
+        });
+        it('should not run inside a cordova-based project with no platforms', function(done) {
+            list_platforms.andReturn([]);
+            Q().then(prepare).then(function() {
+                expect('this call').toBe('fail');
+            }, function(err) {
+                expect('' + err).toContain('No platforms added to this project. Please use `cordova platform add <platform>`.');
+            }).fin(done);
+        });
+    });
+
+    describe('success', function() {
+        it('should run inside a Cordova-based project by calling util.isCordova', function(done) {
+            prepare().then(function() {
+                expect(is_cordova).toHaveBeenCalled();
+            }, function(err) {
+                expect(err).toBeUndefined();
+            }).fin(done);
+        });
+        it('should invoke each platform\'s parser\'s update_project method', function(done) {
+            prepare().then(function() {
+                supported_platforms.forEach(function(p) {
+                    expect(parsers[p]).toHaveBeenCalled();
+                });
+            }, function(err) {
+                expect(err).toBeUndefined();
+            }).fin(done);
+        });
+        it('should invoke lazy_load for each platform to make sure platform libraries are loaded', function(done) {
+            prepare().then(function() {
+                supported_platforms.forEach(function(p) {
+                    expect(load).toHaveBeenCalledWith(project_dir, p);
+                });
+            }, function(err) {
+                expect(err).toBeUndefined();
+            }).fin(done);
+        });
+        describe('plugman integration', function() {
+            it('should invoke plugman.prepare after update_project', function(done) {
+                prepare().then(function() {
+                    var plugins_dir = path.join(project_dir, 'plugins');
+                    supported_platforms.forEach(function(p) {
+                        var platform_path = path.join(project_dir, 'platforms', p);
+                        expect(plugman_prepare).toHaveBeenCalledWith(platform_path, (p=='blackberry'?'blackberry10':p), plugins_dir);
+                    });
+                }, function(err) {
+                    expect(err).toBeUndefined();
+                }).fin(done);
+            });
+        });
+    });
+
+    describe('hooks', function() {
+        describe('when platforms are added', function() {
+            it('should fire before hooks through the hooker module, and pass in platforms and paths as data object', function(done) {
+                prepare().then(function() {
+                    expect(fire).toHaveBeenCalledWith('before_prepare', {verbose: false, platforms:supported_platforms, options: [], paths:supported_platforms_paths});
+                }, function(err) {
+                    expect(err).toBeUndefined();
+                }).fin(done);
+            });
+            it('should fire after hooks through the hooker module, and pass in platforms and paths as data object', function(done) {
+                prepare('android').then(function() {
+                     expect(fire).toHaveBeenCalledWith('after_prepare', {verbose: false, platforms:['android'], options: [], paths:[path.join(project_dir, 'platforms', 'android', 'www')]});
+                }, function(err) {
+                    expect(err).toBeUndefined();
+                }).fin(done);
+            });
+        });
+
+        describe('with no platforms added', function() {
+            beforeEach(function() {
+                list_platforms.andReturn([]);
+            });
+            it('should not fire the hooker', function(done) {
+                Q().then(prepare).then(function() {
+                    expect('this call').toBe('fail');
+                }, function(err) {
+                    expect(err).toEqual(jasmine.any(Error));
+                    expect(fire).not.toHaveBeenCalledWith('before_prepare');
+                    expect(fire).not.toHaveBeenCalledWith('after_prepare');
+                }).fin(done);
+            });
+        });
+    });
+});
+
+describe('prepare._mergeXml', function () {
+    var dstXml;
+    beforeEach(function() {
+        dstXml = et.XML(TEST_XML);
+    });
+    it("should merge attributes and text of the root element without clobbering", function () {
+        var testXml = et.XML("<widget foo='bar' id='NOTANID'>TEXT</widget>");
+        prepare._mergeXml(testXml, dstXml);
+        expect(dstXml.attrib.foo).toEqual("bar");
+        expect(dstXml.attrib.id).not.toEqual("NOTANID");
+        expect(dstXml.text).not.toEqual("TEXT");
+    });
+
+    it("should merge attributes and text of the root element with clobbering", function () {
+        var testXml = et.XML("<widget foo='bar' id='NOTANID'>TEXT</widget>");
+        prepare._mergeXml(testXml, dstXml, "foo", true);
+        expect(dstXml.attrib.foo).toEqual("bar");
+        expect(dstXml.attrib.id).toEqual("NOTANID");
+        expect(dstXml.text).toEqual("TEXT");
+    });
+
+    it("should not merge platform tags with the wrong platform", function () {
+        var testXml = et.XML("<widget><platform name='bar'><testElement testAttrib='value'>testTEXT</testElement></platform></widget>"),
+            origCfg = et.tostring(dstXml);
+
+        prepare._mergeXml(testXml, dstXml, "foo", true);
+        expect(et.tostring(dstXml)).toEqual(origCfg);
+    });
+
+    it("should merge platform tags with the correct platform", function () {
+        var testXml = et.XML("<widget><platform name='bar'><testElement testAttrib='value'>testTEXT</testElement></platform></widget>"),
+            origCfg = et.tostring(dstXml);
+
+        prepare._mergeXml(testXml, dstXml, "bar", true);
+        expect(et.tostring(dstXml)).not.toEqual(origCfg);
+        var testElement = dstXml.find("testElement");
+        expect(testElement).toBeDefined();
+        expect(testElement.attrib.testAttrib).toEqual("value");
+        expect(testElement.text).toEqual("testTEXT");
+    });
+
+    it("should merge singelton children without clobber", function () {
+        var testXml = et.XML("<widget><author testAttrib='value' href='http://www.nowhere.com'>SUPER_AUTHOR</author></widget>");
+
+        prepare._mergeXml(testXml, dstXml);
+        var testElements = dstXml.findall("author");
+        expect(testElements).toBeDefined();
+        expect(testElements.length).toEqual(1);
+        expect(testElements[0].attrib.testAttrib).toEqual("value");
+        expect(testElements[0].attrib.href).toEqual("http://cordova.io");
+        expect(testElements[0].attrib.email).toEqual("dev@cordova.apache.org");
+        expect(testElements[0].text).toContain("Apache Cordova Team");
+    });
+
+    it("should clobber singelton children with clobber", function () {
+        var testXml = et.XML("<widget><author testAttrib='value' href='http://www.nowhere.com'>SUPER_AUTHOR</author></widget>");
+
+        prepare._mergeXml(testXml, dstXml, '', true);
+        var testElements = dstXml.findall("author");
+        expect(testElements).toBeDefined();
+        expect(testElements.length).toEqual(1);
+        expect(testElements[0].attrib.testAttrib).toEqual("value");
+        expect(testElements[0].attrib.href).toEqual("http://www.nowhere.com");
+        expect(testElements[0].attrib.email).toEqual("dev@cordova.apache.org");
+        expect(testElements[0].text).toEqual("SUPER_AUTHOR");
+    });
+
+    it("should append non singelton children", function () {
+        var testXml = et.XML("<widget><preference num='1'/> <preference num='2'/></widget>");
+
+        prepare._mergeXml(testXml, dstXml, '', true);
+        var testElements = dstXml.findall("preference");
+        expect(testElements.length).toEqual(4);
+    });
+
+    it("should handle namespaced elements", function () {
+        var testXml = et.XML("<widget><foo:bar testAttrib='value'>testText</foo:bar></widget>");
+
+        prepare._mergeXml(testXml, dstXml, 'foo', true);
+        var testElement = dstXml.find("foo:bar");
+        expect(testElement).toBeDefined();
+        expect(testElement.attrib.testAttrib).toEqual("value");
+        expect(testElement.text).toEqual("testText");
+    });
+
+    it("should not append duplicate non singelton children", function () {
+        var testXml = et.XML("<widget><preference name='fullscreen' value='true'/></widget>");
+
+        prepare._mergeXml(testXml, dstXml, '', true);
+        var testElements = dstXml.findall("preference");
+        expect(testElements.length).toEqual(2);
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/run.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/run.spec.js b/cordova-lib/spec-cordova/run.spec.js
new file mode 100644
index 0000000..bfaf3f8
--- /dev/null
+++ b/cordova-lib/spec-cordova/run.spec.js
@@ -0,0 +1,114 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    platforms = require('../platforms'),
+    superspawn = require('../src/superspawn'),
+    path = require('path'),
+    fs = require('fs'),
+    hooker = require('../src/hooker'),
+    Q = require('q'),
+    util = require('../src/util');
+
+var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; });
+
+describe('run command', function() {
+    var is_cordova, cd_project_root, list_platforms, fire;
+    var project_dir = '/some/path';
+    var prepare_spy;
+
+    beforeEach(function() {
+        is_cordova = spyOn(util, 'isCordova').andReturn(project_dir);
+        cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir);
+        list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms);
+        fire = spyOn(hooker.prototype, 'fire').andReturn(Q());
+        prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q());
+        spyOn(superspawn, 'spawn').andReturn(Q);
+    });
+    describe('failure', function() {
+        it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function(done) {
+            list_platforms.andReturn([]);
+            Q().then(cordova.raw.run).then(function() {
+                expect('this call').toBe('fail');
+            }, function(err) {
+                expect(err.message).toEqual('No platforms added to this project. Please use `cordova platform add <platform>`.');
+            }).fin(done);
+        });
+        it('should not run outside of a Cordova-based project', function(done) {
+            var msg = 'Dummy message about not being in a cordova dir.';
+            cd_project_root.andThrow(new Error(msg));
+            is_cordova.andReturn(false);
+            Q().then(cordova.raw.run).then(function() {
+                expect('this call').toBe('fail');
+            }, function(err) {
+                expect(err.message).toEqual(msg);
+            }).fin(done);
+        });
+    });
+
+    describe('success', function() {
+        it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the run script', function(done) {
+            cordova.raw.run(['android','ios']).then(function() {
+                expect(prepare_spy).toHaveBeenCalledWith(['android', 'ios']);
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), [], jasmine.any(Object));
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), [], jasmine.any(Object));
+            }, function(err) {
+                expect(err).toBeUndefined();
+            }).fin(done);
+        });
+        it('should pass down parameters', function(done) {
+            cordova.raw.run({platforms: ['blackberry10'], options:['--password', '1q1q']}).then(function() {
+                expect(prepare_spy).toHaveBeenCalledWith(['blackberry10']);
+                expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'run'), ['--password', '1q1q'], jasmine.any(Object));
+            }, function(err) {
+                expect(err).toBeUndefined();
+            }).fin(done);
+        });
+    });
+
+    describe('hooks', function() {
+        describe('when platforms are added', function() {
+            it('should fire before hooks through the hooker module', function(done) {
+                cordova.raw.run(['android', 'ios']).then(function() {
+                    expect(fire).toHaveBeenCalledWith('before_run', {verbose: false, platforms:['android', 'ios'], options: []});
+                }, function(err) {
+                    expect(err).toBeUndefined();
+                }).fin(done);
+            });
+            it('should fire after hooks through the hooker module', function(done) {
+                cordova.raw.run('android').then(function() {
+                     expect(fire).toHaveBeenCalledWith('after_run', {verbose: false, platforms:['android'], options: []});
+                }, function(err) {
+                    expect(err).toBeUndefined();
+                }).fin(done);
+            });
+        });
+
+        describe('with no platforms added', function() {
+            it('should not fire the hooker', function(done) {
+                list_platforms.andReturn([]);
+                Q().then(cordova.raw.run).then(function() {
+                    expect('this call').toBe('fail');
+                }, function(err) {
+                    expect(fire).not.toHaveBeenCalled();
+                    expect(err.message).toEqual('No platforms added to this project. Please use `cordova platform add <platform>`.');
+                }).fin(done);
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/serve.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/serve.spec.js b/cordova-lib/spec-cordova/serve.spec.js
new file mode 100644
index 0000000..75eec4f
--- /dev/null
+++ b/cordova-lib/spec-cordova/serve.spec.js
@@ -0,0 +1,132 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    path = require('path'),
+    shell = require('shelljs'),
+    fs = require('fs'),
+    util = require('../src/util'),
+    hooker = require('../src/hooker'),
+    tempDir = path.join(__dirname, '..', 'temp'),
+    http = require('http'),
+    android_parser = require('../src/metadata/android_parser'),
+    ios_parser = require('../src/metadata/ios_parser'),
+    blackberry_parser = require('../src/metadata/blackberry10_parser'),
+    wp7_parser        = require('../src/metadata/wp7_parser'),
+    wp8_parser        = require('../src/metadata/wp8_parser');
+
+var cwd = process.cwd();
+
+xdescribe('serve command', function() {
+    beforeEach(function() {
+        // Make a temp directory
+        shell.rm('-rf', tempDir);
+        shell.mkdir('-p', tempDir);
+    });
+    it('should not run outside of a Cordova-based project', function() {
+        this.after(function() {
+            process.chdir(cwd);
+        });
+
+        process.chdir(tempDir);
+
+        expect(function() {
+            cordova.serve('android');
+        }).toThrow();
+    });
+
+
+    describe('`serve`', function() {
+        var payloads = {
+            android: 'This is the Android test file.',
+            ios: 'This is the iOS test file.'
+        };
+
+        beforeEach(function() {
+            cordova.raw.create(tempDir);
+            process.chdir(tempDir);
+            cordova.raw.platform('add', 'android');
+            cordova.raw.platform('add', 'ios');
+
+            // Write testing HTML files into the directory.
+            fs.writeFileSync(path.join(tempDir, 'platforms', 'android', 'assets', 'www', 'test.html'), payloads.android);
+            fs.writeFileSync(path.join(tempDir, 'platforms', 'ios', 'www', 'test.html'), payloads.ios);
+        });
+
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+
+        function test_serve(platform, path, expectedContents, port) {
+            return function() {
+                var ret;
+                runs(function() {
+                    ret = port ? cordova.serve(platform, port) : cordova.serve(platform);
+                });
+
+                waitsFor(function() {
+                    return ret.server;
+                }, 'the server should start', 1000);
+
+                var done, errorCB;
+                runs(function() {
+                    expect(ret.server).toBeDefined();
+                    errorCB = jasmine.createSpy();
+                    http.get({
+                        host: 'localhost',
+                        port: port || 8000,
+                        path: path
+                    }).on('response', function(res) {
+                        var response = '';
+                        res.on('data', function(data) {
+                            response += data;
+                        });
+                        res.on('end', function() {
+                            expect(res.statusCode).toEqual(200);
+                            expect(response).toEqual(expectedContents);
+                            done = true;
+                        });
+                    }).on('error', errorCB);
+                });
+
+                waitsFor(function() {
+                    return done;
+                }, 'the HTTP request should complete', 1000);
+
+                runs(function() {
+                    expect(done).toBeTruthy();
+                    expect(errorCB).not.toHaveBeenCalled();
+
+                    ret.server.close();
+                });
+            };
+        };
+
+        it('should serve from top-level www if the file exists there', function() {
+            var payload = 'This is test file.';
+            fs.writeFileSync(path.join(util.projectWww(tempDir), 'test.html'), payload);
+            test_serve('android', '/test.html', payload)();
+        });
+
+        it('should fall back to assets/www on Android', test_serve('android', '/test.html', payloads.android));
+        it('should fall back to www on iOS', test_serve('ios', '/test.html', payloads.ios));
+
+        it('should honour a custom port setting', test_serve('android', '/test.html', payloads.android, 9001));
+    });
+});
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/test-config.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/test-config.xml b/cordova-lib/spec-cordova/test-config.xml
new file mode 100644
index 0000000..5e01e48
--- /dev/null
+++ b/cordova-lib/spec-cordova/test-config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns     = "http://www.w3.org/ns/widgets"
+        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
+        id        = "io.cordova.hellocordova"
+        version   = "0.0.1">
+    <name>Hello Cordova</name>
+
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+
+    <author href="http://cordova.io" email="dev@cordova.apache.org">
+        Apache Cordova Team
+    </author>
+
+    <content src="index.html" />
+
+    <access origin="*" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+    <icon id="icon" src="icon.png" />
+    <icon id="logo" src="logo.png" width="255" height="255" />
+    <platform name="android">
+        <icon src="logo-android.png" width="255" height="255" density="mdpi" />
+    </platform>    
+</widget>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/util.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/util.spec.js b/cordova-lib/spec-cordova/util.spec.js
new file mode 100644
index 0000000..cb24f53
--- /dev/null
+++ b/cordova-lib/spec-cordova/util.spec.js
@@ -0,0 +1,186 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova = require('../cordova'),
+    shell = require('shelljs'),
+    path = require('path'),
+    fs = require('fs'),
+    util = require('../src/util'),
+    temp = path.join(__dirname, '..', 'temp'),
+    fixtures = path.join(__dirname, 'fixtures');
+
+var cwd = process.cwd();
+var home = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
+var origPWD = process.env['PWD'];
+
+describe('util module', function() {
+    describe('isCordova method', function() {
+        afterEach(function() {
+            process.env['PWD'] = origPWD;
+            process.chdir(cwd);
+        });
+        it('should return false if it hits the home directory', function() {
+            var somedir = path.join(home, 'somedir');
+            this.after(function() {
+                shell.rm('-rf', somedir);
+            });
+            shell.mkdir(somedir);
+            expect(util.isCordova(somedir)).toEqual(false);
+        });
+        it('should return false if it cannot find a .cordova directory up the directory tree', function() {
+            var somedir = path.join(home, '..');
+            expect(util.isCordova(somedir)).toEqual(false);
+        });
+        it('should return the first directory it finds with a .cordova folder in it', function() {
+            var somedir = path.join(home,'somedir');
+            var anotherdir = path.join(somedir, 'anotherdir');
+            this.after(function() {
+                shell.rm('-rf', somedir);
+            });
+            shell.mkdir('-p', anotherdir);
+            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
+            expect(util.isCordova(somedir)).toEqual(somedir);
+        });
+        it('should ignore PWD when its undefined', function() {
+            delete process.env['PWD'];
+            var somedir = path.join(home,'somedir');
+            var anotherdir = path.join(somedir, 'anotherdir');
+            this.after(function() {
+                shell.rm('-rf', somedir);
+            });
+            shell.mkdir('-p', anotherdir);
+            shell.mkdir('-p', path.join(somedir, 'www'));
+            shell.mkdir('-p', path.join(somedir, 'config.xml'));
+            process.chdir(anotherdir);
+            expect(util.isCordova()).toEqual(somedir);
+        });
+        it('should use PWD when available', function() {
+            var somedir = path.join(home,'somedir');
+            var anotherdir = path.join(somedir, 'anotherdir');
+            this.after(function() {
+                shell.rm('-rf', somedir);
+            });
+            shell.mkdir('-p', anotherdir);
+            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
+            process.env['PWD'] = anotherdir;
+            process.chdir(path.sep);
+            expect(util.isCordova()).toEqual(somedir);
+        });
+        it('should use cwd as a fallback when PWD is not a cordova dir', function() {
+            var somedir = path.join(home,'somedir');
+            var anotherdir = path.join(somedir, 'anotherdir');
+            this.after(function() {
+                shell.rm('-rf', somedir);
+            });
+            shell.mkdir('-p', anotherdir);
+            shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
+            process.env['PWD'] = path.sep;
+            process.chdir(anotherdir);
+            expect(util.isCordova()).toEqual(somedir);
+        });
+        it('should ignore platform www/config.xml', function() {
+            var somedir = path.join(home,'somedir');
+            var anotherdir = path.join(somedir, 'anotherdir');
+            this.after(function() {
+                shell.rm('-rf', somedir);
+            });
+            shell.mkdir('-p', anotherdir);
+            shell.mkdir('-p', path.join(anotherdir, 'www', 'config.xml'));
+            shell.mkdir('-p', path.join(somedir, 'www'));
+            shell.mkdir('-p', path.join(somedir, 'config.xml'));
+            expect(util.isCordova(anotherdir)).toEqual(somedir);
+        });
+    });
+    describe('deleteSvnFolders method', function() {
+        afterEach(function() {
+            shell.rm('-rf', temp);
+        });
+        it('should delete .svn folders in any subdirectory of specified dir', function() {
+            var one = path.join(temp, 'one');
+            var two = path.join(temp, 'two');
+            var one_svn = path.join(one, '.svn');
+            var two_svn = path.join(two, '.svn');
+            shell.mkdir('-p', one_svn);
+            shell.mkdir('-p', two_svn);
+            util.deleteSvnFolders(temp);
+            expect(fs.existsSync(one_svn)).toEqual(false);
+            expect(fs.existsSync(two_svn)).toEqual(false);
+        });
+    });
+    describe('listPlatforms method', function() {
+        afterEach(function() {
+            shell.rm('-rf', temp);
+        });
+        it('should only return supported platform directories present in a cordova project dir', function() {
+            var platforms = path.join(temp, 'platforms');
+            var android = path.join(platforms, 'android');
+            var ios = path.join(platforms, 'ios');
+            var wp7 = path.join(platforms, 'wp7');
+            var atari = path.join(platforms, 'atari');
+            shell.mkdir('-p', android);
+            shell.mkdir('-p', ios);
+            shell.mkdir('-p', wp7);
+            shell.mkdir('-p', atari);
+            var res = util.listPlatforms(temp);
+            expect(res.length).toEqual(3);
+            expect(res.indexOf('atari')).toEqual(-1);
+        });
+    });
+    describe('findPlugins method', function() {
+        afterEach(function() {
+            shell.rm('-rf', temp);
+        });
+        it('should only return plugin directories present in a cordova project dir', function() {
+            var plugins = path.join(temp, 'plugins');
+            var android = path.join(plugins, 'android');
+            var ios = path.join(plugins, 'ios');
+            var wp7 = path.join(plugins, 'wp7');
+            var atari = path.join(plugins, 'atari');
+            shell.mkdir('-p', android);
+            shell.mkdir('-p', ios);
+            shell.mkdir('-p', wp7);
+            shell.mkdir('-p', atari);
+            var res = util.findPlugins(plugins);
+            expect(res.length).toEqual(4);
+        });
+        it('should not return ".svn" directories', function() {
+            var plugins = path.join(temp, 'plugins');
+            var android = path.join(plugins, 'android');
+            var ios = path.join(plugins, 'ios');
+            var svn = path.join(plugins, '.svn');
+            shell.mkdir('-p', android);
+            shell.mkdir('-p', ios);
+            shell.mkdir('-p', svn);
+            var res = util.findPlugins(plugins);
+            expect(res.length).toEqual(2);
+            expect(res.indexOf('.svn')).toEqual(-1);
+        });
+        it('should not return "CVS" directories', function() {
+            var plugins = path.join(temp, 'plugins');
+            var android = path.join(plugins, 'android');
+            var ios = path.join(plugins, 'ios');
+            var cvs = path.join(plugins, 'CVS');
+            shell.mkdir('-p', android);
+            shell.mkdir('-p', ios);
+            shell.mkdir('-p', cvs);
+            var res = util.findPlugins(plugins);
+            expect(res.length).toEqual(2);
+            expect(res.indexOf('CVS')).toEqual(-1);
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/wrappers.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/wrappers.spec.js b/cordova-lib/spec-cordova/wrappers.spec.js
new file mode 100644
index 0000000..2afbe9b
--- /dev/null
+++ b/cordova-lib/spec-cordova/wrappers.spec.js
@@ -0,0 +1,40 @@
+var Q = require('q'),
+    cordova = require('../cordova');
+
+describe('callback wrapper', function() {
+    var calls = ['prepare', 'build', 'create', 'emulate', 'plugin', 'platform', 'compile', 'run'];
+    for (var i = 0; i < calls.length; i++) {
+        var call = calls[i];
+
+        describe('`' + call + '`', function() {
+            var raw;
+            beforeEach(function() {
+                raw = spyOn(cordova.raw, call);
+            });
+
+            it('should work with no callback and success', function() {
+                raw.andReturn(Q());
+                cordova[call]();
+                expect(raw).toHaveBeenCalled();
+            });
+
+            it('should call the callback on success', function(done) {
+                raw.andReturn(Q());
+                cordova[call](function(err) {
+                    expect(err).toBeUndefined();
+                    done();
+                });
+            });
+
+            it('should call the callback with the error on failure', function(done) {
+                var err = new Error('junk');
+                raw.andReturn(Q.reject(err));
+                cordova[call](function(e) {
+                    expect(e).toEqual(err);
+                    done();
+                });
+            });
+        });
+    }
+});
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/xml-helpers.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/xml-helpers.spec.js b/cordova-lib/spec-cordova/xml-helpers.spec.js
new file mode 100644
index 0000000..6af8c4b
--- /dev/null
+++ b/cordova-lib/spec-cordova/xml-helpers.spec.js
@@ -0,0 +1,137 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var path = require('path')
+  , xml_helpers = require('../src/xml-helpers')
+  , et = require('elementtree')
+
+  , title = et.XML('<title>HELLO</title>')
+  , usesNetworkOne = et.XML('<uses-permission ' +
+            'android:name="PACKAGE_NAME.permission.C2D_MESSAGE"/>')
+  , usesNetworkTwo = et.XML("<uses-permission android:name=\
+            \"PACKAGE_NAME.permission.C2D_MESSAGE\" />")
+  , usesReceive = et.XML("<uses-permission android:name=\
+            \"com.google.android.c2dm.permission.RECEIVE\"/>")
+  , helloTagOne = et.XML("<h1>HELLO</h1>")
+  , goodbyeTag = et.XML("<h1>GOODBYE</h1>")
+  , helloTagTwo = et.XML("<h1>  HELLO  </h1>");
+
+
+describe('xml-helpers', function(){
+    describe('parseElementtreeSync', function() {
+        it('should parse xml with a byte order mark', function() {
+            var xml_path = path.join(__dirname, 'fixtures', 'projects', 'windows', 'bom_test.xml');
+            expect(function() {
+                xml_helpers.parseElementtreeSync(xml_path);
+            }).not.toThrow();
+        })
+    });
+    describe('equalNodes', function() {
+        it('should return false for different tags', function(){
+            expect(xml_helpers.equalNodes(usesNetworkOne, title)).toBe(false);
+        });
+
+        it('should return true for identical tags', function(){
+            expect(xml_helpers.equalNodes(usesNetworkOne, usesNetworkTwo)).toBe(true);
+        });
+
+        it('should return false for different attributes', function(){
+            expect(xml_helpers.equalNodes(usesNetworkOne, usesReceive)).toBe(false);
+        });
+
+        it('should distinguish between text', function(){
+            expect(xml_helpers.equalNodes(helloTagOne, goodbyeTag)).toBe(false);
+        });
+
+        it('should ignore whitespace in text', function(){
+            expect(xml_helpers.equalNodes(helloTagOne, helloTagTwo)).toBe(true);
+        });
+
+        describe('should compare children', function(){
+            it('by child quantity', function(){
+                var one = et.XML('<i><b>o</b></i>'),
+                    two = et.XML('<i><b>o</b><u></u></i>');
+
+                expect(xml_helpers.equalNodes(one, two)).toBe(false);
+            });
+
+            it('by child equality', function(){
+                var one = et.XML('<i><b>o</b></i>'),
+                    two = et.XML('<i><u></u></i>'),
+                    uno = et.XML('<i>\n<b>o</b>\n</i>');
+
+                expect(xml_helpers.equalNodes(one, uno)).toBe(true);
+                expect(xml_helpers.equalNodes(one, two)).toBe(false);
+            });
+        });
+    });
+    describe('pruneXML', function() {
+        var config_xml;
+
+        beforeEach(function() {
+            config_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'projects', 'android', 'res', 'xml', 'config.xml'));
+        });
+
+        it('should remove any children that match the specified selector', function() {
+            var children = config_xml.findall('plugins/plugin');
+            xml_helpers.pruneXML(config_xml, children, 'plugins');
+            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
+        });
+        it('should do nothing if the children cannot be found', function() {
+            var children = [title];
+            xml_helpers.pruneXML(config_xml, children, 'plugins');
+            expect(config_xml.find('plugins').getchildren().length).toEqual(17);
+        });
+        it('should be able to handle absolute selectors', function() {
+            var children = config_xml.findall('plugins/plugin');
+            xml_helpers.pruneXML(config_xml, children, '/cordova/plugins');
+            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
+        });
+        it('should be able to handle absolute selectors with wildcards', function() {
+            var children = config_xml.findall('plugins/plugin');
+            xml_helpers.pruneXML(config_xml, children, '/*/plugins');
+            expect(config_xml.find('plugins').getchildren().length).toEqual(0);
+        });
+    });
+
+    describe('graftXML', function() {
+        var config_xml, plugin_xml;
+
+        beforeEach(function() {
+            config_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'projects', 'android', 'res', 'xml', 'config.xml'));
+            plugin_xml = xml_helpers.parseElementtreeSync(path.join(__dirname, 'fixtures', 'plugins', 'ChildBrowser', 'plugin.xml'));
+        });
+
+        it('should add children to the specified selector', function() {
+            var children = plugin_xml.find('config-file').getchildren();
+            xml_helpers.graftXML(config_xml, children, 'plugins');
+            expect(config_xml.find('plugins').getchildren().length).toEqual(19);
+        });
+        it('should be able to handle absolute selectors', function() {
+            var children = plugin_xml.find('config-file').getchildren();
+            xml_helpers.graftXML(config_xml, children, '/cordova');
+            expect(config_xml.findall('access').length).toEqual(3);
+        });
+        it('should be able to handle absolute selectors with wildcards', function() {
+            var children = plugin_xml.find('config-file').getchildren();
+            xml_helpers.graftXML(config_xml, children, '/*');
+            expect(config_xml.findall('access').length).toEqual(3);
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/ConfigParser.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/ConfigParser.js b/cordova-lib/src/cordova/ConfigParser.js
new file mode 100644
index 0000000..067c30f
--- /dev/null
+++ b/cordova-lib/src/cordova/ConfigParser.js
@@ -0,0 +1,163 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var et = require('elementtree'),
+    xml= require('./xml-helpers'),
+    CordovaError = require('./CordovaError'),
+    fs = require('fs');
+
+/** Wraps a config.xml file */
+function ConfigParser(path) {
+    this.path = path;
+    try {
+        this.doc = xml.parseElementtreeSync(path);
+    } catch (e) {
+        console.error('Parsing '+path+' failed');
+        throw e;
+    }
+    var r = this.doc.getroot();
+    if (r.tag !== 'widget') {
+        throw new CordovaError(path + ' has incorrect root node name (expected "widget", was "' + r.tag + '")');
+    }
+}
+
+function getNodeTextSafe(el) {
+    return el && el.text && el.text.trim();
+}
+
+function findOrCreate(doc, name) {
+    var ret = doc.find(name);
+    if (!ret) {
+        ret = new et.Element(name);
+        doc.getroot().append(content);
+    }
+    return ret;
+}
+
+ConfigParser.prototype = {
+    packageName: function(id) {
+        return this.doc.getroot().attrib['id'];
+    },
+    setPackageName: function(id) {
+        this.doc.getroot().attrib['id'] = id;
+    },
+    name: function() {
+        return getNodeTextSafe(this.doc.find('name'));
+    },
+    setName: function(name) {
+        var el = findOrCreate(this.doc, 'name');
+        el.text = name;
+    },
+    description: function() {
+        return this.doc.find('description').text.trim();
+    },
+    setDescription: function() {
+        this.doc.find('description').text = name;
+        var el = findOrCreate(this.doc, 'description');
+    },
+    version: function() {
+        return this.doc.getroot().attrib['version'];
+    },
+    android_versionCode: function() {
+        return this.doc.getroot().attrib['android-versionCode'];
+    },
+    ios_CFBundleVersion: function() {
+        return this.doc.getroot().attrib['ios-CFBundleVersion'];
+    },
+    setVersion: function(value) {
+        this.doc.getroot().attrib['version'] = value;
+    },
+    author: function() {
+        return getNodeTextSafe(this.doc.find('author'));
+    },
+    getPreference: function(name) {
+        var preferences = this.doc.findall('preference');
+        var ret = null;
+        preferences.forEach(function (preference) {
+            // Take the last one that matches.
+            if (preference.attrib.name.toLowerCase() === name.toLowerCase()) {
+                ret = preference.attrib.value;
+            }
+        });
+        return ret;
+    },
+    /**
+     * Returns all icons for the platform specified.
+     * @param  {String} platform The platform.
+     * @return {Array} Icons for the platform specified.
+     */
+    getIcons: function(platform) {
+        var ret = [];
+            iconElements = [];
+
+        if (platform) { // platform specific icons
+            this.doc.findall('platform[@name=\'' + platform + '\']/icon').forEach(function(elt){
+                elt.platform = platform; // mark as platform specific icon
+                iconElements.push(elt)
+            });
+        }
+        // root level icons
+        iconElements = iconElements.concat(this.doc.findall('icon'));
+        // parse icon elements
+        iconElements.forEach(function (elt) {
+            var icon = {};
+            icon.src = elt.attrib.src;
+            icon.density = elt.attrib['density'] || elt.attrib['cdv:density'] || elt.attrib['gap:density'];
+            icon.platform = elt.platform || null; // null means icon represents default icon (shared between platforms)
+            icon.width = elt.attrib.width;
+            icon.height = elt.attrib.height;
+            // If one of width or Height is undefined, assume they are equal.
+            icon.width = icon.width || icon.height;
+            icon.height = icon.height || icon.width;
+
+            // default icon
+            if (!icon.width && !icon.height && !icon.density) {
+                ret.defaultIcon = icon;
+            }
+            ret.push(icon);
+        });
+
+        /**
+         * Returns icon with specified width and height
+         * @param  {number} w  Width of icon
+         * @param  {number} h  Height of icon
+         * @return {Icon}      Icon object or null if not found
+         */
+        ret.getIconBySize = function(w, h){
+            // If only one of width and height is given
+            // then we assume that they are equal.
+            var width = w || h, height = h || w;
+            for (var idx in this) {
+                var icon = this[idx];
+                if (width == icon.width && height == icon.width) return icon;
+            }
+            return null;
+        };
+        /** Returns default icons */
+        ret.getDefault = function() {
+            return ret.defaultIcon;
+        }
+
+        return ret;
+    },
+    write:function() {
+        fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
+    }
+};
+
+module.exports = ConfigParser;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/CordovaError.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/CordovaError.js b/cordova-lib/src/cordova/CordovaError.js
new file mode 100644
index 0000000..5576e06
--- /dev/null
+++ b/cordova-lib/src/cordova/CordovaError.js
@@ -0,0 +1,31 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+
+// A derived exception class. See usage example in cli.js
+// Based on:
+// stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/8460753#8460753
+function CordovaError(message) {
+    Error.captureStackTrace(this, this.constructor);
+    this.name = this.constructor.name;
+    this.message = message;
+}
+CordovaError.prototype.__proto__ = Error.prototype;
+
+module.exports = CordovaError;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/build.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/build.js b/cordova-lib/src/cordova/build.js
new file mode 100644
index 0000000..5a0f0d3
--- /dev/null
+++ b/cordova-lib/src/cordova/build.js
@@ -0,0 +1,47 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova_util      = require('./util'),
+    Q                 = require('q'),
+    hooker            = require('./hooker');
+
+// Returns a promise.
+module.exports = function build(options) {
+    var projectRoot = cordova_util.cdProjectRoot();
+
+    if (!options) {
+        options = {
+            verbose: false,
+            platforms: [],
+            options: []
+        };
+    }
+
+    options = cordova_util.preProcessOptions(options);
+
+    // fire build hooks
+    var hooks = new hooker(projectRoot);
+    return hooks.fire('before_build', options)
+    .then(function() {
+        return require('../cordova').raw.prepare(options);
+    }).then(function() {
+        return require('../cordova').raw.compile(options);
+    }).then(function() {
+        return hooks.fire('after_build', options);
+    });
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/compile.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/compile.js b/cordova-lib/src/cordova/compile.js
new file mode 100644
index 0000000..857c3a5
--- /dev/null
+++ b/cordova-lib/src/cordova/compile.js
@@ -0,0 +1,45 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+/*global require: true, module: true, process: true*/
+/*jslint sloppy: true, white: true, newcap: true */
+
+var path              = require('path'),
+    cordova_util      = require('./util'),
+    hooker            = require('./hooker'),
+    superspawn        = require('./superspawn');
+
+// Returns a promise.
+module.exports = function compile(options) {
+    var projectRoot = cordova_util.cdProjectRoot();
+    options = cordova_util.preProcessOptions(options);
+
+    var hooks = new hooker(projectRoot);
+    var ret = hooks.fire('before_compile', options);
+    options.platforms.forEach(function(platform) {
+        ret = ret.then(function() {
+            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'build');
+            return superspawn.spawn(cmd, options.options, { stdio: 'inherit', printCommand: true });
+        });
+    });
+    ret = ret.then(function() {
+        return hooks.fire('after_compile', options);
+    });
+    return ret;
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/config.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/config.js b/cordova-lib/src/cordova/config.js
new file mode 100644
index 0000000..d0c8d9a
--- /dev/null
+++ b/cordova-lib/src/cordova/config.js
@@ -0,0 +1,82 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var path          = require('path'),
+    fs            = require('fs'),
+    url           = require('url'),
+    shell         = require('shelljs');
+
+// Map of project_root -> JSON
+var configCache = {};
+var autoPersist = true;
+
+function config(project_root, opts) {
+    var json = config.read(project_root);
+    for (var p in opts) {
+        json[p] = opts[p];
+    }
+    if (autoPersist) {
+        config.write(project_root, json);
+    } else {
+        configCache[project_root] = JSON.stringify(json);
+    }
+    return json;
+};
+
+config.setAutoPersist = function(value) {
+    autoPersist = value;
+};
+
+config.read = function get_config(project_root) {
+    var data = configCache[project_root];
+    if (data === undefined) {
+        var configPath = path.join(project_root, '.cordova', 'config.json');
+        if (!fs.existsSync(configPath)) {
+            data = '{}';
+        } else {
+            data = fs.readFileSync(configPath, 'utf-8');
+        }
+    }
+    configCache[project_root] = data;
+    return JSON.parse(data);
+};
+
+config.write = function set_config(project_root, json) {
+    var configPath = path.join(project_root, '.cordova', 'config.json');
+    var contents = JSON.stringify(json, null, 4);
+    configCache[project_root] = contents;
+    // Don't write the file for an empty config.
+    if (contents != '{}' || fs.existsSync(configPath)) {
+        shell.mkdir('-p', path.join(project_root, '.cordova'));
+        fs.writeFileSync(configPath, contents, 'utf-8');
+    }
+    return json;
+};
+
+config.has_custom_path = function(project_root, platform) {
+    var json = config.read(project_root);
+    if (json.lib && json.lib[platform]) {
+        var uri = url.parse(json.lib[platform].uri);
+        if (!(uri.protocol)) return uri.path;
+        else if (uri.protocol && uri.protocol[1] ==':') return uri.href;
+    }
+    return false;
+};
+
+module.exports = config;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/cordova.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/cordova.js b/cordova-lib/src/cordova/cordova.js
new file mode 100644
index 0000000..687392b
--- /dev/null
+++ b/cordova-lib/src/cordova/cordova.js
@@ -0,0 +1,68 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var cordova_events = require('./src/events');
+var cordova_util = require('./src/util');
+
+var off = function() {
+    cordova_events.removeListener.apply(cordova_events, arguments);
+};
+
+var emit = function() {
+    cordova_events.emit.apply(cordova_events, arguments);
+};
+
+exports = module.exports = {
+    on:        function() {
+        cordova_events.on.apply(cordova_events, arguments);
+    },
+    off:       off,
+    removeListener:off,
+    removeAllListeners:function() {
+        cordova_events.removeAllListeners.apply(cordova_events, arguments);
+    },
+    emit:      emit,
+    trigger:   emit,
+    raw: {}
+};
+
+exports.findProjectRoot = function(opt_startDir) {
+    return cordova_util.isCordova(opt_startDir);
+}
+
+// Each of these APIs takes a final parameter that is a callback function.
+// The callback is passed the error object upon failure, or undefined upon success.
+// To use a promise instead, call the APIs via cordova.raw.FOO(), which returns
+// a promise instead of using a final-parameter-callback.
+var addModuleProperty = cordova_util.addModuleProperty;
+addModuleProperty(module, 'prepare', './src/prepare', true);
+addModuleProperty(module, 'build', './src/build', true);
+addModuleProperty(module, 'help', './src/help');
+addModuleProperty(module, 'config', './src/config');
+addModuleProperty(module, 'create', './src/create', true);
+addModuleProperty(module, 'emulate', './src/emulate', true);
+addModuleProperty(module, 'plugin', './src/plugin', true);
+addModuleProperty(module, 'plugins', './src/plugin', true);
+addModuleProperty(module, 'serve', './src/serve');
+addModuleProperty(module, 'platform', './src/platform', true);
+addModuleProperty(module, 'platforms', './src/platform', true);
+addModuleProperty(module, 'compile', './src/compile', true);
+addModuleProperty(module, 'run', './src/run', true);
+addModuleProperty(module, 'info', './src/info', true);
+
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/create.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/create.js b/cordova-lib/src/cordova/create.js
new file mode 100644
index 0000000..025e56b
--- /dev/null
+++ b/cordova-lib/src/cordova/create.js
@@ -0,0 +1,220 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var path          = require('path'),
+    fs            = require('fs'),
+    shell         = require('shelljs'),
+    platforms     = require('../platforms'),
+    help          = require('./help'),
+    events        = require('./events'),
+    config        = require('./config'),
+    lazy_load     = require('./lazy_load'),
+    Q             = require('q'),
+    CordovaError  = require('./CordovaError'),
+    ConfigParser = require('./ConfigParser'),
+    util          = require('./util');
+
+var DEFAULT_NAME = "HelloCordova",
+    DEFAULT_ID   = "io.cordova.hellocordova";
+
+/**
+ * Usage:
+ * @dir - directory where the project will be created. Required.
+ * @id - app id. Optional, default is DEFAULT_ID.
+ * @name - app name. Optional, default is DEFAULT_NAME.
+ * @cfg - extra config to be saved in .cordova/config.json
+ **/
+// Returns a promise.
+module.exports = create;
+function create(dir, id, name, cfg) {
+    if (!dir ) {
+        return Q(help());
+    }
+
+    // Massage parameters
+    if (typeof cfg == 'string') {
+        cfg = JSON.parse(cfg);
+    }
+    cfg = cfg || {};
+    id = id || cfg.id || DEFAULT_ID;
+    name = name || cfg.name || DEFAULT_NAME;
+
+    // Make absolute.
+    dir = path.resolve(dir);
+
+    events.emit('log', 'Creating a new cordova project with name "' + name + '" and id "' + id + '" at location "' + dir + '"');
+
+    var www_dir = path.join(dir, 'www');
+
+    // dir must be either empty or not exist at all.
+
+    // dir must be either empty except for .cordova config file or not exist at all..
+    var sanedircontents = function (d) {
+        var contents = fs.readdirSync(d);
+        if (contents.length === 0) {
+            return true;
+        } else if (contents.length == 1) {
+            if (contents[0] == '.cordova') {
+                return true;
+            }
+        }
+        return false;
+    };
+
+    if (fs.existsSync(dir) && !sanedircontents(dir)) {
+        return Q.reject(new CordovaError('Path already exists and is not empty: ' + dir));
+    }
+
+    // Read / Write .cordova/config.json file if necessary.
+    var config_json = config(dir, cfg);
+
+    var p;
+    var symlink = false; // Whether to symlink the www dir instead of copying.
+    var www_parent_dir;
+    var custom_config_xml;
+    var custom_merges;
+    var custom_hooks;
+
+    if (config_json.lib && config_json.lib.www) {
+        events.emit('log', 'Using custom www assets from '+config_json.lib.www.uri);
+        // TODO (kamrik): extend lazy_load for retrieval without caching to allow net urls for --src.
+        var www_version = config_json.lib.www.version || 'not_versioned';
+        var www_id = config_json.lib.www.id || 'dummy_id';
+        symlink  = !!config_json.lib.www.link;
+        if ( www_dir.indexOf(path.resolve(config_json.lib.www.uri)) === 0 ) {
+            throw new CordovaError(
+                'Project must not be created inside the www assets dir.' +
+                '\n    project dir:\t' + dir +
+                '\n    www assets dir:\t' + config_json.lib.www.uri
+            );
+        }
+        if(symlink) {
+            p = Q(config_json.lib.www.uri);
+            events.emit('verbose', 'Symlinking custom www assets into "' + www_dir + '"');
+        } else {
+            p = lazy_load.custom(config_json.lib.www.uri, www_id, 'www', www_version)
+            .then(function(d) {
+                events.emit('verbose', 'Copying custom www assets into "' + www_dir + '"');
+                return d;
+            });
+        }
+    } else {
+        // No custom www - use stock cordova-hello-world-app.
+        events.emit('verbose', 'Using stock cordova hello-world application.');
+        p = lazy_load.cordova('www')
+        .then(function(d) {
+            events.emit('verbose', 'Copying stock Cordova www assets into "' + www_dir + '"');
+            return d;
+        });
+    }
+
+    return p.then(function(www_lib) {
+        if (!fs.existsSync(www_lib)) {
+            throw new CordovaError('Could not find directory: '+www_lib);
+        }
+        // Keep going into child "www" folder if exists in stock app package.
+        while (fs.existsSync(path.join(www_lib, 'www'))) {
+            www_parent_dir = www_lib;
+            www_lib = path.join(www_lib, 'www');
+        }
+
+        // Find if we also have custom merges and config.xml as siblings of custom www.
+        if (www_parent_dir && config_json.lib && config_json.lib.www) {
+            custom_config_xml = path.join(www_parent_dir, 'config.xml');
+            if ( !fs.existsSync(custom_config_xml) ) {
+                custom_config_xml = null;
+            }
+            custom_merges = path.join(www_parent_dir, 'merges');
+            if ( !fs.existsSync(custom_merges) ) {
+                custom_merges = null;
+            }
+            custom_hooks = path.join(www_parent_dir, 'hooks');
+            if ( !fs.existsSync(custom_hooks) ) {
+                custom_hooks = null;
+            }
+        }
+
+        var dirAlreadyExisted = fs.existsSync(dir);
+        if (!dirAlreadyExisted) {
+            shell.mkdir(dir);
+        }
+        if (symlink) {
+            try {
+                fs.symlinkSync(www_lib, www_dir, 'dir');
+                if (custom_merges) {
+                    fs.symlinkSync(custom_merges, path.join(dir, 'merges'), 'dir');
+                }
+                if (custom_hooks) {
+                    fs.symlinkSync(custom_hooks, path.join(dir, 'hooks'), 'dir');
+                }
+                if (custom_config_xml) {
+                    fs.symlinkSync(custom_config_xml, path.join(dir, 'config.xml'));
+                }
+            } catch (e) {
+                if (!dirAlreadyExisted) {
+                    fs.rmdirSync(dir);
+                }
+                if (process.platform.slice(0, 3) == 'win' && e.code == 'EPERM')  {
+                    throw new CordovaError('Symlinks on Windows require Administrator privileges');
+                }
+                throw e;
+            }
+        } else {
+            shell.mkdir(www_dir);
+            shell.cp('-R', path.join(www_lib, '*'), www_dir);
+            if (custom_merges) {
+                var merges_dir = path.join(dir, 'merges');
+                shell.mkdir(merges_dir);
+                shell.cp('-R', path.join(custom_merges, '*'), merges_dir);
+            }
+            if (custom_hooks) {
+                var hooks_dir = path.join(dir, 'hooks');
+                shell.mkdir(hooks_dir);
+                shell.cp('-R', path.join(custom_hooks, '*'), hooks_dir);
+            }
+            if (custom_config_xml) {
+                shell.cp(custom_config_xml, path.join(dir, 'config.xml'));
+            }
+
+        }
+
+        // Create basic project structure.
+        shell.mkdir(path.join(dir, 'platforms'));
+        if ( !custom_merges) {
+            shell.mkdir(path.join(dir, 'merges'));
+        }
+        shell.mkdir(path.join(dir, 'plugins'));
+        shell.mkdir(path.join(dir, 'hooks'));
+
+        // Add hooks README.md
+        shell.cp(path.join(__dirname, '..', 'templates', 'hooks-README.md'), path.join(dir, 'hooks', 'README.md'));
+
+        var configPath = util.projectConfig(dir);
+        // Add template config.xml for apps that are missing it
+        if (!fs.existsSync(configPath)) {
+            var template_config_xml = path.join(__dirname, '..', 'templates', 'config.xml');
+            shell.cp(template_config_xml, configPath);
+            // Write out id and name to config.xml
+            var config = new ConfigParser(configPath);
+            config.setPackageName(id);
+            config.setName(name);
+            config.write();
+        }
+    });
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/emulate.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/emulate.js b/cordova-lib/src/cordova/emulate.js
new file mode 100644
index 0000000..c1d3a10
--- /dev/null
+++ b/cordova-lib/src/cordova/emulate.js
@@ -0,0 +1,50 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+/*global require: true, module: true, process: true*/
+/*jslint sloppy: true, white: true, newcap: true */
+
+var cordova_util      = require('./util'),
+    path              = require('path'),
+    hooker            = require('./hooker'),
+    superspawn        = require('./superspawn'),
+    Q                 = require('q');
+
+// Returns a promise.
+module.exports = function emulate(options) {
+    var projectRoot = cordova_util.cdProjectRoot();
+    options = cordova_util.preProcessOptions(options);
+
+    var hooks = new hooker(projectRoot);
+    return hooks.fire('before_emulate', options)
+    .then(function() {
+        // Run a prepare first!
+        return require('../cordova').raw.prepare(options.platforms);
+    }).then(function() {
+        // Deploy in parallel (output gets intermixed though...)
+        return Q.all(options.platforms.map(function(platform) {
+            var cmd = path.join(projectRoot, 'platforms', platform, 'cordova', 'run');
+            var args = ['--emulator'].concat(options.options);
+
+            return superspawn.spawn(cmd, args, {stdio: 'inherit', printCommand: true});
+        }));
+    }).then(function() {
+        return hooks.fire('after_emulate', options);
+    });
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/events.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/events.js b/cordova-lib/src/cordova/events.js
new file mode 100644
index 0000000..be40fec
--- /dev/null
+++ b/cordova-lib/src/cordova/events.js
@@ -0,0 +1,23 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var events = require('events');
+
+var emitter = new events.EventEmitter();
+
+module.exports = emitter;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/src/cordova/hooker.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/hooker.js b/cordova-lib/src/cordova/hooker.js
new file mode 100644
index 0000000..e4ccaff
--- /dev/null
+++ b/cordova-lib/src/cordova/hooker.js
@@ -0,0 +1,161 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var util  = require('./util'),
+    fs    = require('fs'),
+    os    = require('os'),
+    events= require('./events'),
+    superspawn = require('./superspawn'),
+    CordovaError = require('./CordovaError'),
+    Q     = require('q'),
+    path  = require('path'),
+    _ = require('underscore');
+
+module.exports = function hooker(root) {
+    var r = util.isCordova(root);
+    if (!r) throw new CordovaError('Not a Cordova project ("'+root+'"), can\'t use hooks.');
+    else this.root = r;
+};
+
+// Returns a promise.
+module.exports.fire = function global_fire(hook, opts) {
+    opts = opts || {};
+    var handlers = events.listeners(hook);
+    return execute_handlers_serially(handlers, opts);
+};
+
+function compareNumbers(a, b) {
+    return isNaN (parseInt(a))
+        ? a.toLowerCase().localeCompare(b.toLowerCase ? b.toLowerCase(): b)
+        : parseInt(a) > parseInt(b) ? 1 : parseInt(a) < parseInt(b) ? -1 : 0;
+}
+
+module.exports.prototype = {
+    // Returns a promise.
+    fire:function fire(hook, opts) {
+        var root = this.root;
+        opts = opts || {};
+        opts.root = root;
+
+        function fireHooksInDir(dir) {
+            if (!(fs.existsSync(dir))) {
+                return Q();
+            } else {
+                var scripts = fs.readdirSync(dir).sort(compareNumbers).filter(function(s) {
+                    return s[0] != '.';
+                });
+                return execute_scripts_serially(scripts, root, dir, opts);
+            }
+        }
+        // Fire JS hook for the event
+        // These ones need to "serialize" events, that is, each handler attached to the event needs to finish processing (if it "opted in" to the callback) before the next one will fire.
+        var handlers = events.listeners(hook);
+        return execute_handlers_serially(handlers, opts)
+        .then(function() {
+            return fireHooksInDir(path.join(root, '.cordova', 'hooks', hook));
+        }).then(function() {
+            return fireHooksInDir(path.join(root, 'hooks', hook));
+        });
+    }
+};
+
+function extractSheBangInterpreter(fullpath) {
+    var hookFd = fs.openSync(fullpath, "r");
+    try {
+        // this is a modern cluster size. no need to read less
+        var fileData = new Buffer (4096);
+        var octetsRead = fs.readSync(hookFd, fileData, 0, 4096, 0);
+        var fileChunk = fileData.toString();
+    } finally {
+        fs.closeSync(hookFd);
+    }
+
+    var hookCmd, shMatch;
+    // Filter out /usr/bin/env so that "/usr/bin/env node" works like "node".
+    var shebangMatch = fileChunk.match(/^#!(?:\/usr\/bin\/env )?([^\r\n]+)/m);
+    if (octetsRead == 4096 && !fileChunk.match(/[\r\n]/))
+        events.emit('warn', 'shebang is too long for "' + fullpath + '"');
+    if (shebangMatch)
+        hookCmd = shebangMatch[1];
+    // Likewise, make /usr/bin/bash work like "bash".
+    if (hookCmd)
+        shMatch = hookCmd.match(/bin\/((?:ba)?sh)$/)
+    if (shMatch)
+        hookCmd = shMatch[1]
+    return hookCmd;
+}
+
+// Returns a promise.
+function execute_scripts_serially(scripts, root, dir, opts) {
+    opts = opts || {};
+    var isWindows = os.platform().slice(0, 3) === 'win';
+    if (scripts.length) {
+        var s = scripts.shift();
+        var fullpath = path.join(dir, s);
+        if (fs.statSync(fullpath).isDirectory()) {
+            events.emit('verbose', 'skipped directory "' + fullpath + '" within hook directory');
+            return execute_scripts_serially(scripts, root, dir, opts); // skip directories if they're in there.
+        } else {
+            var command = fullpath;
+            var args = [root];
+            if (os.platform().slice(0, 3) == 'win') {
+                // TODO: Make shebang sniffing a setting (not everyone will want this).
+                var interpreter = extractSheBangInterpreter(fullpath);
+                // we have shebang, so try to run this script using correct interpreter
+                if (interpreter) {
+                    args.unshift(command);
+                    command = interpreter;
+                }
+            }
+
+            var execOpts = {cwd: root, printCommand: true, stdio: 'inherit'};
+            execOpts.env = {};
+            execOpts.env.CORDOVA_VERSION = require('../package').version;
+            execOpts.env.CORDOVA_PLATFORMS = opts.platforms ? opts.platforms.join() : '';
+            execOpts.env.CORDOVA_PLUGINS = opts.plugins?opts.plugins.join():'';
+            execOpts.env.CORDOVA_HOOK = fullpath;
+            execOpts.env.CORDOVA_CMDLINE = process.argv.join(' ');
+
+            return superspawn.spawn(command, args, execOpts)
+            .catch(function(err) {
+                // Don't treat non-executable files as errors. They could be READMEs, or Windows-only scripts.
+                if (!isWindows && err.code == 'EACCES') {
+                    events.emit('verbose', 'skipped non-executable file: ' + fullpath);
+                } else {
+                    throw new CordovaError('Hook failed with error code ' + err.code + ': ' + fullpath);
+                }
+            }).then(function() {
+                return execute_scripts_serially(scripts, root, dir, opts);
+            });
+        }
+    } else {
+        return Q(); // Nothing to do.
+    }
+}
+
+// Returns a promise.
+function execute_handlers_serially(handlers, opts) {
+    if (handlers.length) {
+        // Chain the handlers in series.
+        return handlers.reduce(function(soFar, f) {
+            return soFar.then(function() { return f(opts) });
+        }, Q());
+    } else {
+        return Q(); // Nothing to do.
+    }
+}


[19/24] Remove all cordova-lib files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/hooker.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/hooker.spec.js b/cordova-lib/spec-cordova/hooker.spec.js
deleted file mode 100644
index c85cc59..0000000
--- a/cordova-lib/spec-cordova/hooker.spec.js
+++ /dev/null
@@ -1,261 +0,0 @@
- /**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-**/
-
-
-var cordova = require('../cordova'),
-    hooker = require('../src/hooker'),
-    shell  = require('shelljs'),
-    path   = require('path'),
-    fs     = require('fs'),
-    os     = require('os'),
-    Q      = require('q'),
-    child_process = require('child_process'),
-    helpers = require('./helpers');
-
-var platform = os.platform();
-var tmpDir = helpers.tmpDir('hooks_test');
-var project = path.join(tmpDir, 'project');
-var dotCordova = path.join(project, '.cordova');
-var hooksDir = path.join(project, '.cordova', 'hooks');
-var ext = platform.match(/(win32|win64)/)?'bat':'sh';
-
-
-// copy fixture
-shell.rm('-rf', project);
-shell.mkdir('-p', project);
-shell.cp('-R', path.join(__dirname, 'fixtures', 'base', '*'), project);
-shell.mkdir('-p', dotCordova);
-shell.cp('-R', path.join(__dirname, 'fixtures', 'hooks_' + ext), dotCordova);
-shell.mv(path.join(dotCordova, 'hooks_' + ext), hooksDir);
-shell.chmod('-R', 'ug+x', hooksDir);
-
-
-describe('hooker', function() {
-    it('should throw if provided directory is not a cordova project', function() {
-        expect(function() {
-            new hooker(tmpDir);
-        }).toThrow();
-    });
-});
-
-describe('global (static) fire method', function() {
-    it('should execute listeners serially', function(done) {
-        var test_event = 'foo';
-        var h1_fired = false;
-        var h1 = function() {
-            expect(h2_fired).toBe(false);
-            // Delay 100 ms here to check that h2 is not executed until after
-            // the promise returned by h1 is resolved.
-            var q = Q.delay(100).then(function() {
-                h1_fired = true;
-            });
-            return q;
-        };
-        var h2_fired = false;
-        var h2 = function() {
-            h2_fired = true;
-            expect(h1_fired).toBe(true);
-            return Q();
-        };
-
-        cordova.on(test_event, h1);
-        cordova.on(test_event, h2);
-        hooker.fire(test_event).then(function() {
-            expect(h1_fired).toBe(true);
-            expect(h2_fired).toBe(true);
-            done();
-        });
-    });
-});
-
-describe('module-level hooks', function() {
-    var handler = jasmine.createSpy().andReturn(Q());
-    var test_event = 'before_build';
-    var h;
-
-    beforeEach(function() {
-        h = new hooker(project);
-    });
-
-    afterEach(function() {
-        cordova.removeAllListeners(test_event);
-        handler.reset();
-    });
-
-    it('should fire handlers using cordova.on', function(done) {
-        cordova.on(test_event, handler);
-        h.fire(test_event)
-        .then(function() {
-            expect(handler).toHaveBeenCalled();
-        })
-        .fail(function(err) {
-            expect(err).not.toBeDefined();
-        })
-        .fin(done);
-    });
-
-    it('should pass the project root folder as parameter into the module-level handlers', function(done) {
-        cordova.on(test_event, handler);
-        h.fire(test_event)
-        .then(function() {
-            expect(handler).toHaveBeenCalledWith({root:project});
-        })
-        .fail(function(err) {
-            console.log(err);
-            expect(err).not.toBeDefined();
-        })
-        .fin(done);
-    });
-
-    it('should be able to stop listening to events using cordova.off', function(done) {
-        cordova.on(test_event, handler);
-        cordova.off(test_event, handler);
-        h.fire(test_event)
-        .then(function() {
-            expect(handler).not.toHaveBeenCalled();
-        })
-        .fail(function(err) {
-            console.log(err);
-            expect(err).toBeUndefined();
-        })
-        .fin(done);
-    });
-
-    it('should allow for hook to opt into asynchronous execution and block further hooks from firing using the done callback', function(done) {
-        var h1_fired = false;
-        var h1 = function() {
-            h1_fired = true;
-            expect(h2_fired).toBe(false);
-            return Q();
-        };
-        var h2_fired = false;
-        var h2 = function() {
-            h2_fired = true;
-            expect(h1_fired).toBe(true);
-            return Q();
-        };
-
-        cordova.on(test_event, h1);
-        cordova.on(test_event, h2);
-        h.fire(test_event).then(function() {
-            expect(h1_fired).toBe(true);
-            expect(h2_fired).toBe(true);
-            done();
-        });
-    });
-
-    it('should pass data object that fire calls into async handlers', function(done) {
-        var data = {
-            "hi":"ho",
-            "offtowork":"wego"
-        };
-        var async = function(opts) {
-            data.root = tmpDir;
-            expect(opts).toEqual(data);
-            return Q();
-        };
-        cordova.on(test_event, async);
-        h.fire(test_event, data).then(done);
-    });
-
-    it('should pass data object that fire calls into sync handlers', function(done) {
-        var data = {
-            "hi":"ho",
-            "offtowork":"wego"
-        };
-        var async = function(opts) {
-            data.root = tmpDir;
-            expect(opts).toEqual(data);
-        };
-        cordova.on(test_event, async);
-        h.fire(test_event, data).then(done);
-    });
-});
-
-
-describe('hooks', function() {
-    var h;
-    beforeEach(function() {
-        h = new hooker(project);
-    });
-
-
-    it('should not error if the hook is unrecognized', function(done) {
-        h.fire('CLEAN YOUR SHORTS GODDAMNIT LIKE A BIG BOY!')
-        .fail(function (err) {
-            expect('Call with unrecogized hook ').toBe('successful.\n' + err);
-        })
-        .fin(done);
-    });
-
-    it('should error if any script exits with non-zero code', function(done) {
-        h.fire('fail').then(function() {
-            expect('the call').toBe('a failure');
-        }, function(err) {
-            expect(err).toBeDefined();
-        })
-        .fin(done);
-    });
-
-    it('should execute all scripts in order', function(done) {
-        h.fire('test')
-        .then(function() {
-            var hooksOrderFile = path.join(project, 'hooks_order.txt');
-            var hooksEnvFile = path.join(project, 'hooks_env.json');
-            var hooksParamsFile = path.join(project, 'hooks_params.txt');
-            expect(hooksOrderFile).toExist();
-            expect(hooksEnvFile).toExist();
-            expect(hooksParamsFile).toExist();
-            expect(path.join(project, 'dotted_hook_should_not_fire.txt')).not.toExist();
-
-            var order = fs.readFileSync(hooksOrderFile, 'ascii').replace(/\W/gm, '');
-            expect(order).toBe('ab');
-
-            var params = fs.readFileSync(hooksParamsFile, 'ascii').trim().trim('"');
-            expect(params).toMatch(project.replace(/\\/g, '\\\\'));
-
-            var env = JSON.parse(fs.readFileSync(hooksEnvFile, 'ascii'));
-            expect(env.CORDOVA_VERSION).toEqual(require('../package').version);
-        })
-        .fail(function(err) {
-            console.log(err);
-            expect('Test hook call').toBe('successful');
-        })
-        .fin(done);
-
-    });
-
-    // Cleanup. Must be the last spec. Is there a better place for final cleanup in Jasmine?
-    it('should not fail during cleanup', function() {
-        process.chdir(path.join(__dirname, '..'));  // Non e2e tests assume CWD is repo root.
-        if(ext == 'sh') {
-            //shell.rm('-rf', tmpDir);
-        } else { // Windows:
-            // For some mysterious reason, both shell.rm and RMDIR /S /Q won't
-            // delete the dir on Windows, but they do remove the files leaving
-            // only folders. But the dir is removed just fine by
-            // shell.rm('-rf', tmpDir) at the top of this file with the next
-            // invocation of this test. The benefit of RMDIR /S /Q is that it
-            // doesn't print warnings like shell.rmdir() that look like this:
-            // rm: could not remove directory (code ENOTEMPTY): C:\Users\...
-            var cmd =  'RMDIR /S /Q ' + tmpDir;
-            child_process.exec(cmd);
-        }
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/lazy_load.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/lazy_load.spec.js b/cordova-lib/spec-cordova/lazy_load.spec.js
deleted file mode 100644
index 1a92ee9..0000000
--- a/cordova-lib/spec-cordova/lazy_load.spec.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var lazy_load = require('../src/lazy_load'),
-    config = require('../src/config'),
-    util = require('../src/util'),
-    shell = require('shelljs'),
-    npmconf = require('npmconf');
-    path = require('path'),
-    hooker = require('../src/hooker'),
-    request = require('request'),
-    fs = require('fs'),
-    Q = require('q'),
-    platforms = require('../platforms');
-
-describe('lazy_load module', function() {
-    var custom_path;
-    beforeEach(function() {
-        custom_path = spyOn(config, 'has_custom_path').andReturn(false);
-    });
-    describe('cordova method (loads stock cordova libs)', function() {
-        var custom;
-        beforeEach(function() {
-            custom = spyOn(lazy_load, 'custom').andReturn(Q(path.join('lib','dir')));
-        });
-        it('should throw if platform is not a stock cordova platform', function(done) {
-            lazy_load.cordova('atari').then(function() {
-                expect('this call').toEqual('to fail');
-            }, function(err) {
-                expect('' + err).toContain('Cordova library "atari" not recognized.');
-            }).fin(done);
-        });
-        it('should invoke lazy_load.custom with appropriate url, platform, and version as specified in platforms manifest', function(done) {
-            lazy_load.cordova('android').then(function(dir) {
-                expect(custom).toHaveBeenCalledWith(platforms.android.url + ';a=snapshot;h=' + platforms.android.version + ';sf=tgz', 'cordova', 'android', platforms.android.version);
-                expect(dir).toBeDefined();
-                done();
-            });
-        });
-    });
-
-    describe('custom method (loads custom cordova libs)', function() {
-        var exists, fire, rm;
-        beforeEach(function() {
-            spyOn(shell, 'mkdir');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            exists = spyOn(fs, 'existsSync').andReturn(false);
-            readdir = spyOn(fs, 'readdirSync').andReturn(['somefile.txt']);
-            fire = spyOn(hooker, 'fire').andReturn(Q());
-        });
-
-        it('should callback with no errors and not fire event hooks if library already exists', function(done) {
-            exists.andReturn(true);
-            lazy_load.custom('http://some remote url', 'some id', 'platform X', 'three point five').then(function() {
-                expect(fire).not.toHaveBeenCalled()
-            }, function(err) {
-                expect(err).not.toBeDefined();
-            }).fin(done);
-        });
-        it('should callback with no errors and fire event hooks even if library already exists if the lib url is a local dir', function(done) {
-            exists.andReturn(true);
-            lazy_load.custom('some local dir', 'some id', 'platform X', 'three point six').then(function() {
-                expect(fire).not.toHaveBeenCalled()
-            }, function(err) {
-                expect(err).not.toBeDefined();
-            }).fin(done);
-        });
-
-        describe('remote URLs for libraries', function() {
-            var npmConfProxy;
-            var req,
-                load_spy,
-                events = {},
-                fakeRequest = {
-                    on: jasmine.createSpy().andCallFake(function(event, cb) {
-                        events[event] = cb;
-                        return fakeRequest;
-                    }),
-                    pipe: jasmine.createSpy().andCallFake(function() { return fakeRequest; })
-                };
-            beforeEach(function() {
-                npmConfProxy = null;
-                events = {};
-                fakeRequest.on.reset();
-                fakeRequest.pipe.reset();
-                req = spyOn(request, 'get').andCallFake(function() {
-                    // Fire the 'end' event shortly.
-                    setTimeout(function() {
-                        events['end']();
-                    }, 10);
-                    return fakeRequest;
-                });
-                load_spy = spyOn(npmconf, 'load').andCallFake(function(cb) { cb(null, { get: function() { return npmConfProxy }}); });
-            });
-
-            it('should call request with appopriate url params', function(done) {
-                var url = 'https://github.com/apache/someplugin';
-                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
-                    expect(req).toHaveBeenCalledWith({
-                        uri:url
-                    }, jasmine.any(Function));
-                }, function(err) {
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-            it('should take into account https-proxy npm configuration var if exists for https:// calls', function(done) {
-                var proxy = 'https://somelocalproxy.com';
-                npmConfProxy = proxy;
-                var url = 'https://github.com/apache/someplugin';
-                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
-                    expect(req).toHaveBeenCalledWith({
-                        uri:url,
-                        proxy:proxy
-                    }, jasmine.any(Function));
-                }, function(err) {
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-            it('should take into account proxy npm config var if exists for http:// calls', function(done) {
-                var proxy = 'http://somelocalproxy.com';
-                npmConfProxy = proxy;
-                var url = 'http://github.com/apache/someplugin';
-                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
-                    expect(req).toHaveBeenCalledWith({
-                        uri:url,
-                        proxy:proxy
-                    }, jasmine.any(Function));
-                }, function(err) {
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-        });
-
-        describe('local paths for libraries', function() {
-            it('should return the local path, no symlink', function(done) {
-                lazy_load.custom('/some/random/lib', 'id', 'X', 'three point eight').then(function(dir) {
-                    expect(dir).toEqual('/some/random/lib');
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-            it('should not file download hook', function(done) {
-                lazy_load.custom('/some/random/lib', 'id', 'X', 'three point nine').then(function() {
-                    expect(fire).not.toHaveBeenCalledWith('after_library_download', {platform:'X',url:'/some/random/lib',id:'id',version:'three point nine',path:'/some/random/lib', symlink:false});
-                }, function(err) {
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-        });
-    });
-
-    describe('based_on_config method', function() {
-        var cordova, custom;
-        beforeEach(function() {
-            cordova = spyOn(lazy_load, 'cordova').andReturn(Q());
-            custom = spyOn(lazy_load, 'custom').andReturn(Q());
-        });
-        it('should invoke custom if a custom lib is specified', function(done) {
-            var read = spyOn(config, 'read').andReturn({
-                lib:{
-                    maybe:{
-                        uri:'you or eye?',
-                        id:'eye dee',
-                        version:'four point twenty'
-                    }
-                }
-            });
-            var p = '/some/random/custom/path';
-            custom_path.andReturn(p);
-            lazy_load.based_on_config('yup', 'maybe').then(function() {
-                expect(custom).toHaveBeenCalledWith('you or eye?', 'eye dee', 'maybe', 'four point twenty');
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-        it('should invoke cordova if no custom lib is specified', function(done) {
-            lazy_load.based_on_config('yup', 'ios').then(function() {
-                expect(cordova).toHaveBeenCalledWith('ios');
-            }, function(err) {
-                expect(err).toBeUndefined();
-            }).fin(done);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/metadata/android_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/android_parser.spec.js b/cordova-lib/spec-cordova/metadata/android_parser.spec.js
deleted file mode 100644
index 6c6ea41..0000000
--- a/cordova-lib/spec-cordova/metadata/android_parser.spec.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-var STRINGS_XML = '<resources> <string name="app_name">mobilespec</string> </resources>';
-var MANIFEST_XML = '<manifest android:versionCode="1" android:versionName="0.0.1" package="org.apache.mobilespec">\n' +
-    '<application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">\n' +
-    '    <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="mobilespec" android:screenOrientation="VAL">\n' +
-    '        <intent-filter>\n' +
-    '            <action android:name="android.intent.action.MAIN" />\n' +
-    '            <category android:name="android.intent.category.LAUNCHER" />\n' +
-    '        </intent-filter>\n' +
-    '    </activity>\n' +
-    '</application>\n' +
-    '</manifest>\n';
-
-describe('android project parser', function() {
-    var proj = path.join('some', 'path');
-    var exists;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        spyOn(config, 'has_custom_path').andReturn(false);
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain an AndroidManifest.xml', function() {
-            exists.andReturn(false);
-            expect(function() {
-                new platforms.android.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, strings, manifest and android_config properties', function() {
-            expect(function() {
-                var p = new platforms.android.parser(proj);
-                expect(p.path).toEqual(proj);
-                expect(p.strings).toEqual(path.join(proj, 'res', 'values', 'strings.xml'));
-                expect(p.manifest).toEqual(path.join(proj, 'AndroidManifest.xml'));
-                expect(p.android_config).toEqual(path.join(proj, 'res', 'xml', 'config.xml'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, mkdir, is_cordova, write, read;
-        var android_proj = path.join(proj, 'platforms', 'android');
-        var stringsRoot;
-        var manifestRoot;
-        beforeEach(function() {
-            stringsRoot = null;
-            manifestRoot = null;
-            p = new platforms.android.parser(android_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync');
-            mkdir = spyOn(shell, 'mkdir');
-            spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-                if (/strings/.exec(path)) {
-                    return stringsRoot = new et.ElementTree(et.XML(STRINGS_XML));
-                } else if (/AndroidManifest/.exec(path)) {
-                    return manifestRoot = new et.ElementTree(et.XML(MANIFEST_XML));
-                }
-            });
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                spyOn(fs, 'readdirSync').andReturn([path.join(proj, 'src', 'android_pkg', 'MyApp.java')]);
-                cfg.name = function() { return 'testname' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                read.andReturn('package org.cordova.somepackage; public class MyApp extends CordovaActivity { }');
-            });
-
-            it('should handle no orientation', function() {
-                cfg.getPreference = function() { return null; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('VAL');
-            });
-            it('should handle default orientation', function() {
-                cfg.getPreference = function() { return 'default'; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toBeUndefined();
-            });
-            it('should handle portrait orientation', function() {
-                cfg.getPreference = function() { return 'portrait'; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('portrait');
-            });
-            it('should handle invalid orientation', function() {
-                cfg.getPreference = function() { return 'prtrait'; };
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('VAL');
-            });
-            it('should write out the app name to strings.xml', function() {
-                p.update_from_config(cfg);
-                expect(stringsRoot.getroot().find('string').text).toEqual('testname');
-            });
-            it('should write out the app id to androidmanifest.xml and update the cordova-android entry Java class', function() {
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().attrib.package).toEqual('testpkg');
-            });
-            it('should write out the app version to androidmanifest.xml', function() {
-                p.update_from_config(cfg);
-                expect(manifestRoot.getroot().attrib['android:versionName']).toEqual('one point oh');
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return assets/www', function() {
-                expect(p.www_dir()).toEqual(path.join(android_proj, 'assets', 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(p.android_config);
-            });
-        });
-        describe('update_www method', function() {
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_overrides method', function() {
-            it('should do nothing if merges directory does not exist', function() {
-                exists.andReturn(false);
-                p.update_overrides();
-                expect(cp).not.toHaveBeenCalled();
-            });
-            it('should copy merges path into www', function() {
-                p.update_overrides();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                overrides = spyOn(p, 'update_overrides');
-                svn = spyOn(util, 'deleteSvnFolders');
-            });
-            it('should call update_from_config', function() {
-                p.update_project();
-                expect(config).toHaveBeenCalled();
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(err) {
-                    expect(err).toEqual(err);
-                });
-            });
-            it('should not call update_www', function() {
-                p.update_project();
-                expect(www).not.toHaveBeenCalled();
-            });
-            it('should call update_overrides', function() {
-                p.update_project();
-                expect(overrides).toHaveBeenCalled();
-            });
-            it('should call deleteSvnFolders', function() {
-                p.update_project();
-                expect(svn).toHaveBeenCalled();
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js b/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js
deleted file mode 100644
index b1d0b47..0000000
--- a/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    child_process = require('child_process'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
-    '<widget xmlns     = "http://www.w3.org/ns/widgets"\n' +
-    '        xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
-    '        id        = "io.cordova.hellocordova"\n' +
-    '        version   = "0.0.1">\n' +
-    '    <name>Hello Cordova</name>\n' +
-    '    <description>\n' +
-    '        A sample Apache Cordova application that responds to the deviceready event.\n' +
-    '    </description>\n' +
-    '    <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
-    '        Apache Cordova Team\n' +
-    '    </author>\n' +
-    '    <content src="index.html" />\n' +
-    '    <access origin="*" />\n' +
-    '    <preference name="fullscreen" value="true" />\n' +
-    '    <preference name="webviewbounce" value="true" />\n' +
-    '</widget>\n';
-
-describe('blackberry10 project parser', function() {
-    var proj = '/some/path';
-    var exists, custom, sh;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        sh = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            (cb || opts)(0, '', '');
-        });
-        spyOn(ConfigParser.prototype, 'write');
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function() {
-            return new et.ElementTree(et.XML(TEST_XML));
-        });
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw an exception with a path that is not a native blackberry project', function() {
-            exists.andReturn(false);
-            expect(function() {
-                new platforms.blackberry10.parser(proj);
-            }).toThrow();
-        });
-        it('should accept a proper native blackberry project path as construction parameter', function() {
-            var project;
-            expect(function() {
-                project = new platforms.blackberry10.parser(proj);
-            }).not.toThrow();
-            expect(project).toBeDefined();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if the blackberry-deploy shell-out fails', function(done) {
-            sh.andCallFake(function(cmd, opts, cb) {
-                (cb || opts)(1, 'no bb-deploy dewd!');
-            });
-            errorWrapper(platforms.blackberry10.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('no bb-deploy dewd');
-            });
-        });
-        it('should fire a callback with no error if shell out is successful', function(done) {
-            wrapper(platforms.blackberry10.parser.check_requirements(proj), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-    });
-    describe('instance', function() {
-        var p, cp, rm, mkdir, is_cordova, write, read;
-        var bb_proj = path.join(proj, 'platforms', 'blackberry10');
-        beforeEach(function() {
-            p = new platforms.blackberry10.parser(bb_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync');
-        });
-
-        describe('update_from_config method', function() {
-            var xml_name, xml_pkg, xml_version, xml_access_rm, xml_update, xml_append, xml_content;
-            beforeEach(function() {
-                xml_content = jasmine.createSpy('xml content');
-                xml_name = jasmine.createSpy('xml name');
-                xml_pkg = jasmine.createSpy('xml pkg');
-                xml_version = jasmine.createSpy('xml version');
-                xml_access_rm = jasmine.createSpy('xml access rm');
-                xml_access_add = jasmine.createSpy('xml access add');
-                xml_update = jasmine.createSpy('xml update');
-                xml_append = jasmine.createSpy('xml append');
-                xml_preference_remove = jasmine.createSpy('xml preference rm');
-                xml_preference_add = jasmine.createSpy('xml preference add');
-                p.xml.name = xml_name;
-                p.xml.packageName = xml_pkg;
-                p.xml.version = xml_version;
-                p.xml.content = xml_content;
-                p.xml.access = {
-                    remove:xml_access_rm,
-                    add: xml_access_add
-                };
-                p.xml.update = xml_update;
-                p.xml.doc = {
-                    getroot:function() { return { append:xml_append}; }
-                };
-                p.xml.preference = {
-                    add: xml_preference_add,
-                    remove: xml_preference_remove
-                };
-                cfg.name = function() { return 'testname'; };
-                cfg.packageName = function() { return 'testpkg'; };
-                cfg.version = function() { return 'one point oh'; };
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return /www', function() {
-                expect(p.www_dir()).toEqual(path.join(bb_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(proj, 'platforms', 'blackberry10', 'www', 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_overrides method', function() {
-            it('should do nothing if merges directory does not exist', function() {
-                exists.andReturn(false);
-                p.update_overrides();
-                expect(cp).not.toHaveBeenCalled();
-            });
-            it('should copy merges path into www', function() {
-                p.update_overrides();
-                expect(cp).toHaveBeenCalledWith('-rf', path.join(proj, 'merges', 'blackberry10', '*'), path.join(proj, 'platforms', 'blackberry10', 'www'));
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn, parse, get_env, write_env;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                overrides = spyOn(p, 'update_overrides');
-                svn = spyOn(util, 'deleteSvnFolders');
-                parse = spyOn(JSON, 'parse').andReturn({blackberry:{qnx:{}}});
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(e) {
-                    expect(e).toEqual(err);
-                });
-            });
-            it('should not call update_www', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(www).not.toHaveBeenCalled();
-                });
-            });
-            it('should call update_overrides', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(overrides).toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js b/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js
deleted file mode 100644
index 49694eb..0000000
--- a/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-describe('firefoxos project parser', function() {
-    var proj = path.join('some', 'path');
-    var exists, exec, custom;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
-            cb(0, '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-    });
-
-    describe('constructions', function() {
-        it('should create an instance with a path', function() {
-            expect(function() {
-                var p = new platforms.android.parser(proj);
-                expect(p.path).toEqual(proj);
-            }).not.toThrow();
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, is_cordova, write, read;
-        var ff_proj = path.join(proj, 'platforms', 'firefoxos');
-        beforeEach(function() {
-            p = new platforms.firefoxos.parser(ff_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname'; };
-                cfg.packageName = function() { return 'testpkg'; };
-                cfg.version = function() { return '1.0'; };
-            });
-
-          /*  it('should write manifest.webapp', function() {
-                //p.update_from_config(cfg);
-                //expect(write.mostRecentCall.args[0]).toEqual('manifest.webapp');
-            });*/
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/ios_parser.spec.js b/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
deleted file mode 100644
index 5b2977e..0000000
--- a/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    plist = require('plist-with-patches'),
-    xcode = require('xcode'),
-    et = require('elementtree'),
-    fs = require('fs'),
-    Q = require('q'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('ios project parser', function () {
-    var proj = path.join('some', 'path');
-    var custom, readdir;
-    beforeEach(function() {
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.xcodeproj']);
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain an xcodeproj file', function() {
-            readdir.andReturn(['noxcodehere']);
-            expect(function() {
-                new platforms.ios.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, pbxproj, xcodeproj, originalName and cordovaproj properties', function() {
-            expect(function() {
-                var p = new platforms.ios.parser(proj);
-                expect(p.path).toEqual(proj);
-                expect(p.pbxproj).toEqual(path.join(proj, 'test.xcodeproj', 'project.pbxproj'));
-                expect(p.xcodeproj).toEqual(path.join(proj, 'test.xcodeproj'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, mkdir, is_cordova, write, read;
-        var ios_proj = path.join(proj, 'platforms', 'ios');
-        beforeEach(function() {
-            p = new platforms.ios.parser(ios_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            var mv;
-            var cfg_access_add, cfg_access_rm, cfg_pref_add, cfg_pref_rm, cfg_content;
-            var plist_parse, plist_build, xc;
-            var update_name, xc_write;
-            beforeEach(function() {
-                mv = spyOn(shell, 'mv');
-                plist_parse = spyOn(plist, 'parseFileSync').andReturn({
-                });
-                plist_build = spyOn(plist, 'build').andReturn('');
-                update_name = jasmine.createSpy('update_name');
-                xc_write = jasmine.createSpy('xcode writeSync');
-                xc = spyOn(xcode, 'project').andReturn({
-                    parse:function(cb) {cb();},
-                    updateProductName:update_name,
-                    writeSync:xc_write
-                });
-                cfg.name = function() { return 'testname' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                p = new platforms.ios.parser(ios_proj);
-            });
-
-            it('should update the app name in pbxproj by calling xcode.updateProductName, and move the ios native files to match the new name', function(done) {
-                var test_path = path.join(proj, 'platforms', 'ios', 'test');
-                var testname_path = path.join(proj, 'platforms', 'ios', 'testname');
-                wrapper(p.update_from_config(cfg), done, function() {
-                    expect(update_name).toHaveBeenCalledWith('testname');
-                    expect(mv).toHaveBeenCalledWith(path.join(test_path, 'test-Info.plist'), path.join(test_path, 'testname-Info.plist'));
-                    expect(mv).toHaveBeenCalledWith(path.join(test_path, 'test-Prefix.pch'), path.join(test_path, 'testname-Prefix.pch'));
-                    expect(mv).toHaveBeenCalledWith(test_path + '.xcodeproj', testname_path + '.xcodeproj');
-                    expect(mv).toHaveBeenCalledWith(test_path, testname_path);
-                });
-            });
-            it('should write out the app id to info plist as CFBundleIdentifier', function(done) {
-                wrapper(p.update_from_config(cfg), done, function() {
-                    expect(plist_build.mostRecentCall.args[0].CFBundleIdentifier).toEqual('testpkg');
-                });
-            });
-            it('should write out the app version to info plist as CFBundleVersion', function(done) {
-                wrapper(p.update_from_config(cfg), done, function() {
-                    expect(plist_build.mostRecentCall.args[0].CFBundleShortVersionString).toEqual('one point oh');
-                });
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return /www', function() {
-                expect(p.www_dir()).toEqual(path.join(ios_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(ios_proj, 'test', 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www(path.join('lib','dir'));
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_overrides method', function() {
-            var exists;
-            beforeEach(function() {
-                exists = spyOn(fs, 'existsSync').andReturn(true);
-            });
-            it('should do nothing if merges directory does not exist', function() {
-                exists.andReturn(false);
-                p.update_overrides();
-                expect(cp).not.toHaveBeenCalled();
-            });
-            it('should copy merges path into www', function() {
-                p.update_overrides();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config').andReturn(Q());
-                www = spyOn(p, 'update_www');
-                overrides = spyOn(p, 'update_overrides');
-                svn = spyOn(util, 'deleteSvnFolders');
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config errors', function(done) {
-                var e = new Error('uh oh!');
-                config.andReturn(Q.reject(e));
-                errorWrapper(p.update_project({}), done, function(err) {
-                    expect(err).toEqual(e);
-                });
-            });
-            it('should not call update_www', function(done) {
-                wrapper(p.update_project({}), done, function() {
-                    expect(www).not().toHaveBeenCalled();
-                });
-            });
-            it('should call update_overrides', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(overrides).toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js b/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
deleted file mode 100644
index 726391f..0000000
--- a/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    child_process = require('child_process'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    et = require('elementtree'),
-    Q = require('q'),
-    fs = require('fs'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('windows8 project parser', function() {
-
-    var proj = '/some/path';
-    var exists, exec, custom, readdir, cfg_parser;
-    var winXml;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            if (!cb) cb = opts;
-            cb(null, '', '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.jsproj']);
-        winXml = null;
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-            return winXml = new et.ElementTree(et.XML('<foo><Application/><Identity/><VisualElements><a/></VisualElements><Capabilities><a/></Capabilities></foo>'));
-        });
-    });
-
-    function wrapper(promise, done, post) {
-        promise.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(promise, done, post) {
-        promise.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain a jsproj file', function() {
-            readdir.andReturn([]);
-            expect(function() {
-                new platforms.windows8.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, manifest properties', function() {
-            expect(function() {
-                var parser = new platforms.windows8.parser(proj);
-                expect(parser.windows8_proj_dir).toEqual(proj);
-                expect(parser.manifest_path).toEqual(path.join(proj, 'package.appxmanifest'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                if (!cb) cb = opts;
-                cb(50, 'there was an errorz!', '');
-            });
-            errorWrapper(platforms.windows8.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
-            wrapper(platforms.windows8.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
-            var custom_path = path.join('some','custom','path','to','windows8','lib');
-            custom.andReturn(custom_path);
-            wrapper(platforms.windows8.parser.check_requirements(proj),done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-            done();
-        });
-    });
-
-    describe('instance', function() {
-        var parser, cp, rm, is_cordova, write, read, mv, mkdir;
-        var windows8_proj = path.join(proj, 'platforms', 'windows8');
-        beforeEach(function() {
-            parser = new platforms.windows8.parser(windows8_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname' };
-                cfg.content = function() { return 'index.html' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                readdir.andReturn(['test.sln']);
-            });
-
-            it('should write out the app name to package.appxmanifest', function() {
-                parser.update_from_config(cfg);
-                var identityNode = winXml.getroot().find('.//Identity');
-                expect(identityNode.attrib.Name).toEqual(cfg.packageName());
-            });
-
-            it('should write out the app version to package.appxmanifest', function() {
-                parser.update_from_config(cfg);
-                var identityNode = winXml.getroot().find('.//Identity');
-                expect(identityNode.attrib.Version).toEqual('one point oh');
-            });
-        });
-
-        describe('www_dir method', function() {
-            it('should return www', function() {
-                expect(parser.www_dir()).toEqual(path.join(windows8_proj, 'www'));
-            });
-        });
-        describe('update_www method', function() {
-            var update_jsproj;
-            beforeEach(function() {
-                update_jsproj = spyOn(parser, 'update_jsproj');
-            });
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                parser.update_www(path.join('lib','dir'));
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn;
-            beforeEach(function() {
-                config = spyOn(parser, 'update_from_config');
-                www = spyOn(parser, 'update_www');
-                www = spyOn(parser, 'update_jsproj');
-                svn = spyOn(util, 'deleteSvnFolders');
-                exists.andReturn(false);
-            });
-            it('should call update_from_config', function() {
-                parser.update_project();
-                expect(config).toHaveBeenCalled();
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(parser.update_project({}), done, function(err) {
-                    expect(err).toEqual(err);
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(parser.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js b/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js
deleted file mode 100644
index 0856391..0000000
--- a/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    child_process = require('child_process'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    CordovaError = require('../../src/CordovaError'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('wp7 project parser', function() {
-    var proj = '/some/path';
-    var exists, exec, custom, readdir, cfg_parser;
-    var projXml, manifestXml;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            (cb || opts)(0, '', '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.csproj']);
-        projXml = manifestXml = null;
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-            if (/WMAppManifest.xml$/.exec(path)) {
-                return manifestXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/csproj$/.exec(path)) {
-                return projXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/xaml$/.exec(path)) {
-                return new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else {
-                throw new CordovaError('Unexpected parseElementtreeSync: ' + path);
-            }
-        });
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain a csproj file', function() {
-            readdir.andReturn([]);
-            expect(function() {
-                new platforms.wp7.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, manifest properties', function() {
-            expect(function() {
-                var p = new platforms.wp7.parser(proj);
-                expect(p.wp7_proj_dir).toEqual(proj);
-                expect(p.manifest_path).toEqual(path.join(proj, 'Properties', 'WMAppManifest.xml'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                (cb || opts)(50, 'there was an errorz!');
-            });
-            errorWrapper(platforms.wp7.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
-            wrapper(platforms.wp7.parser.check_requirements(proj), done, function(err) {
-                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
-            var custom_path = path.join('some','custom','path','to','wp7','lib');
-            custom.andReturn(custom_path);
-            wrapper(platforms.wp7.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, is_cordova, write, read, mv, mkdir;
-        var wp7_proj = path.join(proj, 'platforms', 'wp7');
-        beforeEach(function() {
-            p = new platforms.wp7.parser(wp7_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname' };
-                cfg.content = function() { return 'index.html' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                readdir.andReturn(['test.sln']);
-            });
-
-            it('should write out the app name to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Title).toEqual('testname');
-            });
-            it('should write out the app id to csproj file', function() {
-                p.update_from_config(cfg);
-                var appEl = projXml.getroot().find('.//RootNamespace');
-                expect(appEl.text).toContain('testpkg');
-            });
-            it('should write out the app version to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Version).toEqual('one point oh');
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return www', function() {
-                expect(p.www_dir()).toEqual(path.join(wp7_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(wp7_proj, 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-            var update_csproj;
-            beforeEach(function() {
-                update_csproj = spyOn(p, 'update_csproj');
-            });
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn, cfg, csproj;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                svn = spyOn(util, 'deleteSvnFolders');
-                csproj = spyOn(p, 'update_csproj');
-                exists.andReturn(false);
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function(){
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(e) {
-                    expect(e).toEqual(err);
-                });
-            });
-            it('should call update_www', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(www).not.toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js b/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
deleted file mode 100644
index 5ea461e..0000000
--- a/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var platforms = require('../../platforms'),
-    util = require('../../src/util'),
-    path = require('path'),
-    shell = require('shelljs'),
-    fs = require('fs'),
-    et = require('elementtree'),
-    xmlHelpers = require('../../src/xml-helpers'),
-    Q = require('q'),
-    child_process = require('child_process'),
-    config = require('../../src/config'),
-    ConfigParser = require('../../src/ConfigParser'),
-    CordovaError = require('../../src/CordovaError'),
-    cordova = require('../../cordova');
-
-// Create a real config object before mocking out everything.
-var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
-
-describe('wp8 project parser', function() {
-    var proj = '/some/path';
-    var exists, exec, custom, readdir, cfg_parser;
-    var manifestXml, projXml;
-    beforeEach(function() {
-        exists = spyOn(fs, 'existsSync').andReturn(true);
-        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
-            (cb || opts)(0, '', '');
-        });
-        custom = spyOn(config, 'has_custom_path').andReturn(false);
-        readdir = spyOn(fs, 'readdirSync').andReturn(['test.csproj']);
-        projXml = manifestXml = null;
-        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
-            if (/WMAppManifest.xml$/.exec(path)) {
-                return manifestXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/csproj$/.exec(path)) {
-                return projXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else if (/xaml$/.exec(path)) {
-                return new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
-            } else {
-                throw new CordovaError('Unexpected parseElementtreeSync: ' + path);
-            }
-        });
-    });
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    }
-
-    function errorWrapper(p, done, post) {
-        p.then(function() {
-            expect('this call').toBe('fail');
-        }, post).fin(done);
-    }
-
-    describe('constructions', function() {
-        it('should throw if provided directory does not contain a csproj file', function() {
-            readdir.andReturn([]);
-            expect(function() {
-                new platforms.wp8.parser(proj);
-            }).toThrow();
-        });
-        it('should create an instance with path, manifest properties', function() {
-            expect(function() {
-                var p = new platforms.wp8.parser(proj);
-                expect(p.wp8_proj_dir).toEqual(proj);
-                expect(p.manifest_path).toEqual(path.join(proj, 'Properties', 'WMAppManifest.xml'));
-            }).not.toThrow();
-        });
-    });
-
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                (cb || opts)(50, 'there was an errorz!');
-            });
-            errorWrapper(platforms.wp8.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
-            wrapper(platforms.wp8.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
-            var custom_path = path.join('some','custom','path','to','wp8','lib');
-            custom.andReturn(custom_path);
-            wrapper(platforms.wp8.parser.check_requirements(proj), done, function(err) {
-                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
-                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
-            });
-        });
-    });
-
-    describe('instance', function() {
-        var p, cp, rm, is_cordova, write, read, mv, mkdir;
-        var wp8_proj = path.join(proj, 'platforms', 'wp8');
-        beforeEach(function() {
-            p = new platforms.wp8.parser(wp8_proj);
-            cp = spyOn(shell, 'cp');
-            rm = spyOn(shell, 'rm');
-            mv = spyOn(shell, 'mv');
-            mkdir = spyOn(shell, 'mkdir');
-            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
-            write = spyOn(fs, 'writeFileSync');
-            read = spyOn(fs, 'readFileSync').andReturn('');
-        });
-
-        describe('update_from_config method', function() {
-            beforeEach(function() {
-                cfg.name = function() { return 'testname' };
-                cfg.content = function() { return 'index.html' };
-                cfg.packageName = function() { return 'testpkg' };
-                cfg.version = function() { return 'one point oh' };
-                readdir.andReturn(['test.sln']);
-            });
-
-            it('should write out the app name to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Title).toEqual('testname');
-            });
-            it('should write out the app id to csproj file', function() {
-                p.update_from_config(cfg);
-                var appEl = projXml.getroot().find('.//RootNamespace');
-                expect(appEl.text).toContain('testpkg');
-            });
-            it('should write out the app version to wmappmanifest.xml', function() {
-                p.update_from_config(cfg);
-                var appEl = manifestXml.getroot().find('.//App');
-                expect(appEl.attrib.Version).toEqual('one point oh');
-            });
-        });
-        describe('www_dir method', function() {
-            it('should return www', function() {
-                expect(p.www_dir()).toEqual(path.join(wp8_proj, 'www'));
-            });
-        });
-        describe('config_xml method', function() {
-            it('should return the location of the config.xml', function() {
-                expect(p.config_xml()).toEqual(path.join(wp8_proj, 'config.xml'));
-            });
-        });
-        describe('update_www method', function() {
-            var update_csproj;
-            beforeEach(function() {
-                update_csproj = spyOn(p, 'update_csproj');
-            });
-            it('should rm project-level www and cp in platform agnostic www', function() {
-                p.update_www();
-                expect(rm).toHaveBeenCalled();
-                expect(cp).toHaveBeenCalled();
-            });
-        });
-        describe('update_project method', function() {
-            var config, www, overrides, svn, csproj;
-            beforeEach(function() {
-                config = spyOn(p, 'update_from_config');
-                www = spyOn(p, 'update_www');
-                svn = spyOn(util, 'deleteSvnFolders');
-                csproj = spyOn(p, 'update_csproj');
-                exists.andReturn(false);
-            });
-            it('should call update_from_config', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(config).toHaveBeenCalled();
-                });
-            });
-            it('should throw if update_from_config throws', function(done) {
-                var err = new Error('uh oh!');
-                config.andCallFake(function() { throw err; });
-                errorWrapper(p.update_project({}), done, function(e) {
-                    expect(e).toEqual(err);
-                });
-            });
-            it('should not call update_www', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(www).not.toHaveBeenCalled();
-                });
-            });
-            it('should call deleteSvnFolders', function(done) {
-                wrapper(p.update_project(), done, function() {
-                    expect(svn).toHaveBeenCalled();
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/platform.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/platform.spec.js b/cordova-lib/spec-cordova/platform.spec.js
deleted file mode 100644
index e16d51d..0000000
--- a/cordova-lib/spec-cordova/platform.spec.js
+++ /dev/null
@@ -1,108 +0,0 @@
-
-var helpers = require('./helpers'),
-    path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    platforms = require('../platforms'),
-    superspawn = require('../src/superspawn'),
-    config = require('../src/config'),
-    Q = require('q'),
-    events = require('../src/events'),
-    cordova = require('../cordova');
-
-var tmpDir = helpers.tmpDir('platform_test');
-var project = path.join(tmpDir, 'project');
-
-var platformParser = platforms[helpers.testPlatform].parser;
-
-describe('platform end-to-end', function() {
-    var results;
-
-    beforeEach(function() {
-        shell.rm('-rf', tmpDir);
-    });
-    afterEach(function() {
-        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
-        shell.rm('-rf', tmpDir);
-    });
-
-    // Factoring out some repeated checks.
-    function emptyPlatformList() {
-        return cordova.raw.platform('list').then(function() {
-            var installed = results.match(/Installed platforms: (.*)/);
-            expect(installed).toBeDefined();
-            expect(installed[1].indexOf(helpers.testPlatform)).toBe(-1);
-        });
-    }
-
-    function fullPlatformList() {
-        return cordova.raw.platform('list').then(function() {
-            var installed = results.match(/Installed platforms: (.*)/);
-            expect(installed).toBeDefined();
-            expect(installed[1].indexOf(helpers.testPlatform)).toBeGreaterThan(-1);
-        });
-    }
-
-    // The flows we want to test are add, rm, list, and upgrade.
-    // They should run the appropriate hooks.
-    // They should fail when not inside a Cordova project.
-    // These tests deliberately have no beforeEach and afterEach that are cleaning things up.
-    it('should successfully run', function(done) {
-        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
-        // Using /* doesn't work because of hidden files.
-        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
-        shell.mv(path.join(tmpDir, 'base'), project);
-        process.chdir(project);
-
-        // Now we load the config.json in the newly created project and edit the target platform's lib entry
-        // to point at the fixture version. This is necessary so that cordova.prepare can find cordova.js there.
-        var c = config.read(project);
-        c.lib[helpers.testPlatform].uri = path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform + '-lib');
-        config.write(project, c);
-
-        // The config.json in the fixture project points at fake "local" paths.
-        // Since it's not a URL, the lazy-loader will just return the junk path.
-        spyOn(superspawn, 'spawn').andCallFake(function(cmd, args) {
-            if (cmd.match(/create\b/)) {
-                // This is a call to the bin/create script, so do the copy ourselves.
-                shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', 'android'), path.join(project, 'platforms'));
-            } else if(cmd.match(/version\b/)) {
-                return Q('3.3.0');
-            } else if(cmd.match(/update\b/)) {
-                fs.writeFileSync(path.join(project, 'platforms', helpers.testPlatform, 'updated'), 'I was updated!', 'utf-8');
-            }
-            return Q();
-        });
-
-        events.on('results', function(res) { results = res; });
-
-        // Check there are no platforms yet.
-        emptyPlatformList().then(function() {
-            // Add the testing platform.
-            return cordova.raw.platform('add', [helpers.testPlatform]);
-        }).then(function() {
-            // Check the platform add was successful.
-            expect(path.join(project, 'platforms', helpers.testPlatform)).toExist();
-            expect(path.join(project, 'merges', helpers.testPlatform)).toExist();
-            expect(path.join(project, 'platforms', helpers.testPlatform, 'cordova')).toExist();
-        }).then(fullPlatformList) // Check for it in platform ls.
-        .then(function() {
-            // Try to update the platform.
-            return cordova.raw.platform('update', [helpers.testPlatform]);
-        }).then(function() {
-            // Our fake update script in the exec mock above creates this dummy file.
-            expect(path.join(project, 'platforms', helpers.testPlatform, 'updated')).toExist();
-        }).then(fullPlatformList) // Platform should still be in platform ls.
-        .then(function() {
-            // And now remove it.
-            return cordova.raw.platform('rm', [helpers.testPlatform]);
-        }).then(function() {
-            // It should be gone.
-            expect(path.join(project, 'platforms', helpers.testPlatform)).not.toExist();
-        }).then(emptyPlatformList) // platform ls should be empty too.
-        .fail(function(err) {
-            expect(err).toBeUndefined();
-        }).fin(done);
-    });
-});
-


[21/24] Remove all cordova-lib files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js
deleted file mode 100644
index 07e3feb..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova.js
+++ /dev/null
@@ -1,1712 +0,0 @@
-// Platform: android
-// 3.1.0
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
- 
-     http://www.apache.org/licenses/LICENSE-2.0
- 
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-;(function() {
-var CORDOVA_JS_BUILD_LABEL = '3.1.0';
-// file: lib/scripts/require.js
-
-var require,
-    define;
-
-(function () {
-    var modules = {},
-    // Stack of moduleIds currently being built.
-        requireStack = [],
-    // Map of module ID -> index into requireStack of modules currently being built.
-        inProgressModules = {},
-        SEPERATOR = ".";
-
-
-
-    function build(module) {
-        var factory = module.factory,
-            localRequire = function (id) {
-                var resultantId = id;
-                //Its a relative path, so lop off the last portion and add the id (minus "./")
-                if (id.charAt(0) === ".") {
-                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
-                }
-                return require(resultantId);
-            };
-        module.exports = {};
-        delete module.factory;
-        factory(localRequire, module.exports, module);
-        return module.exports;
-    }
-
-    require = function (id) {
-        if (!modules[id]) {
-            throw "module " + id + " not found";
-        } else if (id in inProgressModules) {
-            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
-            throw "Cycle in require graph: " + cycle;
-        }
-        if (modules[id].factory) {
-            try {
-                inProgressModules[id] = requireStack.length;
-                requireStack.push(id);
-                return build(modules[id]);
-            } finally {
-                delete inProgressModules[id];
-                requireStack.pop();
-            }
-        }
-        return modules[id].exports;
-    };
-
-    define = function (id, factory) {
-        if (modules[id]) {
-            throw "module " + id + " already defined";
-        }
-
-        modules[id] = {
-            id: id,
-            factory: factory
-        };
-    };
-
-    define.remove = function (id) {
-        delete modules[id];
-    };
-
-    define.moduleMap = modules;
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
-    module.exports.require = require;
-    module.exports.define = define;
-}
-
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-
-
-var channel = require('cordova/channel');
-var platform = require('cordova/platform');
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
-    windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof documentEventHandlers[e] != 'undefined') {
-        documentEventHandlers[e].subscribe(handler);
-    } else {
-        m_document_addEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof windowEventHandlers[e] != 'undefined') {
-        windowEventHandlers[e].subscribe(handler);
-    } else {
-        m_window_addEventListener.call(window, evt, handler, capture);
-    }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof documentEventHandlers[e] != "undefined") {
-        documentEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_document_removeEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof windowEventHandlers[e] != "undefined") {
-        windowEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_window_removeEventListener.call(window, evt, handler, capture);
-    }
-};
-
-function createEvent(type, data) {
-    var event = document.createEvent('Events');
-    event.initEvent(type, false, false);
-    if (data) {
-        for (var i in data) {
-            if (data.hasOwnProperty(i)) {
-                event[i] = data[i];
-            }
-        }
-    }
-    return event;
-}
-
-
-var cordova = {
-    define:define,
-    require:require,
-    version:CORDOVA_JS_BUILD_LABEL,
-    platformId:platform.id,
-    /**
-     * Methods to add/remove your own addEventListener hijacking on document + window.
-     */
-    addWindowEventHandler:function(event) {
-        return (windowEventHandlers[event] = channel.create(event));
-    },
-    addStickyDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.createSticky(event));
-    },
-    addDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.create(event));
-    },
-    removeWindowEventHandler:function(event) {
-        delete windowEventHandlers[event];
-    },
-    removeDocumentEventHandler:function(event) {
-        delete documentEventHandlers[event];
-    },
-    /**
-     * Retrieve original event handlers that were replaced by Cordova
-     *
-     * @return object
-     */
-    getOriginalHandlers: function() {
-        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
-        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
-    },
-    /**
-     * Method to fire event from native code
-     * bNoDetach is required for events which cause an exception which needs to be caught in native code
-     */
-    fireDocumentEvent: function(type, data, bNoDetach) {
-        var evt = createEvent(type, data);
-        if (typeof documentEventHandlers[type] != 'undefined') {
-            if( bNoDetach ) {
-                documentEventHandlers[type].fire(evt);
-            }
-            else {
-                setTimeout(function() {
-                    // Fire deviceready on listeners that were registered before cordova.js was loaded.
-                    if (type == 'deviceready') {
-                        document.dispatchEvent(evt);
-                    }
-                    documentEventHandlers[type].fire(evt);
-                }, 0);
-            }
-        } else {
-            document.dispatchEvent(evt);
-        }
-    },
-    fireWindowEvent: function(type, data) {
-        var evt = createEvent(type,data);
-        if (typeof windowEventHandlers[type] != 'undefined') {
-            setTimeout(function() {
-                windowEventHandlers[type].fire(evt);
-            }, 0);
-        } else {
-            window.dispatchEvent(evt);
-        }
-    },
-
-    /**
-     * Plugin callback mechanism.
-     */
-    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
-    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
-    callbackId: Math.floor(Math.random() * 2000000000),
-    callbacks:  {},
-    callbackStatus: {
-        NO_RESULT: 0,
-        OK: 1,
-        CLASS_NOT_FOUND_EXCEPTION: 2,
-        ILLEGAL_ACCESS_EXCEPTION: 3,
-        INSTANTIATION_EXCEPTION: 4,
-        MALFORMED_URL_EXCEPTION: 5,
-        IO_EXCEPTION: 6,
-        INVALID_ACTION: 7,
-        JSON_EXCEPTION: 8,
-        ERROR: 9
-    },
-
-    /**
-     * Called by native code when returning successful result from an action.
-     */
-    callbackSuccess: function(callbackId, args) {
-        try {
-            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning error result from an action.
-     */
-    callbackError: function(callbackId, args) {
-        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
-        // Derive success from status.
-        try {
-            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning the result from an action.
-     */
-    callbackFromNative: function(callbackId, success, status, args, keepCallback) {
-        var callback = cordova.callbacks[callbackId];
-        if (callback) {
-            if (success && status == cordova.callbackStatus.OK) {
-                callback.success && callback.success.apply(null, args);
-            } else if (!success) {
-                callback.fail && callback.fail.apply(null, args);
-            }
-
-            // Clear callback if not expecting any more results
-            if (!keepCallback) {
-                delete cordova.callbacks[callbackId];
-            }
-        }
-    },
-    addConstructor: function(func) {
-        channel.onCordovaReady.subscribe(function() {
-            try {
-                func();
-            } catch(e) {
-                console.log("Failed to run constructor: " + e);
-            }
-        });
-    }
-};
-
-
-module.exports = cordova;
-
-});
-
-// file: lib/android/android/nativeapiprovider.js
-define("cordova/android/nativeapiprovider", function(require, exports, module) {
-
-/**
- * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
- */
-
-var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
-var currentApi = nativeApi;
-
-module.exports = {
-    get: function() { return currentApi; },
-    setPreferPrompt: function(value) {
-        currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
-    },
-    // Used only by tests.
-    set: function(value) {
-        currentApi = value;
-    }
-};
-
-});
-
-// file: lib/android/android/promptbasednativeapi.js
-define("cordova/android/promptbasednativeapi", function(require, exports, module) {
-
-/**
- * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
- * This is used only on the 2.3 simulator, where addJavascriptInterface() is broken.
- */
-
-module.exports = {
-    exec: function(service, action, callbackId, argsJson) {
-        return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId]));
-    },
-    setNativeToJsBridgeMode: function(value) {
-        prompt(value, 'gap_bridge_mode:');
-    },
-    retrieveJsMessages: function(fromOnlineEvent) {
-        return prompt(+fromOnlineEvent, 'gap_poll:');
-    }
-};
-
-});
-
-// file: lib/common/argscheck.js
-define("cordova/argscheck", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var moduleExports = module.exports;
-
-var typeMap = {
-    'A': 'Array',
-    'D': 'Date',
-    'N': 'Number',
-    'S': 'String',
-    'F': 'Function',
-    'O': 'Object'
-};
-
-function extractParamName(callee, argIndex) {
-    return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
-}
-
-function checkArgs(spec, functionName, args, opt_callee) {
-    if (!moduleExports.enableChecks) {
-        return;
-    }
-    var errMsg = null;
-    var typeName;
-    for (var i = 0; i < spec.length; ++i) {
-        var c = spec.charAt(i),
-            cUpper = c.toUpperCase(),
-            arg = args[i];
-        // Asterix means allow anything.
-        if (c == '*') {
-            continue;
-        }
-        typeName = utils.typeName(arg);
-        if ((arg === null || arg === undefined) && c == cUpper) {
-            continue;
-        }
-        if (typeName != typeMap[cUpper]) {
-            errMsg = 'Expected ' + typeMap[cUpper];
-            break;
-        }
-    }
-    if (errMsg) {
-        errMsg += ', but got ' + typeName + '.';
-        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
-        // Don't log when running unit tests.
-        if (typeof jasmine == 'undefined') {
-            console.error(errMsg);
-        }
-        throw TypeError(errMsg);
-    }
-}
-
-function getValue(value, defaultValue) {
-    return value === undefined ? defaultValue : value;
-}
-
-moduleExports.checkArgs = checkArgs;
-moduleExports.getValue = getValue;
-moduleExports.enableChecks = true;
-
-
-});
-
-// file: lib/common/base64.js
-define("cordova/base64", function(require, exports, module) {
-
-var base64 = exports;
-
-base64.fromArrayBuffer = function(arrayBuffer) {
-    var array = new Uint8Array(arrayBuffer);
-    return uint8ToBase64(array);
-};
-
-//------------------------------------------------------------------------------
-
-/* This code is based on the performance tests at http://jsperf.com/b64tests
- * This 12-bit-at-a-time algorithm was the best performing version on all
- * platforms tested.
- */
-
-var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-var b64_12bit;
-
-var b64_12bitTable = function() {
-    b64_12bit = [];
-    for (var i=0; i<64; i++) {
-        for (var j=0; j<64; j++) {
-            b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];
-        }
-    }
-    b64_12bitTable = function() { return b64_12bit; };
-    return b64_12bit;
-};
-
-function uint8ToBase64(rawData) {
-    var numBytes = rawData.byteLength;
-    var output="";
-    var segment;
-    var table = b64_12bitTable();
-    for (var i=0;i<numBytes-2;i+=3) {
-        segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];
-        output += table[segment >> 12];
-        output += table[segment & 0xfff];
-    }
-    if (numBytes - i == 2) {
-        segment = (rawData[i] << 16) + (rawData[i+1] << 8);
-        output += table[segment >> 12];
-        output += b64_6bit[(segment & 0xfff) >> 6];
-        output += '=';
-    } else if (numBytes - i == 1) {
-        segment = (rawData[i] << 16);
-        output += table[segment >> 12];
-        output += '==';
-    }
-    return output;
-}
-
-});
-
-// file: lib/common/builder.js
-define("cordova/builder", function(require, exports, module) {
-
-var utils = require('cordova/utils');
-
-function each(objects, func, context) {
-    for (var prop in objects) {
-        if (objects.hasOwnProperty(prop)) {
-            func.apply(context, [objects[prop], prop]);
-        }
-    }
-}
-
-function clobber(obj, key, value) {
-    exports.replaceHookForTesting(obj, key);
-    obj[key] = value;
-    // Getters can only be overridden by getters.
-    if (obj[key] !== value) {
-        utils.defineGetter(obj, key, function() {
-            return value;
-        });
-    }
-}
-
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
-    if (message) {
-        utils.defineGetter(obj, key, function() {
-            console.log(message);
-            delete obj[key];
-            clobber(obj, key, value);
-            return value;
-        });
-    } else {
-        clobber(obj, key, value);
-    }
-}
-
-function include(parent, objects, clobber, merge) {
-    each(objects, function (obj, key) {
-        try {
-            var result = obj.path ? require(obj.path) : {};
-
-            if (clobber) {
-                // Clobber if it doesn't exist.
-                if (typeof parent[key] === 'undefined') {
-                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                } else if (typeof obj.path !== 'undefined') {
-                    // If merging, merge properties onto parent, otherwise, clobber.
-                    if (merge) {
-                        recursiveMerge(parent[key], result);
-                    } else {
-                        assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                    }
-                }
-                result = parent[key];
-            } else {
-                // Overwrite if not currently defined.
-                if (typeof parent[key] == 'undefined') {
-                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                } else {
-                    // Set result to what already exists, so we can build children into it if they exist.
-                    result = parent[key];
-                }
-            }
-
-            if (obj.children) {
-                include(result, obj.children, clobber, merge);
-            }
-        } catch(e) {
-            utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
-        }
-    });
-}
-
-/**
- * Merge properties from one object onto another recursively.  Properties from
- * the src object will overwrite existing target property.
- *
- * @param target Object to merge properties into.
- * @param src Object to merge properties from.
- */
-function recursiveMerge(target, src) {
-    for (var prop in src) {
-        if (src.hasOwnProperty(prop)) {
-            if (target.prototype && target.prototype.constructor === target) {
-                // If the target object is a constructor override off prototype.
-                clobber(target.prototype, prop, src[prop]);
-            } else {
-                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
-                    recursiveMerge(target[prop], src[prop]);
-                } else {
-                    clobber(target, prop, src[prop]);
-                }
-            }
-        }
-    }
-}
-
-exports.buildIntoButDoNotClobber = function(objects, target) {
-    include(target, objects, false, false);
-};
-exports.buildIntoAndClobber = function(objects, target) {
-    include(target, objects, true, false);
-};
-exports.buildIntoAndMerge = function(objects, target) {
-    include(target, objects, true, true);
-};
-exports.recursiveMerge = recursiveMerge;
-exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
-
-});
-
-// file: lib/common/channel.js
-define("cordova/channel", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    nextGuid = 1;
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization, as well as for custom events thereafter.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
- * onNativeReady*              Internal event that indicates the Cordova native side is ready.
- * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
- * onDeviceReady*              User event fired to indicate that Cordova is ready
- * onResume                    User event fired to indicate a start/resume lifecycle event
- * onPause                     User event fired to indicate a pause lifecycle event
- * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
- * All listeners that subscribe after the event is fired will be executed right away.
- *
- * The only Cordova events that user code should register for are:
- *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
- *      pause                 App has moved to background
- *      resume                App has returned to foreground
- *
- * Listeners can be registered as:
- *      document.addEventListener("deviceready", myDeviceReadyListener, false);
- *      document.addEventListener("resume", myResumeListener, false);
- *      document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- *      window.onload
- *      window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type  String the channel name
- */
-var Channel = function(type, sticky) {
-    this.type = type;
-    // Map of guid -> function.
-    this.handlers = {};
-    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
-    this.state = sticky ? 1 : 0;
-    // Used in sticky mode to remember args passed to fire().
-    this.fireArgs = null;
-    // Used by onHasSubscribersChange to know if there are any listeners.
-    this.numHandlers = 0;
-    // Function that is called when the first listener is subscribed, or when
-    // the last listener is unsubscribed.
-    this.onHasSubscribersChange = null;
-},
-    channel = {
-        /**
-         * Calls the provided function only after all of the channels specified
-         * have been fired. All channels must be sticky channels.
-         */
-        join: function(h, c) {
-            var len = c.length,
-                i = len,
-                f = function() {
-                    if (!(--i)) h();
-                };
-            for (var j=0; j<len; j++) {
-                if (c[j].state === 0) {
-                    throw Error('Can only use join with sticky channels.');
-                }
-                c[j].subscribe(f);
-            }
-            if (!len) h();
-        },
-        create: function(type) {
-            return channel[type] = new Channel(type, false);
-        },
-        createSticky: function(type) {
-            return channel[type] = new Channel(type, true);
-        },
-
-        /**
-         * cordova Channels that must fire before "deviceready" is fired.
-         */
-        deviceReadyChannelsArray: [],
-        deviceReadyChannelsMap: {},
-
-        /**
-         * Indicate that a feature needs to be initialized before it is ready to be used.
-         * This holds up Cordova's "deviceready" event until the feature has been initialized
-         * and Cordova.initComplete(feature) is called.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        waitForInitialization: function(feature) {
-            if (feature) {
-                var c = channel[feature] || this.createSticky(feature);
-                this.deviceReadyChannelsMap[feature] = c;
-                this.deviceReadyChannelsArray.push(c);
-            }
-        },
-
-        /**
-         * Indicate that initialization code has completed and the feature is ready to be used.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        initializationComplete: function(feature) {
-            var c = this.deviceReadyChannelsMap[feature];
-            if (c) {
-                c.fire();
-            }
-        }
-    };
-
-function forceFunction(f) {
-    if (typeof f != 'function') throw "Function required as first argument!";
-}
-
-/**
- * Subscribes the given function to the channel. Any time that
- * Channel.fire is called so too will the function.
- * Optionally specify an execution context for the function
- * and a guid that can be used to stop subscribing to the channel.
- * Returns the guid.
- */
-Channel.prototype.subscribe = function(f, c) {
-    // need a function to call
-    forceFunction(f);
-    if (this.state == 2) {
-        f.apply(c || this, this.fireArgs);
-        return;
-    }
-
-    var func = f,
-        guid = f.observer_guid;
-    if (typeof c == "object") { func = utils.close(c, f); }
-
-    if (!guid) {
-        // first time any channel has seen this subscriber
-        guid = '' + nextGuid++;
-    }
-    func.observer_guid = guid;
-    f.observer_guid = guid;
-
-    // Don't add the same handler more than once.
-    if (!this.handlers[guid]) {
-        this.handlers[guid] = func;
-        this.numHandlers++;
-        if (this.numHandlers == 1) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Unsubscribes the function with the given guid from the channel.
- */
-Channel.prototype.unsubscribe = function(f) {
-    // need a function to unsubscribe
-    forceFunction(f);
-
-    var guid = f.observer_guid,
-        handler = this.handlers[guid];
-    if (handler) {
-        delete this.handlers[guid];
-        this.numHandlers--;
-        if (this.numHandlers === 0) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Calls all functions subscribed to this channel.
- */
-Channel.prototype.fire = function(e) {
-    var fail = false,
-        fireArgs = Array.prototype.slice.call(arguments);
-    // Apply stickiness.
-    if (this.state == 1) {
-        this.state = 2;
-        this.fireArgs = fireArgs;
-    }
-    if (this.numHandlers) {
-        // Copy the values first so that it is safe to modify it from within
-        // callbacks.
-        var toCall = [];
-        for (var item in this.handlers) {
-            toCall.push(this.handlers[item]);
-        }
-        for (var i = 0; i < toCall.length; ++i) {
-            toCall[i].apply(this, fireArgs);
-        }
-        if (this.state == 2 && this.numHandlers) {
-            this.numHandlers = 0;
-            this.handlers = {};
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-
-// defining them here so they are ready super fast!
-// DOM event that is received when the web page is loaded and parsed.
-channel.createSticky('onDOMContentLoaded');
-
-// Event to indicate the Cordova native side is ready.
-channel.createSticky('onNativeReady');
-
-// Event to indicate that all Cordova JavaScript objects have been created
-// and it's time to run plugin constructors.
-channel.createSticky('onCordovaReady');
-
-// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-channel.createSticky('onPluginsReady');
-
-// Event to indicate that Cordova is ready
-channel.createSticky('onDeviceReady');
-
-// Event to indicate a resume lifecycle event
-channel.create('onResume');
-
-// Event to indicate a pause lifecycle event
-channel.create('onPause');
-
-// Event to indicate a destroy lifecycle event
-channel.createSticky('onDestroy');
-
-// Channels that must fire before "deviceready" is fired.
-channel.waitForInitialization('onCordovaReady');
-channel.waitForInitialization('onDOMContentLoaded');
-
-module.exports = channel;
-
-});
-
-// file: lib/android/exec.js
-define("cordova/exec", function(require, exports, module) {
-
-/**
- * Execute a cordova command.  It is up to the native side whether this action
- * is synchronous or asynchronous.  The native side can return:
- *      Synchronous: PluginResult object as a JSON string
- *      Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success    The success callback
- * @param {Function} fail       The fail callback
- * @param {String} service      The name of the service to use
- * @param {String} action       Action to be run in cordova
- * @param {String[]} [args]     Zero or more arguments to pass to the method
- */
-var cordova = require('cordova'),
-    nativeApiProvider = require('cordova/android/nativeapiprovider'),
-    utils = require('cordova/utils'),
-    base64 = require('cordova/base64'),
-    jsToNativeModes = {
-        PROMPT: 0,
-        JS_OBJECT: 1,
-        // This mode is currently for benchmarking purposes only. It must be enabled
-        // on the native side through the ENABLE_LOCATION_CHANGE_EXEC_MODE
-        // constant within CordovaWebViewClient.java before it will work.
-        LOCATION_CHANGE: 2
-    },
-    nativeToJsModes = {
-        // Polls for messages using the JS->Native bridge.
-        POLLING: 0,
-        // For LOAD_URL to be viable, it would need to have a work-around for
-        // the bug where the soft-keyboard gets dismissed when a message is sent.
-        LOAD_URL: 1,
-        // For the ONLINE_EVENT to be viable, it would need to intercept all event
-        // listeners (both through addEventListener and window.ononline) as well
-        // as set the navigator property itself.
-        ONLINE_EVENT: 2,
-        // Uses reflection to access private APIs of the WebView that can send JS
-        // to be executed.
-        // Requires Android 3.2.4 or above.
-        PRIVATE_API: 3
-    },
-    jsToNativeBridgeMode,  // Set lazily.
-    nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
-    pollEnabled = false,
-    messagesFromNative = [];
-
-function androidExec(success, fail, service, action, args) {
-    // Set default bridge modes if they have not already been set.
-    // By default, we use the failsafe, since addJavascriptInterface breaks too often
-    if (jsToNativeBridgeMode === undefined) {
-        androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
-    }
-
-    // Process any ArrayBuffers in the args into a string.
-    for (var i = 0; i < args.length; i++) {
-        if (utils.typeName(args[i]) == 'ArrayBuffer') {
-            args[i] = base64.fromArrayBuffer(args[i]);
-        }
-    }
-
-    var callbackId = service + cordova.callbackId++,
-        argsJson = JSON.stringify(args);
-
-    if (success || fail) {
-        cordova.callbacks[callbackId] = {success:success, fail:fail};
-    }
-
-    if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) {
-        window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;
-    } else {
-        var messages = nativeApiProvider.get().exec(service, action, callbackId, argsJson);
-        // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
-        // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2.  See CB-2666.
-        if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && messages === "@Null arguments.") {
-            androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
-            androidExec(success, fail, service, action, args);
-            androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
-            return;
-        } else {
-            androidExec.processMessages(messages);
-        }
-    }
-}
-
-function pollOnceFromOnlineEvent() {
-    pollOnce(true);
-}
-
-function pollOnce(opt_fromOnlineEvent) {
-    var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent);
-    androidExec.processMessages(msg);
-}
-
-function pollingTimerFunc() {
-    if (pollEnabled) {
-        pollOnce();
-        setTimeout(pollingTimerFunc, 50);
-    }
-}
-
-function hookOnlineApis() {
-    function proxyEvent(e) {
-        cordova.fireWindowEvent(e.type);
-    }
-    // The network module takes care of firing online and offline events.
-    // It currently fires them only on document though, so we bridge them
-    // to window here (while first listening for exec()-releated online/offline
-    // events).
-    window.addEventListener('online', pollOnceFromOnlineEvent, false);
-    window.addEventListener('offline', pollOnceFromOnlineEvent, false);
-    cordova.addWindowEventHandler('online');
-    cordova.addWindowEventHandler('offline');
-    document.addEventListener('online', proxyEvent, false);
-    document.addEventListener('offline', proxyEvent, false);
-}
-
-hookOnlineApis();
-
-androidExec.jsToNativeModes = jsToNativeModes;
-androidExec.nativeToJsModes = nativeToJsModes;
-
-androidExec.setJsToNativeBridgeMode = function(mode) {
-    if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
-        console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
-        mode = jsToNativeModes.PROMPT;
-    }
-    nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
-    jsToNativeBridgeMode = mode;
-};
-
-androidExec.setNativeToJsBridgeMode = function(mode) {
-    if (mode == nativeToJsBridgeMode) {
-        return;
-    }
-    if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
-        pollEnabled = false;
-    }
-
-    nativeToJsBridgeMode = mode;
-    // Tell the native side to switch modes.
-    nativeApiProvider.get().setNativeToJsBridgeMode(mode);
-
-    if (mode == nativeToJsModes.POLLING) {
-        pollEnabled = true;
-        setTimeout(pollingTimerFunc, 1);
-    }
-};
-
-// Processes a single message, as encoded by NativeToJsMessageQueue.java.
-function processMessage(message) {
-    try {
-        var firstChar = message.charAt(0);
-        if (firstChar == 'J') {
-            eval(message.slice(1));
-        } else if (firstChar == 'S' || firstChar == 'F') {
-            var success = firstChar == 'S';
-            var keepCallback = message.charAt(1) == '1';
-            var spaceIdx = message.indexOf(' ', 2);
-            var status = +message.slice(2, spaceIdx);
-            var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
-            var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
-            var payloadKind = message.charAt(nextSpaceIdx + 1);
-            var payload;
-            if (payloadKind == 's') {
-                payload = message.slice(nextSpaceIdx + 2);
-            } else if (payloadKind == 't') {
-                payload = true;
-            } else if (payloadKind == 'f') {
-                payload = false;
-            } else if (payloadKind == 'N') {
-                payload = null;
-            } else if (payloadKind == 'n') {
-                payload = +message.slice(nextSpaceIdx + 2);
-            } else if (payloadKind == 'A') {
-                var data = message.slice(nextSpaceIdx + 2);
-                var bytes = window.atob(data);
-                var arraybuffer = new Uint8Array(bytes.length);
-                for (var i = 0; i < bytes.length; i++) {
-                    arraybuffer[i] = bytes.charCodeAt(i);
-                }
-                payload = arraybuffer.buffer;
-            } else if (payloadKind == 'S') {
-                payload = window.atob(message.slice(nextSpaceIdx + 2));
-            } else {
-                payload = JSON.parse(message.slice(nextSpaceIdx + 1));
-            }
-            cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
-        } else {
-            console.log("processMessage failed: invalid message:" + message);
-        }
-    } catch (e) {
-        console.log("processMessage failed: Message: " + message);
-        console.log("processMessage failed: Error: " + e);
-        console.log("processMessage failed: Stack: " + e.stack);
-    }
-}
-
-// This is called from the NativeToJsMessageQueue.java.
-androidExec.processMessages = function(messages) {
-    if (messages) {
-        messagesFromNative.push(messages);
-        // Check for the reentrant case, and enqueue the message if that's the case.
-        if (messagesFromNative.length > 1) {
-            return;
-        }
-        while (messagesFromNative.length) {
-            // Don't unshift until the end so that reentrancy can be detected.
-            messages = messagesFromNative[0];
-            // The Java side can send a * message to indicate that it
-            // still has messages waiting to be retrieved.
-            if (messages == '*') {
-                messagesFromNative.shift();
-                window.setTimeout(pollOnce, 0);
-                return;
-            }
-
-            var spaceIdx = messages.indexOf(' ');
-            var msgLen = +messages.slice(0, spaceIdx);
-            var message = messages.substr(spaceIdx + 1, msgLen);
-            messages = messages.slice(spaceIdx + msgLen + 1);
-            processMessage(message);
-            if (messages) {
-                messagesFromNative[0] = messages;
-            } else {
-                messagesFromNative.shift();
-            }
-        }
-    }
-};
-
-module.exports = androidExec;
-
-});
-
-// file: lib/common/init.js
-define("cordova/init", function(require, exports, module) {
-
-var channel = require('cordova/channel');
-var cordova = require('cordova');
-var modulemapper = require('cordova/modulemapper');
-var platform = require('cordova/platform');
-var pluginloader = require('cordova/pluginloader');
-
-var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
-
-function logUnfiredChannels(arr) {
-    for (var i = 0; i < arr.length; ++i) {
-        if (arr[i].state != 2) {
-            console.log('Channel not fired: ' + arr[i].type);
-        }
-    }
-}
-
-window.setTimeout(function() {
-    if (channel.onDeviceReady.state != 2) {
-        console.log('deviceready has not fired after 5 seconds.');
-        logUnfiredChannels(platformInitChannelsArray);
-        logUnfiredChannels(channel.deviceReadyChannelsArray);
-    }
-}, 5000);
-
-// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
-// We replace it so that properties that can't be clobbered can instead be overridden.
-function replaceNavigator(origNavigator) {
-    var CordovaNavigator = function() {};
-    CordovaNavigator.prototype = origNavigator;
-    var newNavigator = new CordovaNavigator();
-    // This work-around really only applies to new APIs that are newer than Function.bind.
-    // Without it, APIs such as getGamepads() break.
-    if (CordovaNavigator.bind) {
-        for (var key in origNavigator) {
-            if (typeof origNavigator[key] == 'function') {
-                newNavigator[key] = origNavigator[key].bind(origNavigator);
-            }
-        }
-    }
-    return newNavigator;
-}
-if (window.navigator) {
-    window.navigator = replaceNavigator(window.navigator);
-}
-
-if (!window.console) {
-    window.console = {
-        log: function(){}
-    };
-}
-if (!window.console.warn) {
-    window.console.warn = function(msg) {
-        this.log("warn: " + msg);
-    };
-}
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
-
-// Listen for DOMContentLoaded and notify our channel subscribers.
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
-    channel.onDOMContentLoaded.fire();
-} else {
-    document.addEventListener('DOMContentLoaded', function() {
-        channel.onDOMContentLoaded.fire();
-    }, false);
-}
-
-// _nativeReady is global variable that the native side can set
-// to signify that the native code is ready. It is a global since
-// it may be called before any cordova JS is ready.
-if (window._nativeReady) {
-    channel.onNativeReady.fire();
-}
-
-modulemapper.clobbers('cordova', 'cordova');
-modulemapper.clobbers('cordova/exec', 'cordova.exec');
-modulemapper.clobbers('cordova/exec', 'Cordova.exec');
-
-// Call the platform-specific initialization.
-platform.bootstrap && platform.bootstrap();
-
-pluginloader.load(function() {
-    channel.onPluginsReady.fire();
-});
-
-/**
- * Create all cordova objects once native side is ready.
- */
-channel.join(function() {
-    modulemapper.mapModules(window);
-
-    platform.initialize && platform.initialize();
-
-    // Fire event to notify that all objects are created
-    channel.onCordovaReady.fire();
-
-    // Fire onDeviceReady event once page has fully loaded, all
-    // constructors have run and cordova info has been received from native
-    // side.
-    channel.join(function() {
-        require('cordova').fireDocumentEvent('deviceready');
-    }, channel.deviceReadyChannelsArray);
-
-}, platformInitChannelsArray);
-
-
-});
-
-// file: lib/common/modulemapper.js
-define("cordova/modulemapper", function(require, exports, module) {
-
-var builder = require('cordova/builder'),
-    moduleMap = define.moduleMap,
-    symbolList,
-    deprecationMap;
-
-exports.reset = function() {
-    symbolList = [];
-    deprecationMap = {};
-};
-
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
-    if (!(moduleName in moduleMap)) {
-        throw new Error('Module ' + moduleName + ' does not exist.');
-    }
-    symbolList.push(strategy, moduleName, symbolPath);
-    if (opt_deprecationMessage) {
-        deprecationMap[symbolPath] = opt_deprecationMessage;
-    }
-}
-
-// Note: Android 2.3 does have Function.bind().
-exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.runs = function(moduleName) {
-    addEntry('r', moduleName, null);
-};
-
-function prepareNamespace(symbolPath, context) {
-    if (!symbolPath) {
-        return context;
-    }
-    var parts = symbolPath.split('.');
-    var cur = context;
-    for (var i = 0, part; part = parts[i]; ++i) {
-        cur = cur[part] = cur[part] || {};
-    }
-    return cur;
-}
-
-exports.mapModules = function(context) {
-    var origSymbols = {};
-    context.CDV_origSymbols = origSymbols;
-    for (var i = 0, len = symbolList.length; i < len; i += 3) {
-        var strategy = symbolList[i];
-        var moduleName = symbolList[i + 1];
-        var module = require(moduleName);
-        // <runs/>
-        if (strategy == 'r') {
-            continue;
-        }
-        var symbolPath = symbolList[i + 2];
-        var lastDot = symbolPath.lastIndexOf('.');
-        var namespace = symbolPath.substr(0, lastDot);
-        var lastName = symbolPath.substr(lastDot + 1);
-
-        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
-        var parentObj = prepareNamespace(namespace, context);
-        var target = parentObj[lastName];
-
-        if (strategy == 'm' && target) {
-            builder.recursiveMerge(target, module);
-        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
-            if (!(symbolPath in origSymbols)) {
-                origSymbols[symbolPath] = target;
-            }
-            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
-        }
-    }
-};
-
-exports.getOriginalSymbol = function(context, symbolPath) {
-    var origSymbols = context.CDV_origSymbols;
-    if (origSymbols && (symbolPath in origSymbols)) {
-        return origSymbols[symbolPath];
-    }
-    var parts = symbolPath.split('.');
-    var obj = context;
-    for (var i = 0; i < parts.length; ++i) {
-        obj = obj && obj[parts[i]];
-    }
-    return obj;
-};
-
-exports.reset();
-
-
-});
-
-// file: lib/android/platform.js
-define("cordova/platform", function(require, exports, module) {
-
-module.exports = {
-    id: 'android',
-    bootstrap: function() {
-        var channel = require('cordova/channel'),
-            cordova = require('cordova'),
-            exec = require('cordova/exec'),
-            modulemapper = require('cordova/modulemapper');
-
-        // Tell the native code that a page change has occurred.
-        exec(null, null, 'PluginManager', 'startup', []);
-        // Tell the JS that the native side is ready.
-        channel.onNativeReady.fire();
-
-        // TODO: Extract this as a proper plugin.
-        modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
-
-        // Inject a listener for the backbutton on the document.
-        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
-        backButtonChannel.onHasSubscribersChange = function() {
-            // If we just attached the first handler or detached the last handler,
-            // let native know we need to override the back button.
-            exec(null, null, "App", "overrideBackbutton", [this.numHandlers == 1]);
-        };
-
-        // Add hardware MENU and SEARCH button handlers
-        cordova.addDocumentEventHandler('menubutton');
-        cordova.addDocumentEventHandler('searchbutton');
-
-        // Let native code know we are all done on the JS side.
-        // Native code will then un-hide the WebView.
-        channel.onCordovaReady.subscribe(function() {
-            exec(null, null, "App", "show", []);
-        });
-    }
-};
-
-});
-
-// file: lib/android/plugin/android/app.js
-define("cordova/plugin/android/app", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-module.exports = {
-    /**
-    * Clear the resource cache.
-    */
-    clearCache:function() {
-        exec(null, null, "App", "clearCache", []);
-    },
-
-    /**
-    * Load the url into the webview or into new browser instance.
-    *
-    * @param url           The URL to load
-    * @param props         Properties that can be passed in to the activity:
-    *      wait: int                           => wait msec before loading URL
-    *      loadingDialog: "Title,Message"      => display a native loading dialog
-    *      loadUrlTimeoutValue: int            => time in msec to wait before triggering a timeout error
-    *      clearHistory: boolean              => clear webview history (default=false)
-    *      openExternal: boolean              => open in a new browser (default=false)
-    *
-    * Example:
-    *      navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
-    */
-    loadUrl:function(url, props) {
-        exec(null, null, "App", "loadUrl", [url, props]);
-    },
-
-    /**
-    * Cancel loadUrl that is waiting to be loaded.
-    */
-    cancelLoadUrl:function() {
-        exec(null, null, "App", "cancelLoadUrl", []);
-    },
-
-    /**
-    * Clear web history in this web view.
-    * Instead of BACK button loading the previous web page, it will exit the app.
-    */
-    clearHistory:function() {
-        exec(null, null, "App", "clearHistory", []);
-    },
-
-    /**
-    * Go to previous page displayed.
-    * This is the same as pressing the backbutton on Android device.
-    */
-    backHistory:function() {
-        exec(null, null, "App", "backHistory", []);
-    },
-
-    /**
-    * Override the default behavior of the Android back button.
-    * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
-    *
-    * Note: The user should not have to call this method.  Instead, when the user
-    *       registers for the "backbutton" event, this is automatically done.
-    *
-    * @param override        T=override, F=cancel override
-    */
-    overrideBackbutton:function(override) {
-        exec(null, null, "App", "overrideBackbutton", [override]);
-    },
-
-    /**
-    * Exit and terminate the application.
-    */
-    exitApp:function() {
-        return exec(null, null, "App", "exitApp", []);
-    }
-};
-
-});
-
-// file: lib/common/pluginloader.js
-define("cordova/pluginloader", function(require, exports, module) {
-
-var modulemapper = require('cordova/modulemapper');
-
-// Helper function to inject a <script> tag.
-function injectScript(url, onload, onerror) {
-    var script = document.createElement("script");
-    // onload fires even when script fails loads with an error.
-    script.onload = onload;
-    script.onerror = onerror || onload;
-    script.src = url;
-    document.head.appendChild(script);
-}
-
-function onScriptLoadingComplete(moduleList, finishPluginLoading) {
-    // Loop through all the plugins and then through their clobbers and merges.
-    for (var i = 0, module; module = moduleList[i]; i++) {
-        if (module) {
-            try {
-                if (module.clobbers && module.clobbers.length) {
-                    for (var j = 0; j < module.clobbers.length; j++) {
-                        modulemapper.clobbers(module.id, module.clobbers[j]);
-                    }
-                }
-
-                if (module.merges && module.merges.length) {
-                    for (var k = 0; k < module.merges.length; k++) {
-                        modulemapper.merges(module.id, module.merges[k]);
-                    }
-                }
-
-                // Finally, if runs is truthy we want to simply require() the module.
-                // This can be skipped if it had any merges or clobbers, though,
-                // since the mapper will already have required the module.
-                if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
-                    modulemapper.runs(module.id);
-                }
-            }
-            catch(err) {
-                // error with module, most likely clobbers, should we continue?
-            }
-        }
-    }
-
-    finishPluginLoading();
-}
-
-// Handler for the cordova_plugins.js content.
-// See plugman's plugin_loader.js for the details of this object.
-// This function is only called if the really is a plugins array that isn't empty.
-// Otherwise the onerror response handler will just call finishPluginLoading().
-function handlePluginsObject(path, moduleList, finishPluginLoading) {
-    // Now inject the scripts.
-    var scriptCounter = moduleList.length;
-
-    if (!scriptCounter) {
-        finishPluginLoading();
-        return;
-    }
-    function scriptLoadedCallback() {
-        if (!--scriptCounter) {
-            onScriptLoadingComplete(moduleList, finishPluginLoading);
-        }
-    }
-
-    for (var i = 0; i < moduleList.length; i++) {
-        injectScript(path + moduleList[i].file, scriptLoadedCallback);
-    }
-}
-
-function injectPluginScript(pathPrefix, finishPluginLoading) {
-    injectScript(pathPrefix + 'cordova_plugins.js', function(){
-        try {
-            var moduleList = require("cordova/plugin_list");
-            handlePluginsObject(pathPrefix, moduleList, finishPluginLoading);
-        } catch (e) {
-            // Error loading cordova_plugins.js, file not found or something
-            // this is an acceptable error, pre-3.0.0, so we just move on.
-            finishPluginLoading();
-        }
-    }, finishPluginLoading); // also, add script load error handler for file not found
-}
-
-function findCordovaPath() {
-    var path = null;
-    var scripts = document.getElementsByTagName('script');
-    var term = 'cordova.js';
-    for (var n = scripts.length-1; n>-1; n--) {
-        var src = scripts[n].src;
-        if (src.indexOf(term) == (src.length - term.length)) {
-            path = src.substring(0, src.length - term.length);
-            break;
-        }
-    }
-    return path;
-}
-
-// Tries to load all plugins' js-modules.
-// This is an async process, but onDeviceReady is blocked on onPluginsReady.
-// onPluginsReady is fired when there are no plugins to load, or they are all done.
-exports.load = function(callback) {
-    var pathPrefix = findCordovaPath();
-    if (pathPrefix === null) {
-        console.log('Could not find cordova.js script tag. Plugin loading may fail.');
-        pathPrefix = '';
-    }
-    injectPluginScript(pathPrefix, callback);
-};
-
-
-});
-
-// file: lib/common/urlutil.js
-define("cordova/urlutil", function(require, exports, module) {
-
-var urlutil = exports;
-var anchorEl = document.createElement('a');
-
-/**
- * For already absolute URLs, returns what is passed in.
- * For relative URLs, converts them to absolute ones.
- */
-urlutil.makeAbsolute = function(url) {
-  anchorEl.href = url;
-  return anchorEl.href;
-};
-
-});
-
-// file: lib/common/utils.js
-define("cordova/utils", function(require, exports, module) {
-
-var utils = exports;
-
-/**
- * Defines a property getter / setter for obj[key].
- */
-utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
-    if (Object.defineProperty) {
-        var desc = {
-            get: getFunc,
-            configurable: true
-        };
-        if (opt_setFunc) {
-            desc.set = opt_setFunc;
-        }
-        Object.defineProperty(obj, key, desc);
-    } else {
-        obj.__defineGetter__(key, getFunc);
-        if (opt_setFunc) {
-            obj.__defineSetter__(key, opt_setFunc);
-        }
-    }
-};
-
-/**
- * Defines a property getter for obj[key].
- */
-utils.defineGetter = utils.defineGetterSetter;
-
-utils.arrayIndexOf = function(a, item) {
-    if (a.indexOf) {
-        return a.indexOf(item);
-    }
-    var len = a.length;
-    for (var i = 0; i < len; ++i) {
-        if (a[i] == item) {
-            return i;
-        }
-    }
-    return -1;
-};
-
-/**
- * Returns whether the item was found in the array.
- */
-utils.arrayRemove = function(a, item) {
-    var index = utils.arrayIndexOf(a, item);
-    if (index != -1) {
-        a.splice(index, 1);
-    }
-    return index != -1;
-};
-
-utils.typeName = function(val) {
-    return Object.prototype.toString.call(val).slice(8, -1);
-};
-
-/**
- * Returns an indication of whether the argument is an array or not
- */
-utils.isArray = function(a) {
-    return utils.typeName(a) == 'Array';
-};
-
-/**
- * Returns an indication of whether the argument is a Date or not
- */
-utils.isDate = function(d) {
-    return utils.typeName(d) == 'Date';
-};
-
-/**
- * Does a deep clone of the object.
- */
-utils.clone = function(obj) {
-    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
-        return obj;
-    }
-
-    var retVal, i;
-
-    if(utils.isArray(obj)){
-        retVal = [];
-        for(i = 0; i < obj.length; ++i){
-            retVal.push(utils.clone(obj[i]));
-        }
-        return retVal;
-    }
-
-    retVal = {};
-    for(i in obj){
-        if(!(i in retVal) || retVal[i] != obj[i]) {
-            retVal[i] = utils.clone(obj[i]);
-        }
-    }
-    return retVal;
-};
-
-/**
- * Returns a wrapped version of the function
- */
-utils.close = function(context, func, params) {
-    if (typeof params == 'undefined') {
-        return function() {
-            return func.apply(context, arguments);
-        };
-    } else {
-        return function() {
-            return func.apply(context, params);
-        };
-    }
-};
-
-/**
- * Create a UUID
- */
-utils.createUUID = function() {
-    return UUIDcreatePart(4) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(6);
-};
-
-/**
- * Extends a child object from a parent object using classical inheritance
- * pattern.
- */
-utils.extend = (function() {
-    // proxy used to establish prototype chain
-    var F = function() {};
-    // extend Child from Parent
-    return function(Child, Parent) {
-        F.prototype = Parent.prototype;
-        Child.prototype = new F();
-        Child.__super__ = Parent.prototype;
-        Child.prototype.constructor = Child;
-    };
-}());
-
-/**
- * Alerts a message in any available way: alert or console.log.
- */
-utils.alert = function(msg) {
-    if (window.alert) {
-        window.alert(msg);
-    } else if (console && console.log) {
-        console.log(msg);
-    }
-};
-
-
-//------------------------------------------------------------------------------
-function UUIDcreatePart(length) {
-    var uuidpart = "";
-    for (var i=0; i<length; i++) {
-        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
-        if (uuidchar.length == 1) {
-            uuidchar = "0" + uuidchar;
-        }
-        uuidpart += uuidchar;
-    }
-    return uuidpart;
-}
-
-
-});
-
-window.cordova = require('cordova');
-// file: lib/scripts/bootstrap.js
-
-require('cordova/init');
-
-})();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js
deleted file mode 100644
index b58b5dd..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/cordova_plugins.js
+++ /dev/null
@@ -1,3 +0,0 @@
-cordova.define('cordova/plugin_list', function(require, exports, module) {
-module.exports = []
-});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css
deleted file mode 100644
index 51daa79..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/css/index.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-* {
-    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
-}
-
-body {
-    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
-    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
-    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
-    background-color:#E4E4E4;
-    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
-    background-image:-webkit-gradient(
-        linear,
-        left top,
-        left bottom,
-        color-stop(0, #A7A7A7),
-        color-stop(0.51, #E4E4E4)
-    );
-    background-attachment:fixed;
-    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
-    font-size:12px;
-    height:100%;
-    margin:0px;
-    padding:0px;
-    text-transform:uppercase;
-    width:100%;
-}
-
-/* Portrait layout (default) */
-.app {
-    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
-    position:absolute;             /* position in the center of the screen */
-    left:50%;
-    top:50%;
-    height:50px;                   /* text area height */
-    width:225px;                   /* text area width */
-    text-align:center;
-    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
-    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
-                                   /* offset horizontal: half of text area width */
-}
-
-/* Landscape layout (with min-width) */
-@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
-    .app {
-        background-position:left center;
-        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
-        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
-                                      /* offset horizontal: half of image width and text area width */
-    }
-}
-
-h1 {
-    font-size:24px;
-    font-weight:normal;
-    margin:0px;
-    overflow:visible;
-    padding:0px;
-    text-align:center;
-}
-
-.event {
-    border-radius:4px;
-    -webkit-border-radius:4px;
-    color:#FFFFFF;
-    font-size:12px;
-    margin:0px 30px;
-    padding:2px 0px;
-}
-
-.event.listening {
-    background-color:#333333;
-    display:block;
-}
-
-.event.received {
-    background-color:#4B946A;
-    display:none;
-}
-
-@keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-@-webkit-keyframes fade {
-    from { opacity: 1.0; }
-    50% { opacity: 0.4; }
-    to { opacity: 1.0; }
-}
- 
-.blink {
-    animation:fade 3000ms infinite;
-    -webkit-animation:fade 3000ms infinite;
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png
deleted file mode 100644
index 9519e7d..0000000
Binary files a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/img/logo.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html
deleted file mode 100644
index bde5741..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <meta charset="utf-8" />
-        <meta name="format-detection" content="telephone=no" />
-        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
-        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
-        <link rel="stylesheet" type="text/css" href="css/index.css" />
-        <title>Hello World</title>
-    </head>
-    <body>
-        <div class="app">
-            <h1>Apache Cordova</h1>
-            <div id="deviceready" class="blink">
-                <p class="event listening">Connecting to Device</p>
-                <p class="event received">Device is Ready</p>
-            </div>
-        </div>
-        <script type="text/javascript" src="cordova.js"></script>
-        <script type="text/javascript" src="js/index.js"></script>
-        <script type="text/javascript">
-            app.initialize();
-        </script>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js
deleted file mode 100644
index 31d9064..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/js/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-var app = {
-    // Application Constructor
-    initialize: function() {
-        this.bindEvents();
-    },
-    // Bind Event Listeners
-    //
-    // Bind any events that are required on startup. Common events are:
-    // 'load', 'deviceready', 'offline', and 'online'.
-    bindEvents: function() {
-        document.addEventListener('deviceready', this.onDeviceReady, false);
-    },
-    // deviceready Event Handler
-    //
-    // The scope of 'this' is the event. In order to call the 'receivedEvent'
-    // function, we must explicity call 'app.receivedEvent(...);'
-    onDeviceReady: function() {
-        app.receivedEvent('deviceready');
-    },
-    // Update DOM on a Received Event
-    receivedEvent: function(id) {
-        var parentElement = document.getElementById(id);
-        var listeningElement = parentElement.querySelector('.listening');
-        var receivedElement = parentElement.querySelector('.received');
-
-        listeningElement.setAttribute('style', 'display:none;');
-        receivedElement.setAttribute('style', 'display:block;');
-
-        console.log('Received Event: ' + id);
-    }
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html b/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html
deleted file mode 100644
index 71f00de..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/assets/www/spec.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-     KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
--->
-<html>
-    <head>
-        <title>Jasmine Spec Runner</title>
-
-        <!-- jasmine source -->
-        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
-        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
-        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
-
-        <!-- include source files here... -->
-        <script type="text/javascript" src="js/index.js"></script>
-
-        <!-- include spec files here... -->
-        <script type="text/javascript" src="spec/helper.js"></script>
-        <script type="text/javascript" src="spec/index.js"></script>
-
-        <script type="text/javascript">
-            (function() {
-                var jasmineEnv = jasmine.getEnv();
-                jasmineEnv.updateInterval = 1000;
-
-                var htmlReporter = new jasmine.HtmlReporter();
-
-                jasmineEnv.addReporter(htmlReporter);
-
-                jasmineEnv.specFilter = function(spec) {
-                    return htmlReporter.specFilter(spec);
-                };
-
-                var currentWindowOnload = window.onload;
-
-                window.onload = function() {
-                    if (currentWindowOnload) {
-                        currentWindowOnload();
-                    }
-                    execJasmine();
-                };
-
-                function execJasmine() {
-                    jasmineEnv.execute();
-                }
-            })();
-        </script>
-    </head>
-    <body>
-        <div id="stage" style="display:none;"></div>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml
deleted file mode 100644
index 9674edf..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/build.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="TestBase" default="help">
-
-    <!-- The local.properties file is created and updated by the 'android' tool.
-         It contains the path to the SDK. It should *NOT* be checked into
-         Version Control Systems. -->
-    <property file="local.properties" />
-
-    <!-- The ant.properties file can be created by you. It is only edited by the
-         'android' tool to add properties to it.
-         This is the place to change some Ant specific build properties.
-         Here are some properties you may want to change/update:
-
-         source.dir
-             The name of the source directory. Default is 'src'.
-         out.dir
-             The name of the output directory. Default is 'bin'.
-
-         For other overridable properties, look at the beginning of the rules
-         files in the SDK, at tools/ant/build.xml
-
-         Properties related to the SDK location or the project target should
-         be updated using the 'android' tool with the 'update' action.
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems.
-
-         -->
-    <property file="ant.properties" />
-
-    <!-- if sdk.dir was not set from one of the property file, then
-         get it from the ANDROID_HOME env var.
-         This must be done before we load project.properties since
-         the proguard config can use sdk.dir -->
-    <property environment="env" />
-    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
-        <isset property="env.ANDROID_HOME" />
-    </condition>
-
-    <!-- The project.properties file is created and updated by the 'android'
-         tool, as well as ADT.
-
-         This contains project specific properties such as project target, and library
-         dependencies. Lower level build properties are stored in ant.properties
-         (or in .classpath for Eclipse projects).
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems. -->
-    <loadproperties srcFile="project.properties" />
-
-    <!-- quick check on sdk.dir -->
-    <fail
-            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
-            unless="sdk.dir"
-    />
-
-    <!--
-        Import per project custom build rules if present at the root of the project.
-        This is the place to put custom intermediary targets such as:
-            -pre-build
-            -pre-compile
-            -post-compile (This is typically used for code obfuscation.
-                           Compiled code location: ${out.classes.absolute.dir}
-                           If this is not done in place, override ${out.dex.input.absolute.dir})
-            -post-package
-            -post-build
-            -pre-clean
-    -->
-    <import file="custom_rules.xml" optional="true" />
-
-    <!-- Import the actual build file.
-
-         To customize existing targets, there are two options:
-         - Customize only one target:
-             - copy/paste the target into this file, *before* the
-               <import> task.
-             - customize it to your needs.
-         - Customize the whole content of build.xml
-             - copy/paste the content of the rules files (minus the top node)
-               into this file, replacing the <import> task.
-             - customize to your needs.
-
-         ***********************
-         ****** IMPORTANT ******
-         ***********************
-         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
-         in order to avoid having your file be overridden by tools such as "android update project"
-    -->
-    <!-- version-tag: 1 -->
-    <import file="${sdk.dir}/tools/ant/build.xml" />
-
-</project>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build
deleted file mode 100755
index 7028eb8..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/build
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var build = require('./lib/build'),
-    reqs  = require('./lib/check_reqs'),
-    args  = process.argv;
-
-// Support basic help commands
-if(args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
-                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
-    build.help();
-} else if(reqs.run()) {
-    build.run(args[2]);
-    process.exit(0);
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs
deleted file mode 100755
index 4a8abee..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/check_reqs
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var check_reqs = require('./lib/check_reqs');
-
-if(!check_reqs.run()) {
-      process.exit(2);
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean
deleted file mode 100755
index 70c4ca8..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/clean
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var clean = require('./lib/clean'),
-    reqs  = require('./lib/check_reqs'),
-    args  = process.argv;
-
-// Usage support for when args are given
-if(args.length > 2) {
-    clean.help();
-} else if(reqs.run()) {
-    clean.run();
-    process.exit(0);
-} else {
-    process.exit(2);
-}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml
deleted file mode 100644
index 24e5725..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/defaults.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<widget xmlns     = "http://www.w3.org/ns/widgets"
-        id        = "io.cordova.helloCordova"
-        version   = "2.0.0">
-    <name>Hello Cordova</name>
-
-    <description>
-        A sample Apache Cordova application that responds to the deviceready event.
-    </description>
-
-    <author href="http://cordova.io" email="dev@cordova.apache.org">
-        Apache Cordova Team
-    </author>
-
-    <access origin="*"/>
-
-    <!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
-    <content src="index.html" />
-
-    <preference name="loglevel" value="DEBUG" />
-    <!--
-      <preference name="splashscreen" value="resourceName" />
-      <preference name="backgroundColor" value="0xFFF" />
-      <preference name="loadUrlTimeoutValue" value="20000" />
-      <preference name="InAppBrowserStorageEnabled" value="true" />
-      <preference name="disallowOverscroll" value="true" />
-    -->
-    <!-- This is required for native Android hooks -->
-    <feature name="App">
-        <param name="android-package" value="org.apache.cordova.App" />
-    </feature>
-</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js
deleted file mode 100755
index 1f8ebe2..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/appinfo.js
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var path = require('path');
-var fs = require('fs');
-var cachedAppInfo = null;
-
-function readAppInfoFromManifest() {
-    var manifestPath = path.join(__dirname, '..', '..', 'AndroidManifest.xml');
-    var manifestData = fs.readFileSync(manifestPath, {encoding:'utf8'});
-    var packageName = /\bpackage\s*=\s*"(.+?)"/.exec(manifestData);
-    if (!packageName) throw new Error('Could not find package name within ' + manifestPath);
-    var activityTag = /<activity\b[\s\S]*<\/activity>/.exec(manifestData);
-    if (!activityTag) throw new Error('Could not find <activity> within ' + manifestPath);
-    var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag);
-    if (!activityName) throw new Error('Could not find android:name within ' + manifestPath);
-
-    return packageName[1] + '/.' + activityName[1];
-}
-
-exports.getActivityName = function() {
-    return cachedAppInfo = cachedAppInfo || readAppInfoFromManifest();
-};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e3515ab/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js b/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js
deleted file mode 100755
index 7bc33ca..0000000
--- a/cordova-lib/spec-cordova/fixtures/platforms/android/cordova/lib/build.js
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-var shell   = require('shelljs'),
-    clean   = require('./clean'),
-    path    = require('path'),
-    fs      = require('fs'),
-    ROOT    = path.join(__dirname, '..', '..');
-
-/*
- * Builds the project with ant.
- */
-module.exports.run = function(build_type) {
-    //default build type
-    build_type = typeof build_type !== 'undefined' ? build_type : "--debug";
-    var cmd;
-    switch(build_type) {
-        case '--debug' :
-            clean.run();
-            cmd = 'ant debug -f ' + path.join(ROOT, 'build.xml');
-            break;
-        case '--release' :
-            clean.run();
-            cmd = 'ant release -f ' + path.join(ROOT, 'build.xml');
-            break;
-        case '--nobuild' :
-            console.log('Skipping build...');
-            break;
-        default :
-           console.error('Build option \'' + build_type + '\' not recognized.');
-           process.exit(2);
-           break;
-    }
-    if(cmd) {
-        var result = shell.exec(cmd, {silent:false, async:false});
-        if(result.code > 0) {
-            console.error('ERROR: Failed to build android project.');
-            console.error(result.output);
-            process.exit(2);
-        }
-    }
-}
-
-/*
- * Gets the path to the apk file, if not such file exists then
- * the script will error out. (should we error or just return undefined?)
- */
-module.exports.get_apk = function() {
-    if(fs.existsSync(path.join(ROOT, 'bin'))) {
-        var bin_files = fs.readdirSync(path.join(ROOT, 'bin'));
-        for (file in bin_files) {
-            if(path.extname(bin_files[file]) == '.apk') {
-                return path.join(ROOT, 'bin', bin_files[file]);
-            }
-        }
-        console.error('ERROR : No .apk found in \'bin\' folder');
-        process.exit(2);
-    } else {
-        console.error('ERROR : unable to find project bin folder, could not locate .apk');
-        process.exit(2);
-    }
-}
-
-module.exports.help = function() {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'build')) + ' [build_type]');
-    console.log('Build Types : ');
-    console.log('    \'--debug\': Default build, will build project in using ant debug');
-    console.log('    \'--release\': will build project using ant release');
-    console.log('    \'--nobuild\': will skip build process (can be used with run command)');
-    process.exit(0);
-}


[11/24] Split out cordova-lib: move cordova-cli files

Posted by ka...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/hooker.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/hooker.spec.js b/cordova-lib/spec-cordova/hooker.spec.js
new file mode 100644
index 0000000..c85cc59
--- /dev/null
+++ b/cordova-lib/spec-cordova/hooker.spec.js
@@ -0,0 +1,261 @@
+ /**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+**/
+
+
+var cordova = require('../cordova'),
+    hooker = require('../src/hooker'),
+    shell  = require('shelljs'),
+    path   = require('path'),
+    fs     = require('fs'),
+    os     = require('os'),
+    Q      = require('q'),
+    child_process = require('child_process'),
+    helpers = require('./helpers');
+
+var platform = os.platform();
+var tmpDir = helpers.tmpDir('hooks_test');
+var project = path.join(tmpDir, 'project');
+var dotCordova = path.join(project, '.cordova');
+var hooksDir = path.join(project, '.cordova', 'hooks');
+var ext = platform.match(/(win32|win64)/)?'bat':'sh';
+
+
+// copy fixture
+shell.rm('-rf', project);
+shell.mkdir('-p', project);
+shell.cp('-R', path.join(__dirname, 'fixtures', 'base', '*'), project);
+shell.mkdir('-p', dotCordova);
+shell.cp('-R', path.join(__dirname, 'fixtures', 'hooks_' + ext), dotCordova);
+shell.mv(path.join(dotCordova, 'hooks_' + ext), hooksDir);
+shell.chmod('-R', 'ug+x', hooksDir);
+
+
+describe('hooker', function() {
+    it('should throw if provided directory is not a cordova project', function() {
+        expect(function() {
+            new hooker(tmpDir);
+        }).toThrow();
+    });
+});
+
+describe('global (static) fire method', function() {
+    it('should execute listeners serially', function(done) {
+        var test_event = 'foo';
+        var h1_fired = false;
+        var h1 = function() {
+            expect(h2_fired).toBe(false);
+            // Delay 100 ms here to check that h2 is not executed until after
+            // the promise returned by h1 is resolved.
+            var q = Q.delay(100).then(function() {
+                h1_fired = true;
+            });
+            return q;
+        };
+        var h2_fired = false;
+        var h2 = function() {
+            h2_fired = true;
+            expect(h1_fired).toBe(true);
+            return Q();
+        };
+
+        cordova.on(test_event, h1);
+        cordova.on(test_event, h2);
+        hooker.fire(test_event).then(function() {
+            expect(h1_fired).toBe(true);
+            expect(h2_fired).toBe(true);
+            done();
+        });
+    });
+});
+
+describe('module-level hooks', function() {
+    var handler = jasmine.createSpy().andReturn(Q());
+    var test_event = 'before_build';
+    var h;
+
+    beforeEach(function() {
+        h = new hooker(project);
+    });
+
+    afterEach(function() {
+        cordova.removeAllListeners(test_event);
+        handler.reset();
+    });
+
+    it('should fire handlers using cordova.on', function(done) {
+        cordova.on(test_event, handler);
+        h.fire(test_event)
+        .then(function() {
+            expect(handler).toHaveBeenCalled();
+        })
+        .fail(function(err) {
+            expect(err).not.toBeDefined();
+        })
+        .fin(done);
+    });
+
+    it('should pass the project root folder as parameter into the module-level handlers', function(done) {
+        cordova.on(test_event, handler);
+        h.fire(test_event)
+        .then(function() {
+            expect(handler).toHaveBeenCalledWith({root:project});
+        })
+        .fail(function(err) {
+            console.log(err);
+            expect(err).not.toBeDefined();
+        })
+        .fin(done);
+    });
+
+    it('should be able to stop listening to events using cordova.off', function(done) {
+        cordova.on(test_event, handler);
+        cordova.off(test_event, handler);
+        h.fire(test_event)
+        .then(function() {
+            expect(handler).not.toHaveBeenCalled();
+        })
+        .fail(function(err) {
+            console.log(err);
+            expect(err).toBeUndefined();
+        })
+        .fin(done);
+    });
+
+    it('should allow for hook to opt into asynchronous execution and block further hooks from firing using the done callback', function(done) {
+        var h1_fired = false;
+        var h1 = function() {
+            h1_fired = true;
+            expect(h2_fired).toBe(false);
+            return Q();
+        };
+        var h2_fired = false;
+        var h2 = function() {
+            h2_fired = true;
+            expect(h1_fired).toBe(true);
+            return Q();
+        };
+
+        cordova.on(test_event, h1);
+        cordova.on(test_event, h2);
+        h.fire(test_event).then(function() {
+            expect(h1_fired).toBe(true);
+            expect(h2_fired).toBe(true);
+            done();
+        });
+    });
+
+    it('should pass data object that fire calls into async handlers', function(done) {
+        var data = {
+            "hi":"ho",
+            "offtowork":"wego"
+        };
+        var async = function(opts) {
+            data.root = tmpDir;
+            expect(opts).toEqual(data);
+            return Q();
+        };
+        cordova.on(test_event, async);
+        h.fire(test_event, data).then(done);
+    });
+
+    it('should pass data object that fire calls into sync handlers', function(done) {
+        var data = {
+            "hi":"ho",
+            "offtowork":"wego"
+        };
+        var async = function(opts) {
+            data.root = tmpDir;
+            expect(opts).toEqual(data);
+        };
+        cordova.on(test_event, async);
+        h.fire(test_event, data).then(done);
+    });
+});
+
+
+describe('hooks', function() {
+    var h;
+    beforeEach(function() {
+        h = new hooker(project);
+    });
+
+
+    it('should not error if the hook is unrecognized', function(done) {
+        h.fire('CLEAN YOUR SHORTS GODDAMNIT LIKE A BIG BOY!')
+        .fail(function (err) {
+            expect('Call with unrecogized hook ').toBe('successful.\n' + err);
+        })
+        .fin(done);
+    });
+
+    it('should error if any script exits with non-zero code', function(done) {
+        h.fire('fail').then(function() {
+            expect('the call').toBe('a failure');
+        }, function(err) {
+            expect(err).toBeDefined();
+        })
+        .fin(done);
+    });
+
+    it('should execute all scripts in order', function(done) {
+        h.fire('test')
+        .then(function() {
+            var hooksOrderFile = path.join(project, 'hooks_order.txt');
+            var hooksEnvFile = path.join(project, 'hooks_env.json');
+            var hooksParamsFile = path.join(project, 'hooks_params.txt');
+            expect(hooksOrderFile).toExist();
+            expect(hooksEnvFile).toExist();
+            expect(hooksParamsFile).toExist();
+            expect(path.join(project, 'dotted_hook_should_not_fire.txt')).not.toExist();
+
+            var order = fs.readFileSync(hooksOrderFile, 'ascii').replace(/\W/gm, '');
+            expect(order).toBe('ab');
+
+            var params = fs.readFileSync(hooksParamsFile, 'ascii').trim().trim('"');
+            expect(params).toMatch(project.replace(/\\/g, '\\\\'));
+
+            var env = JSON.parse(fs.readFileSync(hooksEnvFile, 'ascii'));
+            expect(env.CORDOVA_VERSION).toEqual(require('../package').version);
+        })
+        .fail(function(err) {
+            console.log(err);
+            expect('Test hook call').toBe('successful');
+        })
+        .fin(done);
+
+    });
+
+    // Cleanup. Must be the last spec. Is there a better place for final cleanup in Jasmine?
+    it('should not fail during cleanup', function() {
+        process.chdir(path.join(__dirname, '..'));  // Non e2e tests assume CWD is repo root.
+        if(ext == 'sh') {
+            //shell.rm('-rf', tmpDir);
+        } else { // Windows:
+            // For some mysterious reason, both shell.rm and RMDIR /S /Q won't
+            // delete the dir on Windows, but they do remove the files leaving
+            // only folders. But the dir is removed just fine by
+            // shell.rm('-rf', tmpDir) at the top of this file with the next
+            // invocation of this test. The benefit of RMDIR /S /Q is that it
+            // doesn't print warnings like shell.rmdir() that look like this:
+            // rm: could not remove directory (code ENOTEMPTY): C:\Users\...
+            var cmd =  'RMDIR /S /Q ' + tmpDir;
+            child_process.exec(cmd);
+        }
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/lazy_load.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/lazy_load.spec.js b/cordova-lib/spec-cordova/lazy_load.spec.js
new file mode 100644
index 0000000..1a92ee9
--- /dev/null
+++ b/cordova-lib/spec-cordova/lazy_load.spec.js
@@ -0,0 +1,200 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var lazy_load = require('../src/lazy_load'),
+    config = require('../src/config'),
+    util = require('../src/util'),
+    shell = require('shelljs'),
+    npmconf = require('npmconf');
+    path = require('path'),
+    hooker = require('../src/hooker'),
+    request = require('request'),
+    fs = require('fs'),
+    Q = require('q'),
+    platforms = require('../platforms');
+
+describe('lazy_load module', function() {
+    var custom_path;
+    beforeEach(function() {
+        custom_path = spyOn(config, 'has_custom_path').andReturn(false);
+    });
+    describe('cordova method (loads stock cordova libs)', function() {
+        var custom;
+        beforeEach(function() {
+            custom = spyOn(lazy_load, 'custom').andReturn(Q(path.join('lib','dir')));
+        });
+        it('should throw if platform is not a stock cordova platform', function(done) {
+            lazy_load.cordova('atari').then(function() {
+                expect('this call').toEqual('to fail');
+            }, function(err) {
+                expect('' + err).toContain('Cordova library "atari" not recognized.');
+            }).fin(done);
+        });
+        it('should invoke lazy_load.custom with appropriate url, platform, and version as specified in platforms manifest', function(done) {
+            lazy_load.cordova('android').then(function(dir) {
+                expect(custom).toHaveBeenCalledWith(platforms.android.url + ';a=snapshot;h=' + platforms.android.version + ';sf=tgz', 'cordova', 'android', platforms.android.version);
+                expect(dir).toBeDefined();
+                done();
+            });
+        });
+    });
+
+    describe('custom method (loads custom cordova libs)', function() {
+        var exists, fire, rm;
+        beforeEach(function() {
+            spyOn(shell, 'mkdir');
+            rm = spyOn(shell, 'rm');
+            mv = spyOn(shell, 'mv');
+            exists = spyOn(fs, 'existsSync').andReturn(false);
+            readdir = spyOn(fs, 'readdirSync').andReturn(['somefile.txt']);
+            fire = spyOn(hooker, 'fire').andReturn(Q());
+        });
+
+        it('should callback with no errors and not fire event hooks if library already exists', function(done) {
+            exists.andReturn(true);
+            lazy_load.custom('http://some remote url', 'some id', 'platform X', 'three point five').then(function() {
+                expect(fire).not.toHaveBeenCalled()
+            }, function(err) {
+                expect(err).not.toBeDefined();
+            }).fin(done);
+        });
+        it('should callback with no errors and fire event hooks even if library already exists if the lib url is a local dir', function(done) {
+            exists.andReturn(true);
+            lazy_load.custom('some local dir', 'some id', 'platform X', 'three point six').then(function() {
+                expect(fire).not.toHaveBeenCalled()
+            }, function(err) {
+                expect(err).not.toBeDefined();
+            }).fin(done);
+        });
+
+        describe('remote URLs for libraries', function() {
+            var npmConfProxy;
+            var req,
+                load_spy,
+                events = {},
+                fakeRequest = {
+                    on: jasmine.createSpy().andCallFake(function(event, cb) {
+                        events[event] = cb;
+                        return fakeRequest;
+                    }),
+                    pipe: jasmine.createSpy().andCallFake(function() { return fakeRequest; })
+                };
+            beforeEach(function() {
+                npmConfProxy = null;
+                events = {};
+                fakeRequest.on.reset();
+                fakeRequest.pipe.reset();
+                req = spyOn(request, 'get').andCallFake(function() {
+                    // Fire the 'end' event shortly.
+                    setTimeout(function() {
+                        events['end']();
+                    }, 10);
+                    return fakeRequest;
+                });
+                load_spy = spyOn(npmconf, 'load').andCallFake(function(cb) { cb(null, { get: function() { return npmConfProxy }}); });
+            });
+
+            it('should call request with appopriate url params', function(done) {
+                var url = 'https://github.com/apache/someplugin';
+                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
+                    expect(req).toHaveBeenCalledWith({
+                        uri:url
+                    }, jasmine.any(Function));
+                }, function(err) {
+                    expect(err).not.toBeDefined();
+                }).fin(done);
+            });
+            it('should take into account https-proxy npm configuration var if exists for https:// calls', function(done) {
+                var proxy = 'https://somelocalproxy.com';
+                npmConfProxy = proxy;
+                var url = 'https://github.com/apache/someplugin';
+                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
+                    expect(req).toHaveBeenCalledWith({
+                        uri:url,
+                        proxy:proxy
+                    }, jasmine.any(Function));
+                }, function(err) {
+                    expect(err).not.toBeDefined();
+                }).fin(done);
+            });
+            it('should take into account proxy npm config var if exists for http:// calls', function(done) {
+                var proxy = 'http://somelocalproxy.com';
+                npmConfProxy = proxy;
+                var url = 'http://github.com/apache/someplugin';
+                lazy_load.custom(url, 'random', 'android', '1.0').then(function() {
+                    expect(req).toHaveBeenCalledWith({
+                        uri:url,
+                        proxy:proxy
+                    }, jasmine.any(Function));
+                }, function(err) {
+                    expect(err).not.toBeDefined();
+                }).fin(done);
+            });
+        });
+
+        describe('local paths for libraries', function() {
+            it('should return the local path, no symlink', function(done) {
+                lazy_load.custom('/some/random/lib', 'id', 'X', 'three point eight').then(function(dir) {
+                    expect(dir).toEqual('/some/random/lib');
+                }, function(err) {
+                    expect(err).toBeUndefined();
+                }).fin(done);
+            });
+            it('should not file download hook', function(done) {
+                lazy_load.custom('/some/random/lib', 'id', 'X', 'three point nine').then(function() {
+                    expect(fire).not.toHaveBeenCalledWith('after_library_download', {platform:'X',url:'/some/random/lib',id:'id',version:'three point nine',path:'/some/random/lib', symlink:false});
+                }, function(err) {
+                    expect(err).toBeUndefined();
+                }).fin(done);
+            });
+        });
+    });
+
+    describe('based_on_config method', function() {
+        var cordova, custom;
+        beforeEach(function() {
+            cordova = spyOn(lazy_load, 'cordova').andReturn(Q());
+            custom = spyOn(lazy_load, 'custom').andReturn(Q());
+        });
+        it('should invoke custom if a custom lib is specified', function(done) {
+            var read = spyOn(config, 'read').andReturn({
+                lib:{
+                    maybe:{
+                        uri:'you or eye?',
+                        id:'eye dee',
+                        version:'four point twenty'
+                    }
+                }
+            });
+            var p = '/some/random/custom/path';
+            custom_path.andReturn(p);
+            lazy_load.based_on_config('yup', 'maybe').then(function() {
+                expect(custom).toHaveBeenCalledWith('you or eye?', 'eye dee', 'maybe', 'four point twenty');
+            }, function(err) {
+                expect(err).toBeUndefined();
+            }).fin(done);
+        });
+        it('should invoke cordova if no custom lib is specified', function(done) {
+            lazy_load.based_on_config('yup', 'ios').then(function() {
+                expect(cordova).toHaveBeenCalledWith('ios');
+            }, function(err) {
+                expect(err).toBeUndefined();
+            }).fin(done);
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/metadata/android_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/android_parser.spec.js b/cordova-lib/spec-cordova/metadata/android_parser.spec.js
new file mode 100644
index 0000000..6c6ea41
--- /dev/null
+++ b/cordova-lib/spec-cordova/metadata/android_parser.spec.js
@@ -0,0 +1,211 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var platforms = require('../../platforms'),
+    util = require('../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    fs = require('fs'),
+    et = require('elementtree'),
+    xmlHelpers = require('../../src/xml-helpers'),
+    Q = require('q'),
+    config = require('../../src/config'),
+    ConfigParser = require('../../src/ConfigParser'),
+    cordova = require('../../cordova');
+
+// Create a real config object before mocking out everything.
+var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
+
+var STRINGS_XML = '<resources> <string name="app_name">mobilespec</string> </resources>';
+var MANIFEST_XML = '<manifest android:versionCode="1" android:versionName="0.0.1" package="org.apache.mobilespec">\n' +
+    '<application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">\n' +
+    '    <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="mobilespec" android:screenOrientation="VAL">\n' +
+    '        <intent-filter>\n' +
+    '            <action android:name="android.intent.action.MAIN" />\n' +
+    '            <category android:name="android.intent.category.LAUNCHER" />\n' +
+    '        </intent-filter>\n' +
+    '    </activity>\n' +
+    '</application>\n' +
+    '</manifest>\n';
+
+describe('android project parser', function() {
+    var proj = path.join('some', 'path');
+    var exists;
+    beforeEach(function() {
+        exists = spyOn(fs, 'existsSync').andReturn(true);
+        spyOn(config, 'has_custom_path').andReturn(false);
+    });
+
+    function wrapper(p, done, post) {
+        p.then(post, function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    }
+
+    function errorWrapper(p, done, post) {
+        p.then(function() {
+            expect('this call').toBe('fail');
+        }, post).fin(done);
+    }
+
+    describe('constructions', function() {
+        it('should throw if provided directory does not contain an AndroidManifest.xml', function() {
+            exists.andReturn(false);
+            expect(function() {
+                new platforms.android.parser(proj);
+            }).toThrow();
+        });
+        it('should create an instance with path, strings, manifest and android_config properties', function() {
+            expect(function() {
+                var p = new platforms.android.parser(proj);
+                expect(p.path).toEqual(proj);
+                expect(p.strings).toEqual(path.join(proj, 'res', 'values', 'strings.xml'));
+                expect(p.manifest).toEqual(path.join(proj, 'AndroidManifest.xml'));
+                expect(p.android_config).toEqual(path.join(proj, 'res', 'xml', 'config.xml'));
+            }).not.toThrow();
+        });
+    });
+
+    describe('instance', function() {
+        var p, cp, rm, mkdir, is_cordova, write, read;
+        var android_proj = path.join(proj, 'platforms', 'android');
+        var stringsRoot;
+        var manifestRoot;
+        beforeEach(function() {
+            stringsRoot = null;
+            manifestRoot = null;
+            p = new platforms.android.parser(android_proj);
+            cp = spyOn(shell, 'cp');
+            rm = spyOn(shell, 'rm');
+            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
+            write = spyOn(fs, 'writeFileSync');
+            read = spyOn(fs, 'readFileSync');
+            mkdir = spyOn(shell, 'mkdir');
+            spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
+                if (/strings/.exec(path)) {
+                    return stringsRoot = new et.ElementTree(et.XML(STRINGS_XML));
+                } else if (/AndroidManifest/.exec(path)) {
+                    return manifestRoot = new et.ElementTree(et.XML(MANIFEST_XML));
+                }
+            });
+        });
+
+        describe('update_from_config method', function() {
+            beforeEach(function() {
+                spyOn(fs, 'readdirSync').andReturn([path.join(proj, 'src', 'android_pkg', 'MyApp.java')]);
+                cfg.name = function() { return 'testname' };
+                cfg.packageName = function() { return 'testpkg' };
+                cfg.version = function() { return 'one point oh' };
+                read.andReturn('package org.cordova.somepackage; public class MyApp extends CordovaActivity { }');
+            });
+
+            it('should handle no orientation', function() {
+                cfg.getPreference = function() { return null; };
+                p.update_from_config(cfg);
+                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('VAL');
+            });
+            it('should handle default orientation', function() {
+                cfg.getPreference = function() { return 'default'; };
+                p.update_from_config(cfg);
+                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toBeUndefined();
+            });
+            it('should handle portrait orientation', function() {
+                cfg.getPreference = function() { return 'portrait'; };
+                p.update_from_config(cfg);
+                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('portrait');
+            });
+            it('should handle invalid orientation', function() {
+                cfg.getPreference = function() { return 'prtrait'; };
+                p.update_from_config(cfg);
+                expect(manifestRoot.getroot().find('./application/activity').attrib['android:screenOrientation']).toEqual('VAL');
+            });
+            it('should write out the app name to strings.xml', function() {
+                p.update_from_config(cfg);
+                expect(stringsRoot.getroot().find('string').text).toEqual('testname');
+            });
+            it('should write out the app id to androidmanifest.xml and update the cordova-android entry Java class', function() {
+                p.update_from_config(cfg);
+                expect(manifestRoot.getroot().attrib.package).toEqual('testpkg');
+            });
+            it('should write out the app version to androidmanifest.xml', function() {
+                p.update_from_config(cfg);
+                expect(manifestRoot.getroot().attrib['android:versionName']).toEqual('one point oh');
+            });
+        });
+        describe('www_dir method', function() {
+            it('should return assets/www', function() {
+                expect(p.www_dir()).toEqual(path.join(android_proj, 'assets', 'www'));
+            });
+        });
+        describe('config_xml method', function() {
+            it('should return the location of the config.xml', function() {
+                expect(p.config_xml()).toEqual(p.android_config);
+            });
+        });
+        describe('update_www method', function() {
+            it('should rm project-level www and cp in platform agnostic www', function() {
+                p.update_www();
+                expect(rm).toHaveBeenCalled();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_overrides method', function() {
+            it('should do nothing if merges directory does not exist', function() {
+                exists.andReturn(false);
+                p.update_overrides();
+                expect(cp).not.toHaveBeenCalled();
+            });
+            it('should copy merges path into www', function() {
+                p.update_overrides();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_project method', function() {
+            var config, www, overrides, svn;
+            beforeEach(function() {
+                config = spyOn(p, 'update_from_config');
+                www = spyOn(p, 'update_www');
+                overrides = spyOn(p, 'update_overrides');
+                svn = spyOn(util, 'deleteSvnFolders');
+            });
+            it('should call update_from_config', function() {
+                p.update_project();
+                expect(config).toHaveBeenCalled();
+            });
+            it('should throw if update_from_config throws', function(done) {
+                var err = new Error('uh oh!');
+                config.andCallFake(function() { throw err; });
+                errorWrapper(p.update_project({}), done, function(err) {
+                    expect(err).toEqual(err);
+                });
+            });
+            it('should not call update_www', function() {
+                p.update_project();
+                expect(www).not.toHaveBeenCalled();
+            });
+            it('should call update_overrides', function() {
+                p.update_project();
+                expect(overrides).toHaveBeenCalled();
+            });
+            it('should call deleteSvnFolders', function() {
+                p.update_project();
+                expect(svn).toHaveBeenCalled();
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js b/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js
new file mode 100644
index 0000000..b1d0b47
--- /dev/null
+++ b/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js
@@ -0,0 +1,225 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var platforms = require('../../platforms'),
+    util = require('../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    fs = require('fs'),
+    et = require('elementtree'),
+    xmlHelpers = require('../../src/xml-helpers'),
+    Q = require('q'),
+    child_process = require('child_process'),
+    config = require('../../src/config'),
+    ConfigParser = require('../../src/ConfigParser'),
+    cordova = require('../../cordova');
+
+var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
+
+var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
+    '<widget xmlns     = "http://www.w3.org/ns/widgets"\n' +
+    '        xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
+    '        id        = "io.cordova.hellocordova"\n' +
+    '        version   = "0.0.1">\n' +
+    '    <name>Hello Cordova</name>\n' +
+    '    <description>\n' +
+    '        A sample Apache Cordova application that responds to the deviceready event.\n' +
+    '    </description>\n' +
+    '    <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
+    '        Apache Cordova Team\n' +
+    '    </author>\n' +
+    '    <content src="index.html" />\n' +
+    '    <access origin="*" />\n' +
+    '    <preference name="fullscreen" value="true" />\n' +
+    '    <preference name="webviewbounce" value="true" />\n' +
+    '</widget>\n';
+
+describe('blackberry10 project parser', function() {
+    var proj = '/some/path';
+    var exists, custom, sh;
+    beforeEach(function() {
+        exists = spyOn(fs, 'existsSync').andReturn(true);
+        custom = spyOn(config, 'has_custom_path').andReturn(false);
+        sh = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
+            (cb || opts)(0, '', '');
+        });
+        spyOn(ConfigParser.prototype, 'write');
+        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function() {
+            return new et.ElementTree(et.XML(TEST_XML));
+        });
+    });
+
+    function wrapper(p, done, post) {
+        p.then(post, function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    }
+
+    function errorWrapper(p, done, post) {
+        p.then(function() {
+            expect('this call').toBe('fail');
+        }, post).fin(done);
+    }
+
+    describe('constructions', function() {
+        it('should throw an exception with a path that is not a native blackberry project', function() {
+            exists.andReturn(false);
+            expect(function() {
+                new platforms.blackberry10.parser(proj);
+            }).toThrow();
+        });
+        it('should accept a proper native blackberry project path as construction parameter', function() {
+            var project;
+            expect(function() {
+                project = new platforms.blackberry10.parser(proj);
+            }).not.toThrow();
+            expect(project).toBeDefined();
+        });
+    });
+
+    describe('check_requirements', function() {
+        it('should fire a callback if the blackberry-deploy shell-out fails', function(done) {
+            sh.andCallFake(function(cmd, opts, cb) {
+                (cb || opts)(1, 'no bb-deploy dewd!');
+            });
+            errorWrapper(platforms.blackberry10.parser.check_requirements(proj), done, function(err) {
+                expect(err).toContain('no bb-deploy dewd');
+            });
+        });
+        it('should fire a callback with no error if shell out is successful', function(done) {
+            wrapper(platforms.blackberry10.parser.check_requirements(proj), done, function() {
+                expect(1).toBe(1);
+            });
+        });
+    });
+    describe('instance', function() {
+        var p, cp, rm, mkdir, is_cordova, write, read;
+        var bb_proj = path.join(proj, 'platforms', 'blackberry10');
+        beforeEach(function() {
+            p = new platforms.blackberry10.parser(bb_proj);
+            cp = spyOn(shell, 'cp');
+            rm = spyOn(shell, 'rm');
+            mkdir = spyOn(shell, 'mkdir');
+            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
+            write = spyOn(fs, 'writeFileSync');
+            read = spyOn(fs, 'readFileSync');
+        });
+
+        describe('update_from_config method', function() {
+            var xml_name, xml_pkg, xml_version, xml_access_rm, xml_update, xml_append, xml_content;
+            beforeEach(function() {
+                xml_content = jasmine.createSpy('xml content');
+                xml_name = jasmine.createSpy('xml name');
+                xml_pkg = jasmine.createSpy('xml pkg');
+                xml_version = jasmine.createSpy('xml version');
+                xml_access_rm = jasmine.createSpy('xml access rm');
+                xml_access_add = jasmine.createSpy('xml access add');
+                xml_update = jasmine.createSpy('xml update');
+                xml_append = jasmine.createSpy('xml append');
+                xml_preference_remove = jasmine.createSpy('xml preference rm');
+                xml_preference_add = jasmine.createSpy('xml preference add');
+                p.xml.name = xml_name;
+                p.xml.packageName = xml_pkg;
+                p.xml.version = xml_version;
+                p.xml.content = xml_content;
+                p.xml.access = {
+                    remove:xml_access_rm,
+                    add: xml_access_add
+                };
+                p.xml.update = xml_update;
+                p.xml.doc = {
+                    getroot:function() { return { append:xml_append}; }
+                };
+                p.xml.preference = {
+                    add: xml_preference_add,
+                    remove: xml_preference_remove
+                };
+                cfg.name = function() { return 'testname'; };
+                cfg.packageName = function() { return 'testpkg'; };
+                cfg.version = function() { return 'one point oh'; };
+            });
+        });
+        describe('www_dir method', function() {
+            it('should return /www', function() {
+                expect(p.www_dir()).toEqual(path.join(bb_proj, 'www'));
+            });
+        });
+        describe('config_xml method', function() {
+            it('should return the location of the config.xml', function() {
+                expect(p.config_xml()).toEqual(path.join(proj, 'platforms', 'blackberry10', 'www', 'config.xml'));
+            });
+        });
+        describe('update_www method', function() {
+
+            it('should rm project-level www and cp in platform agnostic www', function() {
+                p.update_www();
+                expect(rm).toHaveBeenCalled();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_overrides method', function() {
+            it('should do nothing if merges directory does not exist', function() {
+                exists.andReturn(false);
+                p.update_overrides();
+                expect(cp).not.toHaveBeenCalled();
+            });
+            it('should copy merges path into www', function() {
+                p.update_overrides();
+                expect(cp).toHaveBeenCalledWith('-rf', path.join(proj, 'merges', 'blackberry10', '*'), path.join(proj, 'platforms', 'blackberry10', 'www'));
+            });
+        });
+        describe('update_project method', function() {
+            var config, www, overrides, svn, parse, get_env, write_env;
+            beforeEach(function() {
+                config = spyOn(p, 'update_from_config');
+                www = spyOn(p, 'update_www');
+                overrides = spyOn(p, 'update_overrides');
+                svn = spyOn(util, 'deleteSvnFolders');
+                parse = spyOn(JSON, 'parse').andReturn({blackberry:{qnx:{}}});
+            });
+            it('should call update_from_config', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(config).toHaveBeenCalled();
+                });
+            });
+            it('should throw if update_from_config throws', function(done) {
+                var err = new Error('uh oh!');
+                config.andCallFake(function() { throw err; });
+                errorWrapper(p.update_project({}), done, function(e) {
+                    expect(e).toEqual(err);
+                });
+            });
+            it('should not call update_www', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(www).not.toHaveBeenCalled();
+                });
+            });
+            it('should call update_overrides', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(overrides).toHaveBeenCalled();
+                });
+            });
+            it('should call deleteSvnFolders', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(svn).toHaveBeenCalled();
+                });
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js b/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js
new file mode 100644
index 0000000..49694eb
--- /dev/null
+++ b/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js
@@ -0,0 +1,74 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+var platforms = require('../../platforms'),
+    util = require('../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    fs = require('fs'),
+    config = require('../../src/config'),
+    ConfigParser = require('../../src/ConfigParser'),
+    cordova = require('../../cordova');
+
+var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
+describe('firefoxos project parser', function() {
+    var proj = path.join('some', 'path');
+    var exists, exec, custom;
+    beforeEach(function() {
+        exists = spyOn(fs, 'existsSync').andReturn(true);
+        exec = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
+            cb(0, '');
+        });
+        custom = spyOn(config, 'has_custom_path').andReturn(false);
+    });
+
+    describe('constructions', function() {
+        it('should create an instance with a path', function() {
+            expect(function() {
+                var p = new platforms.android.parser(proj);
+                expect(p.path).toEqual(proj);
+            }).not.toThrow();
+        });
+    });
+
+    describe('instance', function() {
+        var p, cp, rm, is_cordova, write, read;
+        var ff_proj = path.join(proj, 'platforms', 'firefoxos');
+        beforeEach(function() {
+            p = new platforms.firefoxos.parser(ff_proj);
+            cp = spyOn(shell, 'cp');
+            rm = spyOn(shell, 'rm');
+            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
+            write = spyOn(fs, 'writeFileSync');
+            read = spyOn(fs, 'readFileSync').andReturn('');
+        });
+
+        describe('update_from_config method', function() {
+            beforeEach(function() {
+                cfg.name = function() { return 'testname'; };
+                cfg.packageName = function() { return 'testpkg'; };
+                cfg.version = function() { return '1.0'; };
+            });
+
+          /*  it('should write manifest.webapp', function() {
+                //p.update_from_config(cfg);
+                //expect(write.mostRecentCall.args[0]).toEqual('manifest.webapp');
+            });*/
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/ios_parser.spec.js b/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
new file mode 100644
index 0000000..5b2977e
--- /dev/null
+++ b/cordova-lib/spec-cordova/metadata/ios_parser.spec.js
@@ -0,0 +1,199 @@
+/**
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+var platforms = require('../../platforms'),
+    util = require('../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    plist = require('plist-with-patches'),
+    xcode = require('xcode'),
+    et = require('elementtree'),
+    fs = require('fs'),
+    Q = require('q'),
+    config = require('../../src/config'),
+    ConfigParser = require('../../src/ConfigParser'),
+    cordova = require('../../cordova');
+
+// Create a real config object before mocking out everything.
+var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
+
+describe('ios project parser', function () {
+    var proj = path.join('some', 'path');
+    var custom, readdir;
+    beforeEach(function() {
+        custom = spyOn(config, 'has_custom_path').andReturn(false);
+        readdir = spyOn(fs, 'readdirSync').andReturn(['test.xcodeproj']);
+    });
+
+    function wrapper(p, done, post) {
+        p.then(post, function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    }
+
+    function errorWrapper(p, done, post) {
+        p.then(function() {
+            expect('this call').toBe('fail');
+        }, post).fin(done);
+    }
+
+    describe('constructions', function() {
+        it('should throw if provided directory does not contain an xcodeproj file', function() {
+            readdir.andReturn(['noxcodehere']);
+            expect(function() {
+                new platforms.ios.parser(proj);
+            }).toThrow();
+        });
+        it('should create an instance with path, pbxproj, xcodeproj, originalName and cordovaproj properties', function() {
+            expect(function() {
+                var p = new platforms.ios.parser(proj);
+                expect(p.path).toEqual(proj);
+                expect(p.pbxproj).toEqual(path.join(proj, 'test.xcodeproj', 'project.pbxproj'));
+                expect(p.xcodeproj).toEqual(path.join(proj, 'test.xcodeproj'));
+            }).not.toThrow();
+        });
+    });
+
+    describe('instance', function() {
+        var p, cp, rm, mkdir, is_cordova, write, read;
+        var ios_proj = path.join(proj, 'platforms', 'ios');
+        beforeEach(function() {
+            p = new platforms.ios.parser(ios_proj);
+            cp = spyOn(shell, 'cp');
+            rm = spyOn(shell, 'rm');
+            mkdir = spyOn(shell, 'mkdir');
+            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
+            write = spyOn(fs, 'writeFileSync');
+            read = spyOn(fs, 'readFileSync').andReturn('');
+        });
+
+        describe('update_from_config method', function() {
+            var mv;
+            var cfg_access_add, cfg_access_rm, cfg_pref_add, cfg_pref_rm, cfg_content;
+            var plist_parse, plist_build, xc;
+            var update_name, xc_write;
+            beforeEach(function() {
+                mv = spyOn(shell, 'mv');
+                plist_parse = spyOn(plist, 'parseFileSync').andReturn({
+                });
+                plist_build = spyOn(plist, 'build').andReturn('');
+                update_name = jasmine.createSpy('update_name');
+                xc_write = jasmine.createSpy('xcode writeSync');
+                xc = spyOn(xcode, 'project').andReturn({
+                    parse:function(cb) {cb();},
+                    updateProductName:update_name,
+                    writeSync:xc_write
+                });
+                cfg.name = function() { return 'testname' };
+                cfg.packageName = function() { return 'testpkg' };
+                cfg.version = function() { return 'one point oh' };
+                p = new platforms.ios.parser(ios_proj);
+            });
+
+            it('should update the app name in pbxproj by calling xcode.updateProductName, and move the ios native files to match the new name', function(done) {
+                var test_path = path.join(proj, 'platforms', 'ios', 'test');
+                var testname_path = path.join(proj, 'platforms', 'ios', 'testname');
+                wrapper(p.update_from_config(cfg), done, function() {
+                    expect(update_name).toHaveBeenCalledWith('testname');
+                    expect(mv).toHaveBeenCalledWith(path.join(test_path, 'test-Info.plist'), path.join(test_path, 'testname-Info.plist'));
+                    expect(mv).toHaveBeenCalledWith(path.join(test_path, 'test-Prefix.pch'), path.join(test_path, 'testname-Prefix.pch'));
+                    expect(mv).toHaveBeenCalledWith(test_path + '.xcodeproj', testname_path + '.xcodeproj');
+                    expect(mv).toHaveBeenCalledWith(test_path, testname_path);
+                });
+            });
+            it('should write out the app id to info plist as CFBundleIdentifier', function(done) {
+                wrapper(p.update_from_config(cfg), done, function() {
+                    expect(plist_build.mostRecentCall.args[0].CFBundleIdentifier).toEqual('testpkg');
+                });
+            });
+            it('should write out the app version to info plist as CFBundleVersion', function(done) {
+                wrapper(p.update_from_config(cfg), done, function() {
+                    expect(plist_build.mostRecentCall.args[0].CFBundleShortVersionString).toEqual('one point oh');
+                });
+            });
+        });
+        describe('www_dir method', function() {
+            it('should return /www', function() {
+                expect(p.www_dir()).toEqual(path.join(ios_proj, 'www'));
+            });
+        });
+        describe('config_xml method', function() {
+            it('should return the location of the config.xml', function() {
+                expect(p.config_xml()).toEqual(path.join(ios_proj, 'test', 'config.xml'));
+            });
+        });
+        describe('update_www method', function() {
+            it('should rm project-level www and cp in platform agnostic www', function() {
+                p.update_www(path.join('lib','dir'));
+                expect(rm).toHaveBeenCalled();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_overrides method', function() {
+            var exists;
+            beforeEach(function() {
+                exists = spyOn(fs, 'existsSync').andReturn(true);
+            });
+            it('should do nothing if merges directory does not exist', function() {
+                exists.andReturn(false);
+                p.update_overrides();
+                expect(cp).not.toHaveBeenCalled();
+            });
+            it('should copy merges path into www', function() {
+                p.update_overrides();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_project method', function() {
+            var config, www, overrides, svn;
+            beforeEach(function() {
+                config = spyOn(p, 'update_from_config').andReturn(Q());
+                www = spyOn(p, 'update_www');
+                overrides = spyOn(p, 'update_overrides');
+                svn = spyOn(util, 'deleteSvnFolders');
+            });
+            it('should call update_from_config', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(config).toHaveBeenCalled();
+                });
+            });
+            it('should throw if update_from_config errors', function(done) {
+                var e = new Error('uh oh!');
+                config.andReturn(Q.reject(e));
+                errorWrapper(p.update_project({}), done, function(err) {
+                    expect(err).toEqual(e);
+                });
+            });
+            it('should not call update_www', function(done) {
+                wrapper(p.update_project({}), done, function() {
+                    expect(www).not().toHaveBeenCalled();
+                });
+            });
+            it('should call update_overrides', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(overrides).toHaveBeenCalled();
+                });
+            });
+            it('should call deleteSvnFolders', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(svn).toHaveBeenCalled();
+                });
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js b/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
new file mode 100644
index 0000000..726391f
--- /dev/null
+++ b/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js
@@ -0,0 +1,189 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var platforms = require('../../platforms'),
+    util = require('../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    child_process = require('child_process'),
+    xmlHelpers = require('../../src/xml-helpers'),
+    et = require('elementtree'),
+    Q = require('q'),
+    fs = require('fs'),
+    config = require('../../src/config'),
+    ConfigParser = require('../../src/ConfigParser'),
+    cordova = require('../../cordova');
+
+// Create a real config object before mocking out everything.
+var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
+
+describe('windows8 project parser', function() {
+
+    var proj = '/some/path';
+    var exists, exec, custom, readdir, cfg_parser;
+    var winXml;
+    beforeEach(function() {
+        exists = spyOn(fs, 'existsSync').andReturn(true);
+        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
+            if (!cb) cb = opts;
+            cb(null, '', '');
+        });
+        custom = spyOn(config, 'has_custom_path').andReturn(false);
+        readdir = spyOn(fs, 'readdirSync').andReturn(['test.jsproj']);
+        winXml = null;
+        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
+            return winXml = new et.ElementTree(et.XML('<foo><Application/><Identity/><VisualElements><a/></VisualElements><Capabilities><a/></Capabilities></foo>'));
+        });
+    });
+
+    function wrapper(promise, done, post) {
+        promise.then(post, function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    }
+
+    function errorWrapper(promise, done, post) {
+        promise.then(function() {
+            expect('this call').toBe('fail');
+        }, post).fin(done);
+    }
+
+    describe('constructions', function() {
+        it('should throw if provided directory does not contain a jsproj file', function() {
+            readdir.andReturn([]);
+            expect(function() {
+                new platforms.windows8.parser(proj);
+            }).toThrow();
+        });
+        it('should create an instance with path, manifest properties', function() {
+            expect(function() {
+                var parser = new platforms.windows8.parser(proj);
+                expect(parser.windows8_proj_dir).toEqual(proj);
+                expect(parser.manifest_path).toEqual(path.join(proj, 'package.appxmanifest'));
+            }).not.toThrow();
+        });
+    });
+
+    describe('check_requirements', function() {
+        it('should fire a callback if there is an error during shelling out', function(done) {
+            exec.andCallFake(function(cmd, opts, cb) {
+                if (!cb) cb = opts;
+                cb(50, 'there was an errorz!', '');
+            });
+            errorWrapper(platforms.windows8.parser.check_requirements(proj), done, function(err) {
+                expect(err).toContain('there was an errorz!');
+            });
+        });
+        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
+            wrapper(platforms.windows8.parser.check_requirements(proj), done, function() {
+                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
+                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
+            });
+        });
+        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
+            var custom_path = path.join('some','custom','path','to','windows8','lib');
+            custom.andReturn(custom_path);
+            wrapper(platforms.windows8.parser.check_requirements(proj),done, function() {
+                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
+                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
+            });
+            done();
+        });
+    });
+
+    describe('instance', function() {
+        var parser, cp, rm, is_cordova, write, read, mv, mkdir;
+        var windows8_proj = path.join(proj, 'platforms', 'windows8');
+        beforeEach(function() {
+            parser = new platforms.windows8.parser(windows8_proj);
+            cp = spyOn(shell, 'cp');
+            rm = spyOn(shell, 'rm');
+            mv = spyOn(shell, 'mv');
+            mkdir = spyOn(shell, 'mkdir');
+            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
+            write = spyOn(fs, 'writeFileSync');
+            read = spyOn(fs, 'readFileSync').andReturn('');
+        });
+
+        describe('update_from_config method', function() {
+            beforeEach(function() {
+                cfg.name = function() { return 'testname' };
+                cfg.content = function() { return 'index.html' };
+                cfg.packageName = function() { return 'testpkg' };
+                cfg.version = function() { return 'one point oh' };
+                readdir.andReturn(['test.sln']);
+            });
+
+            it('should write out the app name to package.appxmanifest', function() {
+                parser.update_from_config(cfg);
+                var identityNode = winXml.getroot().find('.//Identity');
+                expect(identityNode.attrib.Name).toEqual(cfg.packageName());
+            });
+
+            it('should write out the app version to package.appxmanifest', function() {
+                parser.update_from_config(cfg);
+                var identityNode = winXml.getroot().find('.//Identity');
+                expect(identityNode.attrib.Version).toEqual('one point oh');
+            });
+        });
+
+        describe('www_dir method', function() {
+            it('should return www', function() {
+                expect(parser.www_dir()).toEqual(path.join(windows8_proj, 'www'));
+            });
+        });
+        describe('update_www method', function() {
+            var update_jsproj;
+            beforeEach(function() {
+                update_jsproj = spyOn(parser, 'update_jsproj');
+            });
+            it('should rm project-level www and cp in platform agnostic www', function() {
+                parser.update_www(path.join('lib','dir'));
+                expect(rm).toHaveBeenCalled();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_project method', function() {
+            var config, www, overrides, svn;
+            beforeEach(function() {
+                config = spyOn(parser, 'update_from_config');
+                www = spyOn(parser, 'update_www');
+                www = spyOn(parser, 'update_jsproj');
+                svn = spyOn(util, 'deleteSvnFolders');
+                exists.andReturn(false);
+            });
+            it('should call update_from_config', function() {
+                parser.update_project();
+                expect(config).toHaveBeenCalled();
+            });
+            it('should throw if update_from_config throws', function(done) {
+                var err = new Error('uh oh!');
+                config.andCallFake(function() { throw err; });
+                errorWrapper(parser.update_project({}), done, function(err) {
+                    expect(err).toEqual(err);
+                });
+            });
+            it('should call deleteSvnFolders', function(done) {
+                wrapper(parser.update_project(), done, function() {
+                    expect(svn).toHaveBeenCalled();
+                });
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js b/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js
new file mode 100644
index 0000000..0856391
--- /dev/null
+++ b/cordova-lib/spec-cordova/metadata/wp7_parser.spec.js
@@ -0,0 +1,208 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var platforms = require('../../platforms'),
+    util = require('../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    fs = require('fs'),
+    et = require('elementtree'),
+    xmlHelpers = require('../../src/xml-helpers'),
+    Q = require('q'),
+    child_process = require('child_process'),
+    config = require('../../src/config'),
+    ConfigParser = require('../../src/ConfigParser'),
+    CordovaError = require('../../src/CordovaError'),
+    cordova = require('../../cordova');
+
+// Create a real config object before mocking out everything.
+var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
+
+describe('wp7 project parser', function() {
+    var proj = '/some/path';
+    var exists, exec, custom, readdir, cfg_parser;
+    var projXml, manifestXml;
+    beforeEach(function() {
+        exists = spyOn(fs, 'existsSync').andReturn(true);
+        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
+            (cb || opts)(0, '', '');
+        });
+        custom = spyOn(config, 'has_custom_path').andReturn(false);
+        readdir = spyOn(fs, 'readdirSync').andReturn(['test.csproj']);
+        projXml = manifestXml = null;
+        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
+            if (/WMAppManifest.xml$/.exec(path)) {
+                return manifestXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
+            } else if (/csproj$/.exec(path)) {
+                return projXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
+            } else if (/xaml$/.exec(path)) {
+                return new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
+            } else {
+                throw new CordovaError('Unexpected parseElementtreeSync: ' + path);
+            }
+        });
+    });
+
+    function wrapper(p, done, post) {
+        p.then(post, function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    }
+
+    function errorWrapper(p, done, post) {
+        p.then(function() {
+            expect('this call').toBe('fail');
+        }, post).fin(done);
+    }
+
+    describe('constructions', function() {
+        it('should throw if provided directory does not contain a csproj file', function() {
+            readdir.andReturn([]);
+            expect(function() {
+                new platforms.wp7.parser(proj);
+            }).toThrow();
+        });
+        it('should create an instance with path, manifest properties', function() {
+            expect(function() {
+                var p = new platforms.wp7.parser(proj);
+                expect(p.wp7_proj_dir).toEqual(proj);
+                expect(p.manifest_path).toEqual(path.join(proj, 'Properties', 'WMAppManifest.xml'));
+            }).not.toThrow();
+        });
+    });
+
+    describe('check_requirements', function() {
+        it('should fire a callback if there is an error during shelling out', function(done) {
+            exec.andCallFake(function(cmd, opts, cb) {
+                (cb || opts)(50, 'there was an errorz!');
+            });
+            errorWrapper(platforms.wp7.parser.check_requirements(proj), done, function(err) {
+                expect(err).toContain('there was an errorz!');
+            });
+        });
+        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
+            wrapper(platforms.wp7.parser.check_requirements(proj), done, function(err) {
+                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
+                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
+            });
+        });
+        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
+            var custom_path = path.join('some','custom','path','to','wp7','lib');
+            custom.andReturn(custom_path);
+            wrapper(platforms.wp7.parser.check_requirements(proj), done, function() {
+                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
+                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
+            });
+        });
+    });
+
+    describe('instance', function() {
+        var p, cp, rm, is_cordova, write, read, mv, mkdir;
+        var wp7_proj = path.join(proj, 'platforms', 'wp7');
+        beforeEach(function() {
+            p = new platforms.wp7.parser(wp7_proj);
+            cp = spyOn(shell, 'cp');
+            rm = spyOn(shell, 'rm');
+            mv = spyOn(shell, 'mv');
+            mkdir = spyOn(shell, 'mkdir');
+            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
+            write = spyOn(fs, 'writeFileSync');
+            read = spyOn(fs, 'readFileSync').andReturn('');
+        });
+
+        describe('update_from_config method', function() {
+            beforeEach(function() {
+                cfg.name = function() { return 'testname' };
+                cfg.content = function() { return 'index.html' };
+                cfg.packageName = function() { return 'testpkg' };
+                cfg.version = function() { return 'one point oh' };
+                readdir.andReturn(['test.sln']);
+            });
+
+            it('should write out the app name to wmappmanifest.xml', function() {
+                p.update_from_config(cfg);
+                var appEl = manifestXml.getroot().find('.//App');
+                expect(appEl.attrib.Title).toEqual('testname');
+            });
+            it('should write out the app id to csproj file', function() {
+                p.update_from_config(cfg);
+                var appEl = projXml.getroot().find('.//RootNamespace');
+                expect(appEl.text).toContain('testpkg');
+            });
+            it('should write out the app version to wmappmanifest.xml', function() {
+                p.update_from_config(cfg);
+                var appEl = manifestXml.getroot().find('.//App');
+                expect(appEl.attrib.Version).toEqual('one point oh');
+            });
+        });
+        describe('www_dir method', function() {
+            it('should return www', function() {
+                expect(p.www_dir()).toEqual(path.join(wp7_proj, 'www'));
+            });
+        });
+        describe('config_xml method', function() {
+            it('should return the location of the config.xml', function() {
+                expect(p.config_xml()).toEqual(path.join(wp7_proj, 'config.xml'));
+            });
+        });
+        describe('update_www method', function() {
+            var update_csproj;
+            beforeEach(function() {
+                update_csproj = spyOn(p, 'update_csproj');
+            });
+            it('should rm project-level www and cp in platform agnostic www', function() {
+                p.update_www();
+                expect(rm).toHaveBeenCalled();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_project method', function() {
+            var config, www, overrides, svn, cfg, csproj;
+            beforeEach(function() {
+                config = spyOn(p, 'update_from_config');
+                www = spyOn(p, 'update_www');
+                svn = spyOn(util, 'deleteSvnFolders');
+                csproj = spyOn(p, 'update_csproj');
+                exists.andReturn(false);
+            });
+            it('should call update_from_config', function(done) {
+                wrapper(p.update_project(), done, function(){
+                    expect(config).toHaveBeenCalled();
+                });
+            });
+            it('should throw if update_from_config throws', function(done) {
+                var err = new Error('uh oh!');
+                config.andCallFake(function() { throw err; });
+                errorWrapper(p.update_project({}), done, function(e) {
+                    expect(e).toEqual(err);
+                });
+            });
+            it('should call update_www', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(www).not.toHaveBeenCalled();
+                });
+            });
+            it('should call deleteSvnFolders', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(svn).toHaveBeenCalled();
+                });
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js b/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
new file mode 100644
index 0000000..5ea461e
--- /dev/null
+++ b/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js
@@ -0,0 +1,208 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var platforms = require('../../platforms'),
+    util = require('../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    fs = require('fs'),
+    et = require('elementtree'),
+    xmlHelpers = require('../../src/xml-helpers'),
+    Q = require('q'),
+    child_process = require('child_process'),
+    config = require('../../src/config'),
+    ConfigParser = require('../../src/ConfigParser'),
+    CordovaError = require('../../src/CordovaError'),
+    cordova = require('../../cordova');
+
+// Create a real config object before mocking out everything.
+var cfg = new ConfigParser(path.join(__dirname, '..', 'test-config.xml'));
+
+describe('wp8 project parser', function() {
+    var proj = '/some/path';
+    var exists, exec, custom, readdir, cfg_parser;
+    var manifestXml, projXml;
+    beforeEach(function() {
+        exists = spyOn(fs, 'existsSync').andReturn(true);
+        exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
+            (cb || opts)(0, '', '');
+        });
+        custom = spyOn(config, 'has_custom_path').andReturn(false);
+        readdir = spyOn(fs, 'readdirSync').andReturn(['test.csproj']);
+        projXml = manifestXml = null;
+        spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function(path) {
+            if (/WMAppManifest.xml$/.exec(path)) {
+                return manifestXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
+            } else if (/csproj$/.exec(path)) {
+                return projXml = new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
+            } else if (/xaml$/.exec(path)) {
+                return new et.ElementTree(et.XML('<foo><App Title="s"><PrimaryToken /><RootNamespace/><SilverlightAppEntry/><XapFilename/><AssemblyName/></App></foo>'));
+            } else {
+                throw new CordovaError('Unexpected parseElementtreeSync: ' + path);
+            }
+        });
+    });
+
+    function wrapper(p, done, post) {
+        p.then(post, function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    }
+
+    function errorWrapper(p, done, post) {
+        p.then(function() {
+            expect('this call').toBe('fail');
+        }, post).fin(done);
+    }
+
+    describe('constructions', function() {
+        it('should throw if provided directory does not contain a csproj file', function() {
+            readdir.andReturn([]);
+            expect(function() {
+                new platforms.wp8.parser(proj);
+            }).toThrow();
+        });
+        it('should create an instance with path, manifest properties', function() {
+            expect(function() {
+                var p = new platforms.wp8.parser(proj);
+                expect(p.wp8_proj_dir).toEqual(proj);
+                expect(p.manifest_path).toEqual(path.join(proj, 'Properties', 'WMAppManifest.xml'));
+            }).not.toThrow();
+        });
+    });
+
+    describe('check_requirements', function() {
+        it('should fire a callback if there is an error during shelling out', function(done) {
+            exec.andCallFake(function(cmd, opts, cb) {
+                (cb || opts)(50, 'there was an errorz!');
+            });
+            errorWrapper(platforms.wp8.parser.check_requirements(proj), done, function(err) {
+                expect(err).toContain('there was an errorz!');
+            });
+        });
+        it('should check by calling check_reqs on the stock lib path if no custom path is defined', function(done) {
+            wrapper(platforms.wp8.parser.check_requirements(proj), done, function() {
+                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
+                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
+            });
+        });
+        it('should check by calling check_reqs on a custom path if it is so defined', function(done) {
+            var custom_path = path.join('some','custom','path','to','wp8','lib');
+            custom.andReturn(custom_path);
+            wrapper(platforms.wp8.parser.check_requirements(proj), done, function(err) {
+                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
+                expect(exec.mostRecentCall.args[0]).toMatch(/check_reqs"$/);
+            });
+        });
+    });
+
+    describe('instance', function() {
+        var p, cp, rm, is_cordova, write, read, mv, mkdir;
+        var wp8_proj = path.join(proj, 'platforms', 'wp8');
+        beforeEach(function() {
+            p = new platforms.wp8.parser(wp8_proj);
+            cp = spyOn(shell, 'cp');
+            rm = spyOn(shell, 'rm');
+            mv = spyOn(shell, 'mv');
+            mkdir = spyOn(shell, 'mkdir');
+            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
+            write = spyOn(fs, 'writeFileSync');
+            read = spyOn(fs, 'readFileSync').andReturn('');
+        });
+
+        describe('update_from_config method', function() {
+            beforeEach(function() {
+                cfg.name = function() { return 'testname' };
+                cfg.content = function() { return 'index.html' };
+                cfg.packageName = function() { return 'testpkg' };
+                cfg.version = function() { return 'one point oh' };
+                readdir.andReturn(['test.sln']);
+            });
+
+            it('should write out the app name to wmappmanifest.xml', function() {
+                p.update_from_config(cfg);
+                var appEl = manifestXml.getroot().find('.//App');
+                expect(appEl.attrib.Title).toEqual('testname');
+            });
+            it('should write out the app id to csproj file', function() {
+                p.update_from_config(cfg);
+                var appEl = projXml.getroot().find('.//RootNamespace');
+                expect(appEl.text).toContain('testpkg');
+            });
+            it('should write out the app version to wmappmanifest.xml', function() {
+                p.update_from_config(cfg);
+                var appEl = manifestXml.getroot().find('.//App');
+                expect(appEl.attrib.Version).toEqual('one point oh');
+            });
+        });
+        describe('www_dir method', function() {
+            it('should return www', function() {
+                expect(p.www_dir()).toEqual(path.join(wp8_proj, 'www'));
+            });
+        });
+        describe('config_xml method', function() {
+            it('should return the location of the config.xml', function() {
+                expect(p.config_xml()).toEqual(path.join(wp8_proj, 'config.xml'));
+            });
+        });
+        describe('update_www method', function() {
+            var update_csproj;
+            beforeEach(function() {
+                update_csproj = spyOn(p, 'update_csproj');
+            });
+            it('should rm project-level www and cp in platform agnostic www', function() {
+                p.update_www();
+                expect(rm).toHaveBeenCalled();
+                expect(cp).toHaveBeenCalled();
+            });
+        });
+        describe('update_project method', function() {
+            var config, www, overrides, svn, csproj;
+            beforeEach(function() {
+                config = spyOn(p, 'update_from_config');
+                www = spyOn(p, 'update_www');
+                svn = spyOn(util, 'deleteSvnFolders');
+                csproj = spyOn(p, 'update_csproj');
+                exists.andReturn(false);
+            });
+            it('should call update_from_config', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(config).toHaveBeenCalled();
+                });
+            });
+            it('should throw if update_from_config throws', function(done) {
+                var err = new Error('uh oh!');
+                config.andCallFake(function() { throw err; });
+                errorWrapper(p.update_project({}), done, function(e) {
+                    expect(e).toEqual(err);
+                });
+            });
+            it('should not call update_www', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(www).not.toHaveBeenCalled();
+                });
+            });
+            it('should call deleteSvnFolders', function(done) {
+                wrapper(p.update_project(), done, function() {
+                    expect(svn).toHaveBeenCalled();
+                });
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/b51e1c12/cordova-lib/spec-cordova/platform.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/platform.spec.js b/cordova-lib/spec-cordova/platform.spec.js
new file mode 100644
index 0000000..e16d51d
--- /dev/null
+++ b/cordova-lib/spec-cordova/platform.spec.js
@@ -0,0 +1,108 @@
+
+var helpers = require('./helpers'),
+    path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    platforms = require('../platforms'),
+    superspawn = require('../src/superspawn'),
+    config = require('../src/config'),
+    Q = require('q'),
+    events = require('../src/events'),
+    cordova = require('../cordova');
+
+var tmpDir = helpers.tmpDir('platform_test');
+var project = path.join(tmpDir, 'project');
+
+var platformParser = platforms[helpers.testPlatform].parser;
+
+describe('platform end-to-end', function() {
+    var results;
+
+    beforeEach(function() {
+        shell.rm('-rf', tmpDir);
+    });
+    afterEach(function() {
+        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
+        shell.rm('-rf', tmpDir);
+    });
+
+    // Factoring out some repeated checks.
+    function emptyPlatformList() {
+        return cordova.raw.platform('list').then(function() {
+            var installed = results.match(/Installed platforms: (.*)/);
+            expect(installed).toBeDefined();
+            expect(installed[1].indexOf(helpers.testPlatform)).toBe(-1);
+        });
+    }
+
+    function fullPlatformList() {
+        return cordova.raw.platform('list').then(function() {
+            var installed = results.match(/Installed platforms: (.*)/);
+            expect(installed).toBeDefined();
+            expect(installed[1].indexOf(helpers.testPlatform)).toBeGreaterThan(-1);
+        });
+    }
+
+    // The flows we want to test are add, rm, list, and upgrade.
+    // They should run the appropriate hooks.
+    // They should fail when not inside a Cordova project.
+    // These tests deliberately have no beforeEach and afterEach that are cleaning things up.
+    it('should successfully run', function(done) {
+        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
+        // Using /* doesn't work because of hidden files.
+        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
+        shell.mv(path.join(tmpDir, 'base'), project);
+        process.chdir(project);
+
+        // Now we load the config.json in the newly created project and edit the target platform's lib entry
+        // to point at the fixture version. This is necessary so that cordova.prepare can find cordova.js there.
+        var c = config.read(project);
+        c.lib[helpers.testPlatform].uri = path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform + '-lib');
+        config.write(project, c);
+
+        // The config.json in the fixture project points at fake "local" paths.
+        // Since it's not a URL, the lazy-loader will just return the junk path.
+        spyOn(superspawn, 'spawn').andCallFake(function(cmd, args) {
+            if (cmd.match(/create\b/)) {
+                // This is a call to the bin/create script, so do the copy ourselves.
+                shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', 'android'), path.join(project, 'platforms'));
+            } else if(cmd.match(/version\b/)) {
+                return Q('3.3.0');
+            } else if(cmd.match(/update\b/)) {
+                fs.writeFileSync(path.join(project, 'platforms', helpers.testPlatform, 'updated'), 'I was updated!', 'utf-8');
+            }
+            return Q();
+        });
+
+        events.on('results', function(res) { results = res; });
+
+        // Check there are no platforms yet.
+        emptyPlatformList().then(function() {
+            // Add the testing platform.
+            return cordova.raw.platform('add', [helpers.testPlatform]);
+        }).then(function() {
+            // Check the platform add was successful.
+            expect(path.join(project, 'platforms', helpers.testPlatform)).toExist();
+            expect(path.join(project, 'merges', helpers.testPlatform)).toExist();
+            expect(path.join(project, 'platforms', helpers.testPlatform, 'cordova')).toExist();
+        }).then(fullPlatformList) // Check for it in platform ls.
+        .then(function() {
+            // Try to update the platform.
+            return cordova.raw.platform('update', [helpers.testPlatform]);
+        }).then(function() {
+            // Our fake update script in the exec mock above creates this dummy file.
+            expect(path.join(project, 'platforms', helpers.testPlatform, 'updated')).toExist();
+        }).then(fullPlatformList) // Platform should still be in platform ls.
+        .then(function() {
+            // And now remove it.
+            return cordova.raw.platform('rm', [helpers.testPlatform]);
+        }).then(function() {
+            // It should be gone.
+            expect(path.join(project, 'platforms', helpers.testPlatform)).not.toExist();
+        }).then(emptyPlatformList) // platform ls should be empty too.
+        .fail(function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    });
+});
+