src/cordova/plugin/add.js
function getFailedRequirements (reqs, pluginMap, platformMap, cordovaVersion) {
    var failed = [];
    var version = cordovaVersion;
    if (semver.prerelease(version)) {
        //  semver.inc with 'patch' type removes prereleased tag from version
        version = semver.inc(version, 'patch');
    }

    for (var req in reqs) {
        if (reqs.hasOwnProperty(req) && typeof req === 'string' && semver.validRange(reqs[req])) {
            var badInstalledVersion = null;
            // remove potential whitespace
            var trimmedReq = req.trim();

            if (pluginMap[trimmedReq] && !semver.satisfies(pluginMap[trimmedReq], reqs[req])) {
                badInstalledVersion = pluginMap[req];
            } else if (trimmedReq === 'cordova' && !semver.satisfies(version, reqs[req])) {
                badInstalledVersion = cordovaVersion;
            } else if (trimmedReq.indexOf('cordova-') === 0) {
                // Might be a platform constraint
                var platform = trimmedReq.substring(8);
                if (platformMap[platform] && !semver.satisfies(platformMap[platform], reqs[req])) {
                    badInstalledVersion = platformMap[platform];
                }
            }

            if (badInstalledVersion) {
                failed.push({
                    dependency: trimmedReq,
                    installed: badInstalledVersion.trim(),
                    required: reqs[req].trim()
                });
            }
        } else {
            events.emit('verbose', 'Ignoring invalid plugin dependency constraint ' + req + ':' + reqs[req]);
        }
    }

    return failed;
}
function getFailedRequirements (reqs, pluginMap, platformMap, cordovaVersion) {
    var failed = [];
    var version = cordovaVersion;
    if (semver.prerelease(version)) {
        //  semver.inc with 'patch' type removes prereleased tag from version
        version = semver.inc(version, 'patch');
    }

    for (var req in reqs) {
        if (reqs.hasOwnProperty(req) && typeof req === 'string' && semver.validRange(reqs[req])) {
            var badInstalledVersion = null;
            // remove potential whitespace
            var trimmedReq = req.trim();

            if (pluginMap[trimmedReq] && !semver.satisfies(pluginMap[trimmedReq], reqs[req])) {
                badInstalledVersion = pluginMap[req];
            } else if (trimmedReq === 'cordova' && !semver.satisfies(version, reqs[req])) {
                badInstalledVersion = cordovaVersion;
            } else if (trimmedReq.indexOf('cordova-') === 0) {
                // Might be a platform constraint
                var platform = trimmedReq.substring(8);
                if (platformMap[platform] && !semver.satisfies(platformMap[platform], reqs[req])) {
                    badInstalledVersion = platformMap[platform];
                }
            }

            if (badInstalledVersion) {
                failed.push({
                    dependency: trimmedReq,
                    installed: badInstalledVersion.trim(),
                    required: reqs[req].trim()
                });
            }
        } else {
            events.emit('verbose', 'Ignoring invalid plugin dependency constraint ' + req + ':' + reqs[req]);
        }
    }

    return failed;
}
/*
Returns an array full of objects of dependency requirements that are not met.
reqs - CordovaDependency object from plugin's package.json
pluginMap - previously installed plugins in the project
platformMap - previously installed platforms in the project
cordovaVersion - version of cordova being used