You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pm...@apache.org on 2012/03/22 21:43:06 UTC

[4/7] [CB-280] Improve layout of cordova-js scripts

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/common/plugin/resolveLocalFileSystemURI.js
----------------------------------------------------------------------
diff --git a/lib/common/plugin/resolveLocalFileSystemURI.js b/lib/common/plugin/resolveLocalFileSystemURI.js
new file mode 100644
index 0000000..fbf849b
--- /dev/null
+++ b/lib/common/plugin/resolveLocalFileSystemURI.js
@@ -0,0 +1,41 @@
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    exec = require('cordova/exec');
+
+/**
+ * Look up file system Entry referred to by local URI.
+ * @param {DOMString} uri  URI referring to a local file or directory
+ * @param successCallback  invoked with Entry object corresponding to URI
+ * @param errorCallback    invoked if error occurs retrieving file system entry
+ */
+module.exports = function(uri, successCallback, errorCallback) {
+    // error callback
+    var fail = function(error) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(error));
+        }
+    };
+    // if successful, return either a file or directory entry
+    var success = function(entry) {
+        var result;
+
+        if (entry) {
+            if (typeof successCallback === 'function') {
+                // create appropriate Entry object
+                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
+                try {
+                    successCallback(result);
+                }
+                catch (e) {
+                    console.log('Error invoking callback: ' + e);
+                }
+            }
+        }
+        else {
+            // no Entry object returned
+            fail(FileError.NOT_FOUND_ERR);
+        }
+    };
+
+    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/common/utils.js
----------------------------------------------------------------------
diff --git a/lib/common/utils.js b/lib/common/utils.js
new file mode 100644
index 0000000..49f6093
--- /dev/null
+++ b/lib/common/utils.js
@@ -0,0 +1,94 @@
+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;
+}
+
+var _self = {
+    /**
+     * Does a deep clone of the object.
+     */
+    clone: function(obj) {
+        if(!obj) { 
+            return obj;
+        }
+        
+        var retVal, i;
+        
+        if(obj instanceof Array){
+            retVal = [];
+            for(i = 0; i < obj.length; ++i){
+                retVal.push(_self.clone(obj[i]));
+            }
+            return retVal;
+        }
+        
+        if (obj instanceof Function) {
+            return obj;
+        }
+        
+        if(!(obj instanceof Object)){
+            return obj;
+        }
+        
+        if(obj instanceof Date){
+            return obj;
+        }
+
+        retVal = {};
+        for(i in obj){
+            if(!(i in retVal) || retVal[i] != obj[i]) {
+                retVal[i] = _self.clone(obj[i]);
+            }
+        }
+        return retVal;
+    },
+
+    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
+     */
+    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.
+     */
+    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;
+        };
+    }())
+
+};
+
+module.exports = _self;

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/errgen/exec.js
----------------------------------------------------------------------
diff --git a/lib/errgen/exec.js b/lib/errgen/exec.js
new file mode 100644
index 0000000..dc47fcb
--- /dev/null
+++ b/lib/errgen/exec.js
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * 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
+ *      Asynchrounous: 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
+ */
+
+//------------------------------------------------------------------------------
+module.exports = function exec(success, fail, service, action, args) {
+    var signature = service + "::" + action
+
+    //--------------------------------------------------------------------------
+    function callFail() {
+        var args = "<unable to JSONify>"
+        
+        try {
+            args = JSON.stringify(args)
+        }
+        catch (e) {}
+
+        var call = signature + "(" + args + ")"
+
+        if (!fail) {
+            console.log("failure callback not set for " + call)
+            return
+        }
+        
+        if (typeof(fail) != 'function') {
+            console.log("failure callback not a function for " + call)
+            return
+        }
+        
+        try {
+            fail("expected errgen failure for " + call)
+        }
+        catch (e) {
+            console.log("exception running failure callback for " + call)
+            console.log("   exception: " + e)
+            return
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    if (Overrides[signature]) {
+        Overrides[signature].call(null, success, fail, args)
+        return
+    }
+    
+    setTimeout(callFail, 10)
+}
+
+//------------------------------------------------------------------------------
+var Overrides = {}
+
+//------------------------------------------------------------------------------
+function addOverride(func) {
+    var name = func.name.replace('__', '::')
+    Overrides[name] = func
+}
+
+//------------------------------------------------------------------------------
+addOverride(function Accelerometer__setTimeout(success, fail, args) {
+    setTimeout(function() { 
+        fail("Accelerometer::setTimeout") 
+    }, 10)
+})
+
+//------------------------------------------------------------------------------
+addOverride(function Accelerometer__getTimeout(success, fail, args) {
+    setTimeout(function() { 
+        fail("Accelerometer::getTimeout") 
+    }, 10)
+})
+
+//------------------------------------------------------------------------------
+addOverride(function Network_Status__getConnectionInfo(success, fail) {
+    setTimeout(function() { 
+        success("none")
+    }, 10)
+})

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

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/errgen/plugin/errgen/device.js
----------------------------------------------------------------------
diff --git a/lib/errgen/plugin/errgen/device.js b/lib/errgen/plugin/errgen/device.js
new file mode 100644
index 0000000..4e05777
--- /dev/null
+++ b/lib/errgen/plugin/errgen/device.js
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+
+//------------------------------------------------------------------------------
+function Device() {
+    window.DeviceInfo = {}
+    
+    this.platform  = "errgen"
+    this.version   = "any"
+    this.name      = "errgen"
+    this.phonegap  = {}
+    this.gap       = this.phonegap
+    this.uuid      = "1234-5678-9012-3456"
+    this.available = true
+    
+    require('cordova/channel').onCordovaInfoReady.fire()
+}
+
+//------------------------------------------------------------------------------
+module.exports = window.DeviceInfo = new Device()

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/exec/android.js
----------------------------------------------------------------------
diff --git a/lib/exec/android.js b/lib/exec/android.js
deleted file mode 100644
index b3410bb..0000000
--- a/lib/exec/android.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * 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
- *      Asynchrounous: 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');
-
-module.exports = function(success, fail, service, action, args) {
-  try {
-    var callbackId = service + cordova.callbackId++;
-    if (success || fail) {
-        cordova.callbacks[callbackId] = {success:success, fail:fail};
-    }
-
-    var r = prompt(JSON.stringify(args), "gap:"+JSON.stringify([service, action, callbackId, true]));
-
-    // If a result was returned
-    if (r.length > 0) {
-        eval("var v="+r+";");
-
-        // If status is OK, then return value back to caller
-        if (v.status === cordova.callbackStatus.OK) {
-
-            // If there is a success callback, then call it now with
-            // returned value
-            if (success) {
-                try {
-                    success(v.message);
-                } catch (e) {
-                    console.log("Error in success callback: " + callbackId  + " = " + e);
-                }
-
-                // Clear callback if not expecting any more results
-                if (!v.keepCallback) {
-                    delete cordova.callbacks[callbackId];
-                }
-            }
-            return v.message;
-        }
-
-        // If no result
-        else if (v.status === cordova.callbackStatus.NO_RESULT) {
-            // Clear callback if not expecting any more results
-            if (!v.keepCallback) {
-                delete cordova.callbacks[callbackId];
-            }
-        }
-
-        // If error, then display error
-        else {
-            console.log("Error: Status="+v.status+" Message="+v.message);
-
-            // If there is a fail callback, then call it now with returned value
-            if (fail) {
-                try {
-                    fail(v.message);
-                }
-                catch (e1) {
-                    console.log("Error in error callback: "+callbackId+" = "+e1);
-                }
-
-                // Clear callback if not expecting any more results
-                if (!v.keepCallback) {
-                    delete cordova.callbacks[callbackId];
-                }
-            }
-            return null;
-        }
-    }
-  } catch (e2) {
-    console.log("Error: "+e2);
-  }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/exec/blackberry.js
----------------------------------------------------------------------
diff --git a/lib/exec/blackberry.js b/lib/exec/blackberry.js
deleted file mode 100644
index a5fb81f..0000000
--- a/lib/exec/blackberry.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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
- *      Asynchrounous: 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 blackberry = require('cordova/plugin/blackberry/manager'),
-    cordova = require('cordova');
-
-module.exports = function(success, fail, service, action, args) {
-    try {
-        var v = blackberry.exec(success, fail, service, action, args);
-
-        // If status is OK, then return value back to caller
-        if (v.status == cordova.callbackStatus.OK) {
-
-            // If there is a success callback, then call it now with returned value
-            if (success) {
-                try {
-                    success(v.message);
-                }
-                catch (e) {
-                    console.log("Error in success callback: "+ service + "." + action + " = "+e);
-                }
-
-            }
-            return v.message;
-        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
-
-        } else {
-            // If error, then display error
-            console.log("Error: " + service + "." + action + " Status="+v.status+" Message="+v.message);
-
-            // If there is a fail callback, then call it now with returned value
-            if (fail) {
-                try {
-                    fail(v.message);
-                }
-                catch (e) {
-                    console.log("Error in error callback: " + service + "." + action + " = "+e);
-                }
-            }
-            return null;
-        }
-    } catch (e) {
-        alert("Error: "+e);
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/exec/errgen.js
----------------------------------------------------------------------
diff --git a/lib/exec/errgen.js b/lib/exec/errgen.js
deleted file mode 100644
index dc47fcb..0000000
--- a/lib/exec/errgen.js
+++ /dev/null
@@ -1,107 +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.
- */
-
-/**
- * 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
- *      Asynchrounous: 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
- */
-
-//------------------------------------------------------------------------------
-module.exports = function exec(success, fail, service, action, args) {
-    var signature = service + "::" + action
-
-    //--------------------------------------------------------------------------
-    function callFail() {
-        var args = "<unable to JSONify>"
-        
-        try {
-            args = JSON.stringify(args)
-        }
-        catch (e) {}
-
-        var call = signature + "(" + args + ")"
-
-        if (!fail) {
-            console.log("failure callback not set for " + call)
-            return
-        }
-        
-        if (typeof(fail) != 'function') {
-            console.log("failure callback not a function for " + call)
-            return
-        }
-        
-        try {
-            fail("expected errgen failure for " + call)
-        }
-        catch (e) {
-            console.log("exception running failure callback for " + call)
-            console.log("   exception: " + e)
-            return
-        }
-    }
-
-    //--------------------------------------------------------------------------
-    if (Overrides[signature]) {
-        Overrides[signature].call(null, success, fail, args)
-        return
-    }
-    
-    setTimeout(callFail, 10)
-}
-
-//------------------------------------------------------------------------------
-var Overrides = {}
-
-//------------------------------------------------------------------------------
-function addOverride(func) {
-    var name = func.name.replace('__', '::')
-    Overrides[name] = func
-}
-
-//------------------------------------------------------------------------------
-addOverride(function Accelerometer__setTimeout(success, fail, args) {
-    setTimeout(function() { 
-        fail("Accelerometer::setTimeout") 
-    }, 10)
-})
-
-//------------------------------------------------------------------------------
-addOverride(function Accelerometer__getTimeout(success, fail, args) {
-    setTimeout(function() { 
-        fail("Accelerometer::getTimeout") 
-    }, 10)
-})
-
-//------------------------------------------------------------------------------
-addOverride(function Network_Status__getConnectionInfo(success, fail) {
-    setTimeout(function() { 
-        success("none")
-    }, 10)
-})

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/exec/ios.js
----------------------------------------------------------------------
diff --git a/lib/exec/ios.js b/lib/exec/ios.js
deleted file mode 100644
index 32d8b6a..0000000
--- a/lib/exec/ios.js
+++ /dev/null
@@ -1,93 +0,0 @@
-    /**
-     * Creates a gap bridge iframe used to notify the native code about queued
-     * commands.
-     *
-     * @private
-     */
-var cordova = require('cordova'),
-    gapBridge,
-    createGapBridge = function() {
-        gapBridge = document.createElement("iframe");
-        gapBridge.setAttribute("style", "display:none;");
-        gapBridge.setAttribute("height","0px");
-        gapBridge.setAttribute("width","0px");
-        gapBridge.setAttribute("frameborder","0");
-        document.documentElement.appendChild(gapBridge);
-    },
-    channel = require('cordova/channel');
-
-module.exports = function() { 
-    if (!channel.onCordovaInfoReady.fired) {
-        alert("ERROR: Attempting to call cordova.exec()" +
-              " before 'deviceready'. Ignoring.");
-        return;
-    }
-
-    var successCallback, failCallback, service, action, actionArgs;
-    var callbackId = null;
-    if (typeof arguments[0] !== "string") {
-        // FORMAT ONE
-        successCallback = arguments[0];
-        failCallback = arguments[1];
-        service = arguments[2];
-        action = arguments[3];
-        actionArgs = arguments[4];
-
-        // Since we need to maintain backwards compatibility, we have to pass
-        // an invalid callbackId even if no callback was provided since plugins
-        // will be expecting it. The Cordova.exec() implementation allocates
-        // an invalid callbackId and passes it even if no callbacks were given.
-        callbackId = 'INVALID';
-    } else {
-        // FORMAT TWO
-        splitCommand = arguments[0].split(".");
-        action = splitCommand.pop();
-        service = splitCommand.join(".");
-        actionArgs = Array.prototype.splice.call(arguments, 1);
-    }
-    
-    // Start building the command object.
-    var command = {
-        className: service,
-        methodName: action,
-        arguments: []
-    };
-
-    // Register the callbacks and add the callbackId to the positional
-    // arguments if given.
-    if (successCallback || failCallback) {
-        callbackId = service + cordova.callbackId++;
-        cordova.callbacks[callbackId] = 
-            {success:successCallback, fail:failCallback};
-    }
-    if (callbackId != null) {
-        command.arguments.push(callbackId);
-    }
-
-    for (var i = 0; i < actionArgs.length; ++i) {
-        var arg = actionArgs[i];
-        if (arg == undefined || arg == null) { // nulls are pushed to the args now (becomes NSNull)
-            continue;  //command.arguments.push(arg);
-        } else if (typeof(arg) == 'object' && !(arg instanceof Array)) {
-            command.options = arg;
-        } else {
-            command.arguments.push(arg);
-        }
-    }
-
-    // Stringify and queue the command. We stringify to command now to
-    // effectively clone the command arguments in case they are mutated before
-    // the command is executed.
-    cordova.commandQueue.push(JSON.stringify(command));
-
-    // If the queue length is 1, then that means it was empty before we queued
-    // the given command, so let the native side know that we have some
-    // commands to execute, unless the queue is currently being flushed, in
-    // which case the command will be picked up without notification.
-    if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) {
-        if (!gapBridge) {
-            createGapBridge();
-        }
-        gapBridge.src = "gap://ready";
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/exec/playbook.js
----------------------------------------------------------------------
diff --git a/lib/exec/playbook.js b/lib/exec/playbook.js
deleted file mode 100644
index ff2cbd9..0000000
--- a/lib/exec/playbook.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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
- *      Asynchrounous: 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
- */
-
-module.exports = function(success, fail, service, action, args) {
-    try {
-        var playbook = require('cordova/plugin/playbook/manager'),
-            cordova = require('cordova'),
-            v = playbook.exec(success, fail, service, action, args);
-
-        // If status is OK, then return value back to caller
-        if (v.status == cordova.callbackStatus.OK) {
-
-            // If there is a success callback, then call it now with returned value
-            if (success) {
-                try {
-                    success(v.message);
-                }
-                catch (e) {
-                    console.log("Error in success callback: "+cordova.callbackId+" = "+e);
-                }
-
-            }
-            return v.message;
-        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
-
-        } else {
-            // If error, then display error
-            console.log("Error: Status="+v.status+" Message="+v.message);
-
-            // If there is a fail callback, then call it now with returned value
-            if (fail) {
-                try {
-                    fail(v.message);
-                }
-                catch (e) {
-                    console.log("Error in error callback: "+cordova.callbackId+" = "+e);
-                }
-            }
-            return null;
-        }
-    } catch (e) {
-        alert("Error: "+e);
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/exec/test.js
----------------------------------------------------------------------
diff --git a/lib/exec/test.js b/lib/exec/test.js
deleted file mode 100644
index a5d1a69..0000000
--- a/lib/exec/test.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = jasmine.createSpy();

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/exec/wp7.js
----------------------------------------------------------------------
diff --git a/lib/exec/wp7.js b/lib/exec/wp7.js
deleted file mode 100644
index 78eef40..0000000
--- a/lib/exec/wp7.js
+++ /dev/null
@@ -1,57 +0,0 @@
-var cordova = require('cordova');
-
-/**
- * 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
- *      Asynchrounous: 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
- */
-
-module.exports = function(success, fail, service, action, args) {
-    var callbackId = service + cordova.callbackId++;
-    if (typeof success == "function" || typeof fail == "function") {
-        cordova.callbacks[callbackId] = {success:success, fail:fail};
-    }
-    // generate a new command string, ex. DebugConsole/log/DebugConsole23/{"message":"wtf dude?"}
-     var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
-     // pass it on to Notify
-     window.external.Notify(command);
-};
-
-// TODO: is this what native side invokes?
-// if so pluginize under plugin/wp7
-cordovaCommandResult = function(status,callbackId,args,cast) {
-    if(status === "backbutton") {
-
-        cordova.fireEvent(document,"backbutton");
-        return "true";
-
-    } else if(status === "resume") {
-
-        cordova.onResume.fire();
-        return "true";
-
-    } else if(status === "pause") {
-
-        cordova.onPause.fire();
-        return "true";  
-    }
-    
-    var safeStatus = parseInt(status, 10);
-    if(safeStatus === cordova.callbackStatus.NO_RESULT ||
-       safeStatus === cordova.callbackStatus.OK) {
-        cordova.CallbackSuccess(callbackId,args,cast);
-    }
-    else
-    {
-        cordova.CallbackError(callbackId,args,cast);
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/exec.js
----------------------------------------------------------------------
diff --git a/lib/ios/exec.js b/lib/ios/exec.js
new file mode 100644
index 0000000..32d8b6a
--- /dev/null
+++ b/lib/ios/exec.js
@@ -0,0 +1,93 @@
+    /**
+     * Creates a gap bridge iframe used to notify the native code about queued
+     * commands.
+     *
+     * @private
+     */
+var cordova = require('cordova'),
+    gapBridge,
+    createGapBridge = function() {
+        gapBridge = document.createElement("iframe");
+        gapBridge.setAttribute("style", "display:none;");
+        gapBridge.setAttribute("height","0px");
+        gapBridge.setAttribute("width","0px");
+        gapBridge.setAttribute("frameborder","0");
+        document.documentElement.appendChild(gapBridge);
+    },
+    channel = require('cordova/channel');
+
+module.exports = function() { 
+    if (!channel.onCordovaInfoReady.fired) {
+        alert("ERROR: Attempting to call cordova.exec()" +
+              " before 'deviceready'. Ignoring.");
+        return;
+    }
+
+    var successCallback, failCallback, service, action, actionArgs;
+    var callbackId = null;
+    if (typeof arguments[0] !== "string") {
+        // FORMAT ONE
+        successCallback = arguments[0];
+        failCallback = arguments[1];
+        service = arguments[2];
+        action = arguments[3];
+        actionArgs = arguments[4];
+
+        // Since we need to maintain backwards compatibility, we have to pass
+        // an invalid callbackId even if no callback was provided since plugins
+        // will be expecting it. The Cordova.exec() implementation allocates
+        // an invalid callbackId and passes it even if no callbacks were given.
+        callbackId = 'INVALID';
+    } else {
+        // FORMAT TWO
+        splitCommand = arguments[0].split(".");
+        action = splitCommand.pop();
+        service = splitCommand.join(".");
+        actionArgs = Array.prototype.splice.call(arguments, 1);
+    }
+    
+    // Start building the command object.
+    var command = {
+        className: service,
+        methodName: action,
+        arguments: []
+    };
+
+    // Register the callbacks and add the callbackId to the positional
+    // arguments if given.
+    if (successCallback || failCallback) {
+        callbackId = service + cordova.callbackId++;
+        cordova.callbacks[callbackId] = 
+            {success:successCallback, fail:failCallback};
+    }
+    if (callbackId != null) {
+        command.arguments.push(callbackId);
+    }
+
+    for (var i = 0; i < actionArgs.length; ++i) {
+        var arg = actionArgs[i];
+        if (arg == undefined || arg == null) { // nulls are pushed to the args now (becomes NSNull)
+            continue;  //command.arguments.push(arg);
+        } else if (typeof(arg) == 'object' && !(arg instanceof Array)) {
+            command.options = arg;
+        } else {
+            command.arguments.push(arg);
+        }
+    }
+
+    // Stringify and queue the command. We stringify to command now to
+    // effectively clone the command arguments in case they are mutated before
+    // the command is executed.
+    cordova.commandQueue.push(JSON.stringify(command));
+
+    // If the queue length is 1, then that means it was empty before we queued
+    // the given command, so let the native side know that we have some
+    // commands to execute, unless the queue is currently being flushed, in
+    // which case the command will be picked up without notification.
+    if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) {
+        if (!gapBridge) {
+            createGapBridge();
+        }
+        gapBridge.src = "gap://ready";
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/platform.js
----------------------------------------------------------------------
diff --git a/lib/ios/platform.js b/lib/ios/platform.js
new file mode 100644
index 0000000..e68b52e
--- /dev/null
+++ b/lib/ios/platform.js
@@ -0,0 +1,41 @@
+module.exports = {
+    id: "ios",
+    initialize:function() {
+        // iOS doesn't allow reassigning / overriding navigator.geolocation object.
+        // So clobber its methods here instead :)
+        var geo = require('cordova/plugin/geolocation');
+        
+        navigator.geolocation.getCurrentPosition = geo.getCurrentPosition;
+        navigator.geolocation.watchPosition = geo.watchPosition;
+        navigator.geolocation.clearWatch = geo.clearWatch;
+    },
+    objects: {
+        File: { // exists natively, override
+            path: "cordova/plugin/File"
+        },
+        MediaError: { // exists natively, override
+            path: "cordova/plugin/MediaError"
+        },
+        device: {
+            path: 'cordova/plugin/ios/device'
+        },
+        console: {
+            path: 'cordova/plugin/ios/console'
+        }
+    },
+    merges:{
+        Entry:{
+            path: "cordova/plugin/ios/Entry"
+        },
+        FileReader:{
+            path: "cordova/plugin/ios/FileReader"
+        },
+        navigator:{
+            children:{
+                notification:{
+                    path:"cordova/plugin/ios/notification"
+                }
+            }
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/plugin/ios/Entry.js
----------------------------------------------------------------------
diff --git a/lib/ios/plugin/ios/Entry.js b/lib/ios/plugin/ios/Entry.js
new file mode 100644
index 0000000..230da8a
--- /dev/null
+++ b/lib/ios/plugin/ios/Entry.js
@@ -0,0 +1,7 @@
+module.exports = {
+    toURL:function() {
+        // TODO: refactor path in a cross-platform way so we can eliminate 
+        // these kinds of platform-specific hacks.
+        return "file://localhost" + this.fullPath;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/plugin/ios/FileReader.js
----------------------------------------------------------------------
diff --git a/lib/ios/plugin/ios/FileReader.js b/lib/ios/plugin/ios/FileReader.js
new file mode 100644
index 0000000..5711393
--- /dev/null
+++ b/lib/ios/plugin/ios/FileReader.js
@@ -0,0 +1,87 @@
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    FileReader = require('cordova/plugin/FileReader'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+module.exports = {
+    readAsText:function(file, encoding) {
+        // Figure out pathing
+        this.fileName = '';
+        if (typeof file.fullPath === 'undefined') {
+            this.fileName = file;
+        } else {
+            this.fileName = file.fullPath;
+        }
+
+        // Already loading something
+        if (this.readyState == FileReader.LOADING) {
+            throw new FileError(FileError.INVALID_STATE_ERR);
+        }
+
+        // LOADING state
+        this.readyState = FileReader.LOADING;
+
+        // If loadstart callback
+        if (typeof this.onloadstart === "function") {
+            this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+        }
+
+        // Default encoding is UTF-8
+        var enc = encoding ? encoding : "UTF-8";
+
+        var me = this;
+
+        // Read file
+        exec(
+            // Success callback
+            function(r) {
+                // If DONE (cancelled), then don't do anything
+                if (me.readyState === FileReader.DONE) {
+                    return;
+                }
+
+                // Save result
+                me.result = decodeURIComponent(r);
+
+                // If onload callback
+                if (typeof me.onload === "function") {
+                    me.onload(new ProgressEvent("load", {target:me}));
+                }
+
+                // DONE state
+                me.readyState = FileReader.DONE;
+
+                // If onloadend callback
+                if (typeof me.onloadend === "function") {
+                    me.onloadend(new ProgressEvent("loadend", {target:me}));
+                }
+            },
+            // Error callback
+            function(e) {
+                // If DONE (cancelled), then don't do anything
+                if (me.readyState === FileReader.DONE) {
+                    return;
+                }
+
+                // DONE state
+                me.readyState = FileReader.DONE;
+
+                // null result
+                me.result = null;
+
+                // Save error
+                me.error = new FileError(e);
+
+                // If onerror callback
+                if (typeof me.onerror === "function") {
+                    me.onerror(new ProgressEvent("error", {target:me}));
+                }
+
+                // If onloadend callback
+                if (typeof me.onloadend === "function") {
+                    me.onloadend(new ProgressEvent("loadend", {target:me}));
+                }
+            }, 
+        "File", "readAsText", [this.fileName, enc]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/plugin/ios/console.js
----------------------------------------------------------------------
diff --git a/lib/ios/plugin/ios/console.js b/lib/ios/plugin/ios/console.js
new file mode 100644
index 0000000..8651591
--- /dev/null
+++ b/lib/ios/plugin/ios/console.js
@@ -0,0 +1,102 @@
+var exec = require('cordova/exec');
+
+/**
+ * String indentation/formatting
+ */
+function indent(str) {
+    return str.replace(/^/mg, "    ");
+}
+/**
+ * Format a string for pretty logging
+ */
+function makeStructured(obj, depth) {
+    var str = "";
+    for (var i in obj) {
+        try {
+            if (typeof(obj[i]) == 'object' && depth < maxDepth) {
+                str += i + ":\n" + indent(makeStructured(obj[i])) + "\n";
+            } else {
+                str += i + " = " + indent(String(obj[i])).replace(/^ {4}/, "") + "\n";
+            }
+        } catch(e) {
+            str += i + " = EXCEPTION: " + e.message + "\n";
+        }
+    }
+    return str;
+}
+
+/**
+ * This class provides access to the debugging console.
+ * @constructor
+ */
+var DebugConsole = function() {
+    this.winConsole = window.console;
+    this.logLevel = DebugConsole.INFO_LEVEL;
+};
+
+// from most verbose, to least verbose
+DebugConsole.ALL_LEVEL    = 1; // same as first level
+DebugConsole.INFO_LEVEL   = 1;
+DebugConsole.WARN_LEVEL   = 2;
+DebugConsole.ERROR_LEVEL  = 4;
+DebugConsole.NONE_LEVEL   = 8;
+													
+DebugConsole.prototype.setLevel = function(level) {
+    this.logLevel = level;
+};
+
+/**
+ * Utility function for rendering and indenting strings, or serializing
+ * objects to a string capable of being printed to the console.
+ * @param {Object|String} message The string or object to convert to an indented string
+ * @private
+ */
+DebugConsole.prototype.processMessage = function(message, maxDepth) {
+	if (maxDepth === undefined) maxDepth = 0;
+    if (typeof(message) != 'object') {
+        return (this.isDeprecated ? "WARNING: debug object is deprecated, please use console object \n" + message : message);
+    } else {
+        return ("Object:\n" + makeStructured(message, maxDepth));
+    }
+};
+
+/**
+ * Print a normal log message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.log = function(message, maxDepth) {
+    if (this.logLevel <= DebugConsole.INFO_LEVEL)
+        exec(null, null, 'Debug Console', 'log',
+            [ this.processMessage(message, maxDepth), { logLevel: 'INFO' } ]
+        );
+    else
+        this.winConsole.log(message);
+};
+
+/**
+ * Print a warning message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.warn = function(message, maxDepth) {
+    if (this.logLevel <= DebugConsole.WARN_LEVEL)
+        exec(null, null, 'Debug Console', 'log',
+            [ this.processMessage(message, maxDepth), { logLevel: 'WARN' } ]
+        );
+    else
+        this.winConsole.error(message);
+};
+
+/**
+ * Print an error message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.error = function(message, maxDepth) {
+    if (this.logLevel <= DebugConsole.ERROR_LEVEL)
+        exec(null, null, 'Debug Console', 'log',
+            [ this.processMessage(message, maxDepth), { logLevel: 'ERROR' } ]
+        );
+    else
+        this.winConsole.error(message);
+};
+
+module.exports = new DebugConsole();

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/plugin/ios/device.js
----------------------------------------------------------------------
diff --git a/lib/ios/plugin/ios/device.js b/lib/ios/plugin/ios/device.js
new file mode 100644
index 0000000..c6d117b
--- /dev/null
+++ b/lib/ios/plugin/ios/device.js
@@ -0,0 +1,30 @@
+/**
+ * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+var exec = require('cordova/exec'),
+    channel = require('cordova/channel');
+
+var Device = function() {
+    this.platform = null;
+    this.version  = null;
+    this.name     = null;
+    this.cordova  = null;
+    this.uuid     = null;
+};
+
+Device.prototype.setInfo = function(info) {
+    try {
+        this.platform = info.platform;
+        this.version = info.version;
+        this.name = info.name;
+        this.cordova = info.gap;
+        this.uuid = info.uuid;
+        channel.onCordovaInfoReady.fire();
+    } catch(e) {
+        alert('Error during device info setting in cordova/plugin/ios/device!');
+    }
+};
+
+module.exports = new Device();

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/plugin/ios/nativecomm.js
----------------------------------------------------------------------
diff --git a/lib/ios/plugin/ios/nativecomm.js b/lib/ios/plugin/ios/nativecomm.js
new file mode 100644
index 0000000..938a68c
--- /dev/null
+++ b/lib/ios/plugin/ios/nativecomm.js
@@ -0,0 +1,10 @@
+var cordova = require('cordova');
+
+/**
+ * Called by native code to retrieve all queued commands and clear the queue.
+ */
+module.exports = function() {
+  var json = JSON.stringify(cordova.commandQueue);
+  cordova.commandQueue = [];
+  return json;
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/ios/plugin/ios/notification.js
----------------------------------------------------------------------
diff --git a/lib/ios/plugin/ios/notification.js b/lib/ios/plugin/ios/notification.js
new file mode 100644
index 0000000..a49567d
--- /dev/null
+++ b/lib/ios/plugin/ios/notification.js
@@ -0,0 +1,7 @@
+var Media = require('cordova/plugin/Media');
+
+module.exports = {
+    beep:function(count) {
+        (new Media('beep.wav')).play();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/platform/android.js
----------------------------------------------------------------------
diff --git a/lib/platform/android.js b/lib/platform/android.js
deleted file mode 100644
index 6c71820..0000000
--- a/lib/platform/android.js
+++ /dev/null
@@ -1,131 +0,0 @@
-module.exports = {
-    id: "android",
-    initialize:function() {
-        var channel = require("cordova/channel"),
-            cordova = require('cordova'),
-            callback = require('cordova/plugin/android/callback'),
-            polling = require('cordova/plugin/android/polling'),
-            exec = require('cordova/exec');
-
-        channel.onDestroy.subscribe(function() {
-            cordova.shuttingDown = true;
-        });
-
-        // Start listening for XHR callbacks
-        // Figure out which bridge approach will work on this Android
-        // device: polling or XHR-based callbacks
-        setTimeout(function() {
-            if (cordova.UsePolling) {
-                polling();
-            }
-            else {
-                var isPolling = prompt("usePolling", "gap_callbackServer:");
-                cordova.UsePolling = isPolling;
-                if (isPolling == "true") {
-                    cordova.UsePolling = true;
-                    polling();
-                } else {
-                    cordova.UsePolling = false;
-                    callback();
-                }
-            }
-        }, 1);
-
-        // Inject a listener for the backbutton on the document.
-        var backButtonChannel = cordova.addDocumentEventHandler('backbutton', {
-            onSubscribe:function() {
-                // If we just attached the first handler, let native know we need to override the back button.
-                if (this.numHandlers === 1) {
-                    exec(null, null, "App", "overrideBackbutton", [true]);
-                }
-            },
-            onUnsubscribe:function() {
-                // If we just detached the last handler, let native know we no longer override the back button.
-                if (this.numHandlers === 0) {
-                    exec(null, null, "App", "overrideBackbutton", [false]);
-                }
-            }
-        });
-
-        // Add hardware MENU and SEARCH button handlers
-        cordova.addDocumentEventHandler('menubutton');
-        cordova.addDocumentEventHandler('searchbutton');
-
-        // Figure out if we need to shim-in localStorage and WebSQL
-        // support from the native side.
-        var storage = require('cordova/plugin/android/storage');
-
-        // First patch WebSQL if necessary
-        if (typeof window.openDatabase == 'undefined') {
-            // Not defined, create an openDatabase function for all to use!
-            window.openDatabase = storage.openDatabase;
-        } else {
-            // Defined, but some Android devices will throw a SECURITY_ERR -
-            // so we wrap the whole thing in a try-catch and shim in our own
-            // if the device has Android bug 16175.
-            var originalOpenDatabase = window.openDatabase;
-            window.openDatabase = function(name, version, desc, size) {
-                var db = null;
-                try {
-                    db = originalOpenDatabase(name, version, desc, size);
-                } 
-                catch (ex) {
-                    db = null;
-                }
-
-                if (db === null) {
-                    return storage.openDatabase(name, version, desc, size);
-                }
-                else {
-                    return db;
-                }
-              
-            };
-        }
-
-        // Patch localStorage if necessary
-        if (typeof window.localStorage == 'undefined' || window.localStorage === null) {
-            window.localStorage = new storage.CupCakeLocalStorage();
-        }
-
-        // Let native code know we are all done on the JS side.
-        // Native code will then un-hide the WebView.
-        channel.join(function() {
-            prompt("", "gap_init:");
-        }, [channel.onCordovaReady]);
-    },
-    objects: {
-        cordova: {
-            children: {
-                JSCallback:{
-                    path:"cordova/plugin/android/callback"
-                },
-                JSCallbackPolling:{
-                    path:"cordova/plugin/android/polling"
-                }
-            }
-        },
-        navigator: {
-            children: {
-                app:{
-                    path: "cordova/plugin/android/app"
-                }
-            }
-        },
-        device:{
-            path: "cordova/plugin/android/device"
-        },
-        File: { // exists natively on Android WebView, override
-            path: "cordova/plugin/File"
-        },
-        FileReader: { // exists natively on Android WebView, override
-            path: "cordova/plugin/FileReader"
-        },
-        FileError: { //exists natively on Android WebView on Android 4.x
-            path: "cordova/plugin/FileError"
-        },
-        MediaError: { // exists natively on Android WebView on Android 4.x
-            path: "cordova/plugin/MediaError"
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/platform/blackberry.js
----------------------------------------------------------------------
diff --git a/lib/platform/blackberry.js b/lib/platform/blackberry.js
deleted file mode 100644
index d98f0e6..0000000
--- a/lib/platform/blackberry.js
+++ /dev/null
@@ -1,179 +0,0 @@
-module.exports = {
-    id: "blackberry",
-    initialize:function() {
-        var cordova = require('cordova'),
-            exec = require('cordova/exec'),
-            channel = require('cordova/channel'),
-            blackberryManager = require('cordova/plugin/blackberry/manager'),
-            app = require('cordova/plugin/blackberry/app');
-
-        // BB OS 5 does not define window.console.
-        if (typeof window.console === 'undefined') {
-            window.console = {};
-        }
-
-        // Override console.log with native logging ability.
-        // BB OS 7 devices define console.log for use with web inspector
-        // debugging. If console.log is already defined, invoke it in addition
-        // to native logging.
-        var origLog = window.console.log;
-        window.console.log = function(msg) {
-            if (typeof origLog === 'function') {
-                origLog.call(window.console, msg);
-            }
-            org.apache.cordova.Logger.log(''+msg);
-        };
-
-        // Mapping of button events to BlackBerry key identifier.
-        var buttonMapping = {
-            'backbutton'         : blackberry.system.event.KEY_BACK,
-            'conveniencebutton1' : blackberry.system.event.KEY_CONVENIENCE_1,
-            'conveniencebutton2' : blackberry.system.event.KEY_CONVENIENCE_2,
-            'endcallbutton'      : blackberry.system.event.KEY_ENDCALL,
-            'menubutton'         : blackberry.system.event.KEY_MENU,
-            'startcallbutton'    : blackberry.system.event.KEY_STARTCALL,
-            'volumedownbutton'   : blackberry.system.event.KEY_VOLUMEDOWN,
-            'volumeupbutton'     : blackberry.system.event.KEY_VOLUMEUP
-        };
-
-        // Generates a function which fires the specified event.
-        var fireEvent = function(event) {
-            return function() {
-                cordova.fireDocumentEvent(event, null);
-            };
-        };
-
-        var eventHandler = function(event) {
-            return { onSubscribe : function() {
-                // If we just attached the first handler, let native know we
-                // need to override the back button.
-                if (this.numHandlers === 1) {
-                    blackberry.system.event.onHardwareKey(
-                            buttonMapping[event], fireEvent(event));
-                }
-            },
-            onUnsubscribe : function() {
-                // If we just detached the last handler, let native know we
-                // no longer override the back button.
-                if (this.numHandlers === 0) {
-                    blackberry.system.event.onHardwareKey(
-                            buttonMapping[event], null);
-                }
-            }};
-        };
-
-        // Inject listeners for buttons on the document.
-        for (var button in buttonMapping) {
-            if (buttonMapping.hasOwnProperty(button)) {
-                cordova.addDocumentEventHandler(button, eventHandler(button));
-            }
-        }
-
-        // Fires off necessary code to pause/resume app
-        var resume = function() {
-            cordova.fireDocumentEvent('resume');
-            blackberryManager.resume();
-        };
-        var pause = function() {
-            cordova.fireDocumentEvent('pause');
-            blackberryManager.pause();
-        };
-
-        /************************************************
-         * Patch up the generic pause/resume listeners. *
-         ************************************************/
-
-        // Unsubscribe handler - turns off native backlight change
-        // listener
-        var onUnsubscribe = function() {
-            if (channel.onResume.numHandlers === 0 && channel.onPause.numHandlers === 0) {
-                exec(null, null, 'App', 'ignoreBacklight', []);
-            }
-        };
-
-        // Native backlight detection win/fail callbacks
-        var backlightWin = function(isOn) {
-            if (isOn === true) {
-                resume();
-            } else {
-                pause();
-            }
-        };
-        var backlightFail = function(e) {
-            console.log("Error detecting backlight on/off.");
-        };
-
-        // Override stock resume and pause listeners so we can trigger
-        // some native methods during attach/remove
-        channel.onResume = cordova.addDocumentEventHandler('resume', {
-            onSubscribe:function() {
-                // If we just attached the first handler and there are
-                // no pause handlers, start the backlight system
-                // listener on the native side.
-                if (channel.onResume.numHandlers === 1 && channel.onPause.numHandlers === 0) {
-                    exec(backlightWin, backlightFail, "App", "detectBacklight", []);
-                }
-            },
-            onUnsubscribe:onUnsubscribe
-        });
-        channel.onPause = cordova.addDocumentEventHandler('pause', {
-            onSubscribe:function() {
-                // If we just attached the first handler and there are
-                // no resume handlers, start the backlight system
-                // listener on the native side.
-                if (channel.onResume.numHandlers === 0 && channel.onPause.numHandlers === 1) {
-                    exec(backlightWin, backlightFail, "App", "detectBacklight", []);
-                }
-            },
-            onUnsubscribe:onUnsubscribe
-        });
-
-        // Fire resume event when application brought to foreground.
-        blackberry.app.event.onForeground(resume);
-
-        // Fire pause event when application sent to background.
-        blackberry.app.event.onBackground(pause);
-
-        // Trap BlackBerry WebWorks exit. Allow plugins to clean up before exiting.
-        blackberry.app.event.onExit(app.exitApp);
-    },
-    objects: {
-        navigator: {
-            children: {
-                app: {
-                    path: "cordova/plugin/blackberry/app"
-                }
-            }
-        },
-        device: {
-            path: "cordova/plugin/blackberry/device"
-        },
-        File: { // exists natively on BlackBerry OS 7, override
-            path: "cordova/plugin/File"
-        }
-    },
-    merges: {
-        navigator: {
-            children: {
-                contacts: {
-                    path: 'cordova/plugin/blackberry/contacts'
-                },
-                device: {
-                    path: 'cordova/plugin/blackberry/device'
-                },
-                notification: {
-                    path: 'cordova/plugin/blackberry/notification'
-                }
-            }
-        },
-        Contact: {
-            path: 'cordova/plugin/blackberry/Contact'
-        },
-        DirectoryEntry: {
-            path: 'cordova/plugin/blackberry/DirectoryEntry'
-        },
-        Entry: {
-            path: 'cordova/plugin/blackberry/Entry'
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/platform/common.js
----------------------------------------------------------------------
diff --git a/lib/platform/common.js b/lib/platform/common.js
deleted file mode 100644
index e07bf03..0000000
--- a/lib/platform/common.js
+++ /dev/null
@@ -1,180 +0,0 @@
-module.exports = {
-    objects: {
-        cordova: {
-            path: 'cordova',
-            children: {
-                exec: {
-                    path: 'cordova/exec'
-                }
-            }
-        },
-        navigator: {
-            children: {
-                notification: {
-                    path: 'cordova/plugin/notification'
-                },
-                accelerometer: {
-                    path: 'cordova/plugin/accelerometer'
-                },
-                battery: {
-                    path: 'cordova/plugin/battery'
-                },
-                camera:{
-                    path: 'cordova/plugin/Camera'
-                },
-                compass:{
-                    path: 'cordova/plugin/compass'
-                },
-                contacts: {
-                    path: 'cordova/plugin/contacts'
-                },
-                device:{
-                    children:{
-                        capture: {
-                            path: 'cordova/plugin/capture'
-                        }
-                    }
-                },
-                geolocation: {
-                    path: 'cordova/plugin/geolocation'
-                },
-                network: {
-                    children: {
-                        connection: {
-                            path: 'cordova/plugin/network'
-                        }
-                    }
-                }
-            }
-        },
-        Acceleration: {
-            path: 'cordova/plugin/Acceleration'
-        },
-        Camera:{
-            path: 'cordova/plugin/CameraConstants'
-        },
-        CaptureError: {
-            path: 'cordova/plugin/CaptureError'
-        },
-        CaptureAudioOptions:{
-            path: 'cordova/plugin/CaptureAudioOptions'
-        },
-        CaptureImageOptions: {
-            path: 'cordova/plugin/CaptureImageOptions'
-        },
-        CaptureVideoOptions: {
-            path: 'cordova/plugin/CaptureVideoOptions'
-        },
-        CompassHeading:{
-            path: 'cordova/plugin/CompassHeading'
-        },
-        CompassError:{
-            path: 'cordova/plugin/CompassError'
-        },
-        ConfigurationData: {
-            path: 'cordova/plugin/ConfigurationData'
-        },
-        Connection: {
-            path: 'cordova/plugin/Connection'
-        },
-        Contact: {
-            path: 'cordova/plugin/Contact'
-        },
-        ContactAddress: {
-            path: 'cordova/plugin/ContactAddress'
-        },
-        ContactError: {
-            path: 'cordova/plugin/ContactError'
-        },
-        ContactField: {
-            path: 'cordova/plugin/ContactField'
-        },
-        ContactFindOptions: {
-            path: 'cordova/plugin/ContactFindOptions'
-        },
-        ContactName: {
-            path: 'cordova/plugin/ContactName'
-        },
-        ContactOrganization: {
-            path: 'cordova/plugin/ContactOrganization'
-        },
-        Coordinates: {
-            path: 'cordova/plugin/Coordinates'
-        },
-        DirectoryEntry: {
-            path: 'cordova/plugin/DirectoryEntry'
-        },
-        DirectoryReader: {
-            path: 'cordova/plugin/DirectoryReader'
-        },
-        Entry: {
-            path: 'cordova/plugin/Entry'
-        },
-        File: {
-            path: 'cordova/plugin/File'
-        },
-        FileEntry: {
-            path: 'cordova/plugin/FileEntry'
-        },
-        FileError: {
-            path: 'cordova/plugin/FileError'
-        },
-        FileReader: {
-            path: 'cordova/plugin/FileReader'
-        },
-        FileSystem: {
-            path: 'cordova/plugin/FileSystem'
-        },
-        FileTransfer: {
-            path: 'cordova/plugin/FileTransfer'
-        },
-        FileTransferError: {
-            path: 'cordova/plugin/FileTransferError'
-        },
-        FileUploadOptions: {
-            path: 'cordova/plugin/FileUploadOptions'
-        },
-        FileUploadResult: {
-            path: 'cordova/plugin/FileUploadResult'
-        },
-        FileWriter: {
-            path: 'cordova/plugin/FileWriter'
-        },
-        Flags: {
-            path: 'cordova/plugin/Flags'
-        },
-        LocalFileSystem: {
-            path: 'cordova/plugin/LocalFileSystem'
-        },
-        Media: {
-            path: 'cordova/plugin/Media'
-        },
-        MediaError: {
-            path: 'cordova/plugin/MediaError'
-        },
-        MediaFile: {
-            path: 'cordova/plugin/MediaFile'
-        },
-        MediaFileData:{
-            path: 'cordova/plugin/MediaFileData'
-        },
-        Metadata:{
-            path: 'cordova/plugin/Metadata'
-        },
-        Position: {
-            path: 'cordova/plugin/Position'
-        },
-        PositionError: {
-            path: 'cordova/plugin/PositionError'
-        },
-        ProgressEvent: {
-            path: 'cordova/plugin/ProgressEvent'
-        },
-        requestFileSystem:{
-            path: 'cordova/plugin/requestFileSystem'
-        },
-        resolveLocalFileSystemURI:{
-            path: 'cordova/plugin/resolveLocalFileSystemURI'
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/platform/errgen.js
----------------------------------------------------------------------
diff --git a/lib/platform/errgen.js b/lib/platform/errgen.js
deleted file mode 100644
index 8677cab..0000000
--- a/lib/platform/errgen.js
+++ /dev/null
@@ -1,28 +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.
- */
-
-// required call to kick off the device ready callback
-require('cordova/plugin/errgen/device')
-
-//------------------------------------------------------------------------------
-module.exports = {
-    id:         "errgen",
-    initialize: function() {},
-    objects:    {}
-}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/platform/ios.js
----------------------------------------------------------------------
diff --git a/lib/platform/ios.js b/lib/platform/ios.js
deleted file mode 100644
index e68b52e..0000000
--- a/lib/platform/ios.js
+++ /dev/null
@@ -1,41 +0,0 @@
-module.exports = {
-    id: "ios",
-    initialize:function() {
-        // iOS doesn't allow reassigning / overriding navigator.geolocation object.
-        // So clobber its methods here instead :)
-        var geo = require('cordova/plugin/geolocation');
-        
-        navigator.geolocation.getCurrentPosition = geo.getCurrentPosition;
-        navigator.geolocation.watchPosition = geo.watchPosition;
-        navigator.geolocation.clearWatch = geo.clearWatch;
-    },
-    objects: {
-        File: { // exists natively, override
-            path: "cordova/plugin/File"
-        },
-        MediaError: { // exists natively, override
-            path: "cordova/plugin/MediaError"
-        },
-        device: {
-            path: 'cordova/plugin/ios/device'
-        },
-        console: {
-            path: 'cordova/plugin/ios/console'
-        }
-    },
-    merges:{
-        Entry:{
-            path: "cordova/plugin/ios/Entry"
-        },
-        FileReader:{
-            path: "cordova/plugin/ios/FileReader"
-        },
-        navigator:{
-            children:{
-                notification:{
-                    path:"cordova/plugin/ios/notification"
-                }
-            }
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/platform/playbook.js
----------------------------------------------------------------------
diff --git a/lib/platform/playbook.js b/lib/platform/playbook.js
deleted file mode 100644
index 4854f9b..0000000
--- a/lib/platform/playbook.js
+++ /dev/null
@@ -1,16 +0,0 @@
-module.exports = {
-    id: "playbook",
-    initialize:function() {},
-    objects: {
-        navigator: {
-            children: {
-                device: {
-                    path: "cordova/plugin/playbook/device"
-                }
-            }
-        },
-        device: {
-            path: "cordova/plugin/playbook/device"
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/platform/wp7.js
----------------------------------------------------------------------
diff --git a/lib/platform/wp7.js b/lib/platform/wp7.js
deleted file mode 100644
index f2d74b4..0000000
--- a/lib/platform/wp7.js
+++ /dev/null
@@ -1,16 +0,0 @@
-module.exports = {
-    id: "wp7",
-    initialize:function() {},
-    objects: {
-        navigator: {
-            children: {
-                device: {
-                    path: "cordova/plugin/wp7/device"
-                }
-            }
-        },
-        device: {
-            path: 'cordova/plugin/wp7/device'
-        }
-    }
-};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/playbook/exec.js
----------------------------------------------------------------------
diff --git a/lib/playbook/exec.js b/lib/playbook/exec.js
new file mode 100644
index 0000000..ff2cbd9
--- /dev/null
+++ b/lib/playbook/exec.js
@@ -0,0 +1,56 @@
+/**
+ * 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
+ *      Asynchrounous: 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
+ */
+
+module.exports = function(success, fail, service, action, args) {
+    try {
+        var playbook = require('cordova/plugin/playbook/manager'),
+            cordova = require('cordova'),
+            v = playbook.exec(success, fail, service, action, args);
+
+        // If status is OK, then return value back to caller
+        if (v.status == cordova.callbackStatus.OK) {
+
+            // If there is a success callback, then call it now with returned value
+            if (success) {
+                try {
+                    success(v.message);
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+cordova.callbackId+" = "+e);
+                }
+
+            }
+            return v.message;
+        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
+
+        } else {
+            // If error, then display error
+            console.log("Error: Status="+v.status+" Message="+v.message);
+
+            // If there is a fail callback, then call it now with returned value
+            if (fail) {
+                try {
+                    fail(v.message);
+                }
+                catch (e) {
+                    console.log("Error in error callback: "+cordova.callbackId+" = "+e);
+                }
+            }
+            return null;
+        }
+    } catch (e) {
+        alert("Error: "+e);
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/playbook/platform.js
----------------------------------------------------------------------
diff --git a/lib/playbook/platform.js b/lib/playbook/platform.js
new file mode 100644
index 0000000..4854f9b
--- /dev/null
+++ b/lib/playbook/platform.js
@@ -0,0 +1,16 @@
+module.exports = {
+    id: "playbook",
+    initialize:function() {},
+    objects: {
+        navigator: {
+            children: {
+                device: {
+                    path: "cordova/plugin/playbook/device"
+                }
+            }
+        },
+        device: {
+            path: "cordova/plugin/playbook/device"
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/playbook/plugin/playbook/device.js
----------------------------------------------------------------------
diff --git a/lib/playbook/plugin/playbook/device.js b/lib/playbook/plugin/playbook/device.js
new file mode 100644
index 0000000..90ec376
--- /dev/null
+++ b/lib/playbook/plugin/playbook/device.js
@@ -0,0 +1,23 @@
+var me = {},
+    exec = require('cordova/exec'),
+    channel = require('cordova/channel');
+
+exec(
+    function (device) {
+        me.platform = device.platform;
+        me.version  = device.version;
+        me.name     = device.name;
+        me.uuid     = device.uuid;
+        me.cordova  = device.cordova;
+
+        channel.onCordovaInfoReady.fire();
+    },
+    function (e) {
+        console.log("error initializing cordova: " + e);
+    },
+    "Device",
+    "getDeviceInfo",
+    []
+);
+
+module.exports = me;

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/playbook/plugin/playbook/manager.js
----------------------------------------------------------------------
diff --git a/lib/playbook/plugin/playbook/manager.js b/lib/playbook/plugin/playbook/manager.js
new file mode 100644
index 0000000..df19a9a
--- /dev/null
+++ b/lib/playbook/plugin/playbook/manager.js
@@ -0,0 +1,321 @@
+var webworks = require('cordova/plugin/webworks/manager'),
+    cordova = require('cordova'),
+    /**
+     * Private list of HTML 5 audio objects, indexed by the Cordova media object ids
+     */
+    audioObjects = {},
+    retInvalidAction = function () {
+        return { "status" : cordova.callbackStatus.INVALID_ACTION, "message" : "Action not found" };
+    },
+    retAsyncCall = function () {
+        return { "status" : cordova.callbackStatus.NO_RESULT, "message" : "WebWorks Is On It" };
+    },
+    batteryAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            if (action === 'start') {
+                // Register one listener to each of level and state change
+                // events using WebWorks API.
+                blackberry.system.event.deviceBatteryStateChange(function(state) {
+                    var me = navigator.battery;
+                    // state is either CHARGING or UNPLUGGED
+                    if (state === 2 || state === 3) {
+                        var info = {
+                            "level" : me._level,
+                            "isPlugged" : state === 2
+                        };
+
+                        if (me._isPlugged !== info.isPlugged
+                                && typeof win === 'function') {
+                            win(info);
+                        }
+                    }
+                });
+                blackberry.system.event.deviceBatteryLevelChange(function(level) {
+                    var me = navigator.battery;
+                    if (level != me._level && typeof win === 'function') {
+                        win({'level' : level, 'isPlugged' : me._isPlugged});
+                    }
+                });
+            } else if (action === 'stop') {
+                // Unregister battery listeners.
+                blackberry.system.event.deviceBatteryStateChange(null);
+                blackberry.system.event.deviceBatteryLevelChange(null);
+            } else {
+                return retInvalidAction();
+            }
+        }
+    },
+    cameraAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            if (action === 'takePicture') {
+                blackberry.media.camera.takePicture(win, fail, fail);
+                return retAsyncCall();
+            }
+            else {
+                return retInvalidAction();
+            }
+        }
+    },
+    deviceAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            if (action === 'getDeviceInfo') {
+                return {"status" : cordova.callbackStatus.OK,
+                        "message" : {
+                            "version" : blackberry.system.softwareVersion,
+                            "name" : blackberry.system.model,
+                            "uuid" : blackberry.identity.PIN,
+                            "platform" : "PlayBook",
+                            "cordova" : "1.4.1"
+                        }
+                };
+            }
+            return retInvalidAction();
+        }
+    },
+    loggerAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            if (action === 'log') {
+                console.log(args);
+                return {"status" : cordova.callbackStatus.OK,
+                        "message" : 'Message logged to console: ' + args};
+            }
+            else {
+                return retInvalidAction();
+            }
+        }
+    },
+    mediaAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            if (!args.length) {
+                return {"status" : 9, "message" : "Media Object id was not sent in arguments"};
+            }
+
+            var id = args[0],
+                audio = audioObjects[id],
+                result;
+
+            switch (action) {
+            case 'startPlayingAudio':
+                if (args.length === 1) {
+                    result = {"status" : 9, "message" : "Media source argument not found"};
+
+                }
+
+                if (audio) {
+                    audio.pause();
+                    audioObjects[id] = undefined;
+                }
+
+                audio = audioObjects[id] = new Audio(args[1]);
+                audio.play();
+
+                result = {"status" : 1, "message" : "Audio play started" };
+                break;
+            case 'stopPlayingAudio':
+                if (!audio) {
+                    return {"status" : 2, "message" : "Audio Object has not been initialized"};
+                }
+
+                audio.pause();
+                audioObjects[id] = undefined;
+
+                result = {"status" : 1, "message" : "Audio play stopped" };
+                break;
+            case 'seekToAudio':
+                if (!audio) {
+                    result = {"status" : 2, "message" : "Audio Object has not been initialized"};
+                } else if (args.length === 1) {
+                    result = {"status" : 9, "message" : "Media seek time argument not found"};
+                } else {
+                    try {
+                        audio.currentTime = args[1];
+                    } catch (e) {
+                        console.log('Error seeking audio: ' + e);
+                        return {"status" : 3, "message" : "Error seeking audio: " + e};
+                    }
+
+                    result = {"status" : 1, "message" : "Seek to audio succeeded" };
+                }
+                break;
+            case 'pausePlayingAudio':
+                if (!audio) {
+                    return {"status" : 2, "message" : "Audio Object has not been initialized"};
+                }
+
+                audio.pause();
+
+                result = {"status" : 1, "message" : "Audio paused" };
+                break;
+            case 'getCurrentPositionAudio':
+                if (!audio) {
+                    return {"status" : 2, "message" : "Audio Object has not been initialized"};
+                }
+
+                result = {"status" : 1, "message" : audio.currentTime };
+                break;
+            case 'getDuration':
+                if (!audio) {
+                    return {"status" : 2, "message" : "Audio Object has not been initialized"};
+                }
+
+                result = {"status" : 1, "message" : audio.duration };
+                break;
+            case 'startRecordingAudio':
+                if (args.length <= 1) {
+                    result = {"status" : 9, "message" : "Media start recording, insufficient arguments"};
+                }
+
+                blackberry.media.microphone.record(args[1], win, fail);
+                result = retAsyncCall();
+                break;
+            case 'stopRecordingAudio':
+                break;
+            case 'release':
+                if (audio) {
+                    audioObjects[id] = undefined;
+                    audio.src = undefined;
+                    //delete audio;
+                }
+
+                result = {"status" : 1, "message" : "Media resources released"};
+                break;
+            default:
+                result = retInvalidAction();
+            }
+
+            return result;
+        }
+    },
+    mediaCaptureAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            var limit = args[0],
+                pictureFiles = [],
+                captureMethod;
+
+            function captureCB(filePath) {
+                var mediaFile;
+
+                if (filePath) {
+                    mediaFile = new MediaFile();
+                    mediaFile.fullPath = filePath;
+                    pictureFiles.push(mediaFile);
+                }
+
+                if (limit > 0) {
+                    limit--;
+                    blackberry.media.camera[captureMethod](win, fail, fail);
+                    return;
+                }
+
+                win(pictureFiles);
+
+                return retAsyncCall();
+            }
+
+            switch (action) {
+                case 'getSupportedAudioModes':
+                case 'getSupportedImageModes':
+                case 'getSupportedVideoModes':
+                    return {"status": cordova.callbackStatus.OK, "message": []};
+                case 'captureImage':
+                    captureMethod = "takePicture";
+                    captureCB();
+                    break;
+                case 'captureVideo':
+                    captureMethod = "takeVideo";
+                    captureCB();
+                    break;
+                case 'captureAudio':
+                    return {"status": cordova.callbackStatus.INVALID_ACTION, "message": "captureAudio is not currently supported"};
+            }
+
+            return retAsyncCall();
+        }
+    },
+    networkAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            if (action !== 'getConnectionInfo') {
+                return retInvalidAction();
+            }
+
+            var connectionType = require("cordova/plugin/Connection").NONE,
+                eventType = "offline",
+                callbackID,
+                request;
+
+            /**
+             * For PlayBooks, we currently only have WiFi connections, so return WiFi if there is
+             * any access at all.
+             * TODO: update if/when PlayBook gets other connection types...
+             */
+            if (blackberry.system.hasDataCoverage()) {
+                connectionType = require("cordova/plugin/Connection").WIFI;
+                eventType = "online";
+            }
+
+            //Register an event handler for the networkChange event
+            callbackID = blackberry.events.registerEventHandler("networkChange", win);
+
+            //pass our callback id down to our network extension
+            request = new blackberry.transport.RemoteFunctionCall("org/apache/cordova/getConnectionInfo");
+            request.addParam("networkStatusChangedID", callbackID);
+            request.makeSyncCall();
+
+            return { "status": cordova.callbackStatus.OK, "message": {"type": connectionType, "event": eventType } };
+        }
+    },
+    notificationAPI = {
+        execute: function (webWorksResult, action, args, win, fail) {
+            if (args.length !== 3) {
+              return {"status" : 9, "message" : "Notification action - " + action + " arguments not found"};
+
+            }
+
+            //Unpack and map the args
+            var msg = args[0],
+                title = args[1],
+                btnLabel = args[2],
+                btnLabels;
+
+            switch (action) {
+            case 'alert':
+                blackberry.ui.dialog.customAskAsync.apply(this, [ msg, [ btnLabel ], win, { "title" : title } ]);
+                return retAsyncCall();
+            case 'confirm':
+                btnLabels = btnLabel.split(",");
+                blackberry.ui.dialog.customAskAsync.apply(this, [msg, btnLabels, win, {"title" : title} ]);
+                return retAsyncCall();
+            }
+            return retInvalidAction();
+
+        }
+    },
+    plugins = {
+        'Battery' : batteryAPI,
+        'Camera' : cameraAPI,
+        'Device' : deviceAPI,
+        'Logger' : loggerAPI,
+        'Media' : mediaAPI,
+        'Capture' : mediaCaptureAPI,
+        'Network Status' : networkAPI,
+        'Notification' : notificationAPI
+    };
+
+module.exports = {
+    exec: function (win, fail, clazz, action, args) {
+        var wwResult = webworks.exec(win, fail, clazz, action, args);
+
+        //We got a sync result or a not found from WW that we can pass on to get a native mixin
+        //For async calls there's nothing to do
+        if ((wwResult.status === cordova.callbackStatus.OK ||
+          wwResult.status === cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION) &&
+          plugins[clazz]) {
+            return plugins[clazz].execute(wwResult.message, action, args, win, fail);
+        }
+
+        return wwResult;
+    },
+    resume: function () {},
+    pause: function () {},
+    destroy: function () {}
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/plugin/Acceleration.js
----------------------------------------------------------------------
diff --git a/lib/plugin/Acceleration.js b/lib/plugin/Acceleration.js
deleted file mode 100644
index f02d24b..0000000
--- a/lib/plugin/Acceleration.js
+++ /dev/null
@@ -1,8 +0,0 @@
-var Acceleration = function(x, y, z) {
-  this.x = x;
-  this.y = y;
-  this.z = z;
-  this.timestamp = new Date().getTime();
-};
-
-module.exports = Acceleration;

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/e50b7ef6/lib/plugin/Camera.js
----------------------------------------------------------------------
diff --git a/lib/plugin/Camera.js b/lib/plugin/Camera.js
deleted file mode 100644
index 5e58af8..0000000
--- a/lib/plugin/Camera.js
+++ /dev/null
@@ -1,84 +0,0 @@
-var exec = require('cordova/exec'),
-    Camera = require('cordova/plugin/CameraConstants');
-
-var cameraExport = {};
-
-// Tack on the Camera Constants to the base camera plugin.
-for (var key in Camera) {
-    cameraExport[key] = Camera[key];
-}
-
-/**
- * Gets a picture from source defined by "options.sourceType", and returns the
- * image as defined by the "options.destinationType" option.
-
- * The defaults are sourceType=CAMERA and destinationType=FILE_URL.
- *
- * @param {Function} successCallback
- * @param {Function} errorCallback
- * @param {Object} options
- */
-cameraExport.getPicture = function(successCallback, errorCallback, options) {
-    // successCallback required
-    if (typeof successCallback != "function") {
-        console.log("Camera Error: successCallback is not a function");
-        return;
-    }
-
-    // errorCallback optional
-    if (errorCallback && (typeof errorCallback != "function")) {
-        console.log("Camera Error: errorCallback is not a function");
-        return;
-    }
-
-    var quality = 50;
-    if (options && typeof options.quality == "number") {
-        quality = options.quality;
-    } else if (options && typeof options.quality == "string") {
-        var qlity = parseInt(options.quality, 10);
-        if (isNaN(qlity) === false) {
-            quality = qlity.valueOf();
-        }
-    }
-
-    var destinationType = Camera.DestinationType.FILE_URI;
-    if (typeof options.destinationType == "number") {
-        destinationType = options.destinationType;
-    }
-
-    var sourceType = Camera.PictureSourceType.CAMERA;
-    if (typeof options.sourceType == "number") {
-        sourceType = options.sourceType;
-    }
-
-    var targetWidth = -1;
-    if (typeof options.targetWidth == "number") {
-        targetWidth = options.targetWidth;
-    } else if (typeof options.targetWidth == "string") {
-        var width = parseInt(options.targetWidth, 10);
-        if (isNaN(width) === false) {
-            targetWidth = width.valueOf();
-        }
-    }
-
-    var targetHeight = -1;
-    if (typeof options.targetHeight == "number") {
-        targetHeight = options.targetHeight;
-    } else if (typeof options.targetHeight == "string") {
-        var height = parseInt(options.targetHeight, 10);
-        if (isNaN(height) === false) {
-            targetHeight = height.valueOf();
-        }
-    }
-
-    var encodingType = Camera.EncodingType.JPEG;
-    if (typeof options.encodingType == "number") {
-        encodingType = options.encodingType;
-    }
-    // TODO: parse MediaType
-    // TODO: enable allow edit?
-
-    exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType]);
-}
-
-module.exports = cameraExport;