You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/03/25 22:53:29 UTC

[6/6] git commit: 2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added androids local.properties to gitignore.

2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added androids local.properties to gitignore.


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

Branch: refs/heads/2.6.x
Commit: 37b92ff47d532490f67a635e0f3b011c03be8eb1
Parents: 50e8e4e
Author: Fil Maj <ma...@gmail.com>
Authored: Mon Mar 25 14:52:11 2013 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Mon Mar 25 14:52:11 2013 -0700

----------------------------------------------------------------------
 .gitignore                                         |    2 +-
 lib/cordova-android/VERSION                        |    2 +-
 lib/cordova-android/bin/create                     |   16 +-
 .../bin/templates/cordova/appinfo.jar              |  Bin 1574 -> 1574 bytes
 .../bin/templates/project/assets/www/index.html    |    2 +-
 lib/cordova-android/bin/update                     |  139 ++++
 lib/cordova-android/bin/update.bat                 |   32 +
 lib/cordova-android/bin/update.js                  |  193 ++++++
 .../framework/assets/js/cordova.android.js         |  474 +++++++++++---
 .../framework/assets/www/index.html                |    2 +-
 .../src/org/apache/cordova/AudioHandler.java       |    6 +-
 .../src/org/apache/cordova/AudioPlayer.java        |   15 +-
 .../src/org/apache/cordova/CameraLauncher.java     |   16 +-
 .../framework/src/org/apache/cordova/Capture.java  |   14 +-
 .../framework/src/org/apache/cordova/Config.java   |   10 +
 .../src/org/apache/cordova/CordovaArgs.java        |    5 +-
 .../org/apache/cordova/CordovaChromeClient.java    |    2 +-
 .../src/org/apache/cordova/CordovaWebView.java     |  124 +---
 .../org/apache/cordova/CordovaWebViewClient.java   |  103 ++--
 .../framework/src/org/apache/cordova/Device.java   |    2 +-
 .../framework/src/org/apache/cordova/DroidGap.java |   13 +-
 .../src/org/apache/cordova/FileHelper.java         |  142 ++++
 .../src/org/apache/cordova/FileTransfer.java       |   81 ++-
 .../src/org/apache/cordova/FileUtils.java          |  350 ++++-------
 .../src/org/apache/cordova/GeoBroker.java          |    2 +-
 .../cordova/IceCreamCordovaWebViewClient.java      |   16 +-
 .../src/org/apache/cordova/InAppBrowser.java       |  135 ++++-
 .../src/org/apache/cordova/JSONUtils.java          |   24 +
 .../org/apache/cordova/NativeToJsMessageQueue.java |   13 +-
 .../src/org/apache/cordova/Notification.java       |  167 ++++-
 .../org/apache/cordova/api/CallbackContext.java    |    9 +
 .../src/org/apache/cordova/api/CordovaPlugin.java  |   18 +-
 .../src/org/apache/cordova/api/PluginManager.java  |   23 +-
 .../src/org/apache/cordova/api/PluginResult.java   |   11 +-
 lib/cordova-blackberry/bin/create                  |   21 +-
 .../bin/templates/project/www/index.html           |    4 +-
 .../ext/src/org/apache/cordova/util/FileUtils.java |   33 +-
 .../javascript/cordova.blackberry.js               |  365 +++++++++--
 .../CordovaLib/Classes/CDVAvailability.h           |   19 +-
 lib/cordova-ios/CordovaLib/Classes/CDVCamera.h     |    4 +-
 lib/cordova-ios/CordovaLib/Classes/CDVCamera.m     |   53 ++
 lib/cordova-ios/CordovaLib/Classes/CDVCapture.m    |   10 +-
 .../CordovaLib/Classes/CDVCommandDelegate.h        |    1 -
 .../CordovaLib/Classes/CDVCommandDelegateImpl.m    |   22 +-
 .../CordovaLib/Classes/CDVCommandQueue.h           |    8 +-
 .../CordovaLib/Classes/CDVCommandQueue.m           |   17 +-
 .../CordovaLib/Classes/CDVConfigParser.m           |    2 +-
 lib/cordova-ios/CordovaLib/Classes/CDVConnection.m |   12 +-
 lib/cordova-ios/CordovaLib/Classes/CDVContact.m    |   32 +-
 lib/cordova-ios/CordovaLib/Classes/CDVContacts.h   |   14 +-
 lib/cordova-ios/CordovaLib/Classes/CDVContacts.m   |  490 +++++++-------
 lib/cordova-ios/CordovaLib/Classes/CDVEcho.m       |    7 +
 lib/cordova-ios/CordovaLib/Classes/CDVExif.h       |   43 ++
 lib/cordova-ios/CordovaLib/Classes/CDVFile.h       |    2 +
 lib/cordova-ios/CordovaLib/Classes/CDVFile.m       |  285 +++++----
 .../CordovaLib/Classes/CDVFileTransfer.h           |    8 +-
 .../CordovaLib/Classes/CDVFileTransfer.m           |   51 +-
 .../CordovaLib/Classes/CDVGlobalization.m          |   62 +-
 .../CordovaLib/Classes/CDVInAppBrowser.h           |    3 +
 .../CordovaLib/Classes/CDVInAppBrowser.m           |   41 +-
 .../CordovaLib/Classes/CDVInvokedUrlCommand.h      |    6 +-
 .../CordovaLib/Classes/CDVJpegHeaderWriter.h       |   60 ++
 .../CordovaLib/Classes/CDVJpegHeaderWriter.m       |  472 +++++++++++++
 .../CordovaLib/Classes/CDVLocalStorage.h           |    4 +-
 .../CordovaLib/Classes/CDVLocalStorage.m           |   36 +-
 lib/cordova-ios/CordovaLib/Classes/CDVLocation.h   |    8 +-
 lib/cordova-ios/CordovaLib/Classes/CDVLocation.m   |   24 +-
 .../CordovaLib/Classes/CDVNotification.h           |    1 +
 .../CordovaLib/Classes/CDVNotification.m           |   89 ++-
 lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h     |    8 +-
 lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m     |    9 +-
 .../CordovaLib/Classes/CDVPluginResult.h           |    7 +
 .../CordovaLib/Classes/CDVPluginResult.m           |   57 ++-
 .../CordovaLib/Classes/CDVReachability.m           |   28 +-
 lib/cordova-ios/CordovaLib/Classes/CDVSound.m      |   21 +-
 .../CordovaLib/Classes/CDVSplashScreen.h           |    3 +-
 .../CordovaLib/Classes/CDVSplashScreen.m           |  176 +++--
 .../CordovaLib/Classes/CDVURLProtocol.m            |   12 +-
 .../CordovaLib/Classes/CDVUserAgentUtil.m          |    2 +-
 .../CordovaLib/Classes/CDVViewController.h         |   10 +-
 .../CordovaLib/Classes/CDVViewController.m         |  140 ++++-
 .../CordovaLib/Classes/CDVWebViewDelegate.m        |   30 +-
 lib/cordova-ios/CordovaLib/Classes/NSData+Base64.m |   19 +-
 .../CordovaLib/Classes/NSDictionary+Extensions.m   |    2 +-
 .../CordovaLib.xcodeproj/project.pbxproj           |   14 +
 lib/cordova-ios/CordovaLib/VERSION                 |    2 +-
 lib/cordova-ios/CordovaLib/cordova.ios.js          |  521 ++++++++++++---
 .../CordovaLibTests/CDVFakeFileManager.h           |    2 +-
 .../CordovaLibTests/CDVFileTransferTests.m         |   12 +-
 .../CordovaLibTests/CDVLocalStorageTests.m         |   24 +-
 lib/cordova-ios/CordovaLibTests/CDVUserAgentTest.m |    4 +-
 lib/cordova-ios/CordovaLibTests/CDVWebViewTest.m   |    4 +-
 .../CordovaLibTests/CordovaLibApp/config.xml       |    6 +-
 .../CordovaTests.xcodeproj/project.pbxproj         |    6 +
 lib/cordova-ios/CordovaLibTests/ExifTests.h        |   27 +
 lib/cordova-ios/CordovaLibTests/ExifTests.m        |  155 +++++
 lib/cordova-ios/RELEASENOTES.md                    |   66 ++-
 .../project/__TESTING__.xcodeproj/project.pbxproj  |    6 +-
 .../project/__TESTING__/Classes/AppDelegate.m      |    6 +-
 .../Resources/splash/Default-568h@2x~iphone.png    |  Bin 29944 -> 34225 bytes
 .../Resources/splash/Default-Landscape@2x~ipad.png |  Bin 75573 -> 77300 bytes
 .../Resources/splash/Default-Landscape~ipad.png    |  Bin 33147 -> 34935 bytes
 .../Resources/splash/Default-Portrait@2x~ipad.png  |  Bin 74097 -> 76546 bytes
 .../Resources/splash/Default-Portrait~ipad.png     |  Bin 32666 -> 34278 bytes
 .../bin/templates/project/__TESTING__/config.xml   |   20 +-
 .../bin/templates/project/www/index.html           |    2 +-
 .../guides/Cordova Plugin Upgrade Guide.md         |    6 +
 lib/cordova-ios/hooks/pre-commit                   |    6 +
 package.json                                       |    2 +-
 109 files changed, 4423 insertions(+), 1464 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 3abe651..b31c8bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,8 +6,8 @@ spec/fixtures/projects/native
 spec/fixtures/projects/cordova
 lib/cordova-android/framework/bin
 lib/cordova-android/framework/gen
+lib/cordova-android/framework/local.properties
 .idea/*
 spec/fixtures/*
 .gitcore
 *.jar
-lib/*

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/VERSION
----------------------------------------------------------------------
diff --git a/lib/cordova-android/VERSION b/lib/cordova-android/VERSION
index 437459c..f47de85 100644
--- a/lib/cordova-android/VERSION
+++ b/lib/cordova-android/VERSION
@@ -1 +1 @@
-2.5.0
+2.6.0rc1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/create
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/create b/lib/cordova-android/bin/create
index ea214ac..2eae82b 100755
--- a/lib/cordova-android/bin/create
+++ b/lib/cordova-android/bin/create
@@ -59,10 +59,10 @@ function on_exit {
 }
 
 function createAppInfoJar {
-    (cd "$BUILD_PATH"/bin/templates/cordova/ApplicationInfo &&
-     javac ApplicationInfo.java &&
-     jar -cfe ../appinfo.jar ApplicationInfo ApplicationInfo.class
-    )
+    pushd "$BUILD_PATH"/bin/templates/cordova/ApplicationInfo > /dev/null
+    javac ApplicationInfo.java
+    jar -cfe ../appinfo.jar ApplicationInfo ApplicationInfo.class
+    popd > /dev/null
 }
 
 function on_error {
@@ -108,7 +108,7 @@ fi
 # if this a distribution release no need to build a jar
 if [ ! -e "$BUILD_PATH"/cordova-$VERSION.jar ] && [ -d "$BUILD_PATH"/framework ]
 then
-# update the cordova-android framework for the desired target
+    # update the cordova-android framework for the desired target
     "$ANDROID_BIN" update project --target $TARGET --path "$BUILD_PATH"/framework &> /dev/null
 
     if [ ! -e "$BUILD_PATH"/framework/libs/commons-codec-1.7.jar ]; then
@@ -121,8 +121,10 @@ then
         rm commons-codec-1.7-bin.zip && rm -rf commons-codec-1.7
     fi
 
-# compile cordova.js and cordova.jar
-    (cd "$BUILD_PATH"/framework && ant jar &> /dev/null )
+    # compile cordova.js and cordova.jar
+    pushd "$BUILD_PATH"/framework > /dev/null
+    ant jar > /dev/null
+    popd > /dev/null
 fi
 
 # create new android project

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/templates/cordova/appinfo.jar
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/templates/cordova/appinfo.jar b/lib/cordova-android/bin/templates/cordova/appinfo.jar
index fff4d0f..7f8ac60 100644
Binary files a/lib/cordova-android/bin/templates/cordova/appinfo.jar and b/lib/cordova-android/bin/templates/cordova/appinfo.jar differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/templates/project/assets/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/templates/project/assets/www/index.html b/lib/cordova-android/bin/templates/project/assets/www/index.html
index b8c0535..5596f62 100644
--- a/lib/cordova-android/bin/templates/project/assets/www/index.html
+++ b/lib/cordova-android/bin/templates/project/assets/www/index.html
@@ -33,7 +33,7 @@
                 <p class="event received">Device is Ready</p>
             </div>
         </div>
-        <script type="text/javascript" src="cordova-2.5.0.js"></script>
+        <script type="text/javascript" src="cordova-2.6.0rc1.js"></script>
         <script type="text/javascript" src="js/index.js"></script>
         <script type="text/javascript">
             app.initialize();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/update
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/update b/lib/cordova-android/bin/update
new file mode 100755
index 0000000..0e86886
--- /dev/null
+++ b/lib/cordova-android/bin/update
@@ -0,0 +1,139 @@
+#! /bin/bash
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you under the Apache License, Version 2.0 (the
+#       "License"); you may not use this file except in compliance
+#       with the License.  You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#       Unless required by applicable law or agreed to in writing,
+#       software distributed under the License is distributed on an
+#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#       KIND, either express or implied.  See the License for the
+#       specific language governing permissions and limitations
+#       under the License.
+#
+# update a cordova/android project's command line tools
+# 
+# USAGE
+#   ./update [path]
+#
+
+set -e
+
+if [ -z "$1" ] || [ "$1" == "-h" ]
+then
+    echo 'usage: update path'
+    echo "Make sure the Android SDK tools folder is in your PATH!"
+    exit 0
+fi
+
+BUILD_PATH="$( cd "$( dirname "$0" )/.." && pwd )"
+VERSION=$(cat "$BUILD_PATH"/VERSION)
+
+PROJECT_PATH="${1:-'./example'}"
+
+if [ ! -d "$PROJECT_PATH" ]
+then
+    echo "The project path has to exist for it to be updated"
+    exit 0
+fi
+
+
+# cleanup after exit and/or on error
+function on_exit {
+    if [ -f "$BUILD_PATH"/framework/assets/www/cordova-$VERSION.js ]
+    then
+        rm "$BUILD_PATH"/framework/assets/www/cordova-$VERSION.js
+    fi
+    if [ -f "$BUILD_PATH"/framework/cordova-$VERSION.jar ]
+    then
+        rm "$BUILD_PATH"/framework/cordova-$VERSION.jar
+    fi
+}
+
+function createAppInfoJar {
+    (cd "$BUILD_PATH"/bin/templates/cordova/ApplicationInfo &&
+     javac ApplicationInfo.java &&
+     jar -cfe ../appinfo.jar ApplicationInfo ApplicationInfo.class
+    )
+}
+
+function on_error {
+    echo "An unexpected error occurred: $previous_command exited with $?"
+    echo "Deleting project..."
+    [ -d "$PROJECT_PATH" ] && rm -rf "$PROJECT_PATH"
+    exit 1
+}
+
+function replace {
+    local pattern=$1
+    local filename=$2
+    # Mac OS X requires -i argument
+    if [[ "$OSTYPE" =~ "darwin" ]]
+    then
+        /usr/bin/sed -i '' -e $pattern "$filename"
+    elif [[ "$OSTYPE" =~ "linux" ]]
+    then
+        /bin/sed -i -e $pattern "$filename"
+    fi
+}
+
+# we do not want the script to silently fail
+trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
+trap on_error ERR
+trap on_exit EXIT
+
+ANDROID_BIN="${ANDROID_BIN:=$( which android )}"
+
+TARGET=$("$ANDROID_BIN" list targets | grep id: | tail -1 | cut -f 2 -d ' ' )
+API_LEVEL=$("$ANDROID_BIN" list target | grep "API level:" | tail -n 1 | cut -f 2 -d ':' | tr -d ' ')
+
+# check that build targets exist
+if [ -z "$TARGET" ] || [ -z "$API_LEVEL" ]
+then
+    echo "No Android Targets are installed. Please install at least one via the android SDK"
+    exit 1
+fi
+
+# if this a distribution release no need to build a jar
+if [ ! -e "$BUILD_PATH"/cordova-$VERSION.jar ] && [ -d "$BUILD_PATH"/framework ]
+then
+# update the cordova-android framework for the desired target
+    "$ANDROID_BIN" update project --target $TARGET --path "$BUILD_PATH"/framework &> /dev/null
+
+    if [ ! -e "$BUILD_PATH"/framework/libs/commons-codec-1.7.jar ]; then
+        # Use curl to get the jar (TODO: Support Apache Mirrors)
+        curl -OL http://archive.apache.org/dist/commons/codec/binaries/commons-codec-1.7-bin.zip &> /dev/null
+        unzip commons-codec-1.7-bin.zip &> /dev/null
+        mkdir -p "$BUILD_PATH"/framework/libs
+        cp commons-codec-1.7/commons-codec-1.7.jar "$BUILD_PATH"/framework/libs
+        # cleanup yo
+        rm commons-codec-1.7-bin.zip && rm -rf commons-codec-1.7
+    fi
+
+# compile cordova.js and cordova.jar
+    (cd "$BUILD_PATH"/framework && ant jar &> /dev/null )
+fi
+
+# copy cordova.js, cordova.jar and res/xml
+if [ -d "$BUILD_PATH"/framework ]
+then
+    cp "$BUILD_PATH"/framework/assets/www/cordova-$VERSION.js "$PROJECT_PATH"/assets/www/cordova-$VERSION.js
+    cp "$BUILD_PATH"/framework/cordova-$VERSION.jar "$PROJECT_PATH"/libs/cordova-$VERSION.jar
+else
+    cp "$BUILD_PATH"/cordova-$VERSION.js "$PROJECT_PATH"/assets/www/cordova-$VERSION.js
+    cp "$BUILD_PATH"/cordova-$VERSION.jar "$PROJECT_PATH"/libs/cordova-$VERSION.jar
+fi
+
+# creating cordova folder and copying run/build/log/launch scripts
+cp "$BUILD_PATH"/bin/templates/cordova/appinfo.jar "$PROJECT_PATH"/cordova/appinfo.jar
+cp "$BUILD_PATH"/bin/templates/cordova/cordova "$PROJECT_PATH"/cordova/cordova
+cp "$BUILD_PATH"/bin/templates/cordova/build "$PROJECT_PATH"/cordova/build
+cp "$BUILD_PATH"/bin/templates/cordova/release "$PROJECT_PATH"/cordova/release
+cp "$BUILD_PATH"/bin/templates/cordova/clean "$PROJECT_PATH"/cordova/clean
+cp "$BUILD_PATH"/bin/templates/cordova/log "$PROJECT_PATH"/cordova/log
+cp "$BUILD_PATH"/bin/templates/cordova/run "$PROJECT_PATH"/cordova/run

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/update.bat
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/update.bat b/lib/cordova-android/bin/update.bat
new file mode 100644
index 0000000..a61fd26
--- /dev/null
+++ b/lib/cordova-android/bin/update.bat
@@ -0,0 +1,32 @@
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements.  See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership.  The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License.  You may obtain a copy of the License at
+:: 
+:: http://www.apache.org/licenses/LICENSE-2.0
+:: 
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied.  See the License for the
+:: specific language governing permissions and limitations
+:: under the License.
+
+@ECHO OFF
+IF NOT DEFINED JAVA_HOME GOTO MISSING
+FOR %%X in (java.exe javac.exe ant.bat android.bat) do (
+    SET FOUND=%%~$PATH:X
+    IF NOT DEFINED FOUND GOTO MISSING
+)
+cscript "%~dp0\update.js" %*
+GOTO END
+:MISSING
+ECHO Missing one of the following:
+ECHO JDK: http://java.oracle.com
+ECHO Android SDK: http://developer.android.com
+ECHO Apache ant: http://ant.apache.org
+EXIT /B 1
+:END

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/update.js
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/update.js b/lib/cordova-android/bin/update.js
new file mode 100644
index 0000000..244dcc1
--- /dev/null
+++ b/lib/cordova-android/bin/update.js
@@ -0,0 +1,193 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+/*
+ * create a cordova/android project
+ *
+ * USAGE
+ *  ./update [path]
+ */
+
+var fso = WScript.CreateObject('Scripting.FileSystemObject');
+
+function read(filename) {
+    var fso=WScript.CreateObject("Scripting.FileSystemObject");
+    var f=fso.OpenTextFile(filename, 1);
+    var s=f.ReadAll();
+    f.Close();
+    return s;
+}
+
+function checkTargets(targets) {
+    if(!targets) {
+        WScript.Echo("You do not have any android targets setup. Please create at least one target with the `android` command");
+        WScript.Quit(69);
+    }
+}
+
+function setTarget() {
+    var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s\d+/g);
+    checkTargets(targets);
+    return targets[targets.length - 1].replace(/id: /, ""); // TODO: give users the option to set their target 
+}
+
+function setApiLevel() {
+    var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/API level:\s\d+/g);
+    checkTargets(targets);
+    return targets[targets.length - 1].replace(/API level: /, "");
+}
+
+function write(filename, contents) {
+    var fso=WScript.CreateObject("Scripting.FileSystemObject");
+    var f=fso.OpenTextFile(filename, 2, true);
+    f.Write(contents);
+    f.Close();
+}
+
+function replaceInFile(filename, regexp, replacement) {
+    write(filename, read(filename).replace(regexp, replacement));
+}
+
+function exec(command) {
+    var oShell=shell.Exec(command);
+    while (oShell.Status == 0) {
+        if(!oShell.StdOut.AtEndOfStream) {
+            var line = oShell.StdOut.ReadLine();
+            // XXX: Change to verbose mode 
+            // WScript.StdOut.WriteLine(line);
+        }
+        WScript.sleep(100);
+    }
+}
+
+function createAppInfoJar() {
+    if(!fso.FileExists(ROOT+"\\bin\\templates\\cordova\\appinfo.jar")) {
+        WScript.Echo("Creating appinfo.jar...");
+        var cur = shell.CurrentDirectory;
+        shell.CurrentDirectory = ROOT+"\\bin\\templates\\cordova\\ApplicationInfo";
+        exec("javac ApplicationInfo.java");
+        exec("jar -cfe ..\\appinfo.jar ApplicationInfo ApplicationInfo.class");
+        shell.CurrentDirectory = cur;
+    }
+}
+
+function cleanup() {
+    if(fso.FileExists(ROOT + '\\framework\\cordova-'+VERSION+'.jar')) {
+        fso.DeleteFile(ROOT + '\\framework\\cordova-'+VERSION+'.jar');
+    }
+    if(fso.FileExists(ROOT + '\\framework\\assets\\www\\cordova-'+VERSION+'.js')) {
+        fso.DeleteFile(ROOT + '\\framework\\assets\\www\\cordova-'+VERSION+'.js');
+    }
+}
+
+function downloadCommonsCodec() {
+    if (!fso.FileExists(ROOT + '\\framework\\libs\\commons-codec-1.7.jar')) {
+      // We need the .jar
+      var url = 'http://archive.apache.org/dist/commons/codec/binaries/commons-codec-1.7-bin.zip';
+      var libsPath = ROOT + '\\framework\\libs';
+      var savePath = libsPath + '\\commons-codec-1.7-bin.zip';
+      if (!fso.FileExists(savePath)) {
+        if(!fso.FolderExists(ROOT + '\\framework\\libs')) {
+            fso.CreateFolder(libsPath);
+        }
+        // We need the zip to get the jar
+        var xhr = WScript.CreateObject('MSXML2.XMLHTTP');
+        xhr.open('GET', url, false);
+        xhr.send();
+        if (xhr.status == 200) {
+          var stream = WScript.CreateObject('ADODB.Stream');
+          stream.Open();
+          stream.Type = 1;
+          stream.Write(xhr.ResponseBody);
+          stream.Position = 0;
+          stream.SaveToFile(savePath);
+          stream.Close();
+        } else {
+          WScript.Echo('Could not retrieve the commons-codec. Please download it yourself and put into the framework/libs directory. This process may fail now. Sorry.');
+        }
+      }
+      var app = WScript.CreateObject('Shell.Application');
+      var source = app.NameSpace(savePath).Items();
+      var target = app.NameSpace(ROOT + '\\framework\\libs');
+      target.CopyHere(source, 256);
+      
+      // Move the jar into libs
+      fso.MoveFile(ROOT + '\\framework\\libs\\commons-codec-1.7\\commons-codec-1.7.jar', ROOT + '\\framework\\libs\\commons-codec-1.7.jar');
+      
+      // Clean up
+      fso.DeleteFile(ROOT + '\\framework\\libs\\commons-codec-1.7-bin.zip');
+      fso.DeleteFolder(ROOT + '\\framework\\libs\\commons-codec-1.7', true);
+    }
+}
+
+var args = WScript.Arguments, PROJECT_PATH="example", 
+    shell=WScript.CreateObject("WScript.Shell");
+    
+// working dir
+var ROOT = WScript.ScriptFullName.split('\\bin\\update.js').join('');
+
+if (args.Count() == 1) {
+    PROJECT_PATH=args(0);
+}
+
+if(!fso.FolderExists(PROJECT_PATH)) {
+    WScript.Echo("Project doesn't exist!");
+    WScript.Quit(1);
+}
+
+var TARGET=setTarget();
+var API_LEVEL=setApiLevel();
+var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
+
+// build from source. distro should have these files
+if (!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.jar') &&
+    !fso.FileExists(ROOT+'\\cordova-'+VERSION+'.js')) {
+    WScript.Echo("Building jar and js files...");
+    // update the cordova framework project to a target that exists on this machine
+    exec('android.bat update project --target '+TARGET+' --path '+ROOT+'\\framework');
+    // pull down commons codec if necessary
+    downloadCommonsCodec();
+    exec('ant.bat -f \"'+ ROOT +'\\framework\\build.xml\" jar');
+}
+
+// check if we have the source or the distro files
+WScript.Echo("Copying js, jar & config.xml files...");
+if(fso.FolderExists(ROOT + '\\framework')) {
+    exec('%comspec% /c copy "'+ROOT+'"\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
+    exec('%comspec% /c copy "'+ROOT+'"\\framework\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
+} else {
+    // copy in cordova.js
+    exec('%comspec% /c copy "'+ROOT+'"\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
+    // copy in cordova.jar
+    exec('%comspec% /c copy "'+ROOT+'"\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
+    // copy in xml
+}
+
+// update cordova scripts
+createAppInfoJar();
+WScript.Echo("Copying cordova command tools...");
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\appinfo.jar ' + PROJECT_PATH + '\\cordova\\appinfo.jar /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\cordova.js ' + PROJECT_PATH + '\\cordova\\cordova.js /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\cordova.bat ' + PROJECT_PATH + '\\cordova\\cordova.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\clean.bat ' + PROJECT_PATH + '\\cordova\\clean.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\build.bat ' + PROJECT_PATH + '\\cordova\\build.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\log.bat ' + PROJECT_PATH + '\\cordova\\log.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\run.bat ' + PROJECT_PATH + '\\cordova\\run.bat /Y');
+
+cleanup();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/assets/js/cordova.android.js
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/assets/js/cordova.android.js b/lib/cordova-android/framework/assets/js/cordova.android.js
index bfd6545..a0c3278 100644
--- a/lib/cordova-android/framework/assets/js/cordova.android.js
+++ b/lib/cordova-android/framework/assets/js/cordova.android.js
@@ -1,8 +1,8 @@
 // Platform: android
 
-// commit f50d20a87431c79a54572263729461883f611a53
+// commit 47593b2bc1dba9bf46545b1da24577f937966e12
 
-// File generated at :: Tue Feb 26 2013 13:37:51 GMT-0800 (PST)
+// File generated at :: Thu Mar 21 2013 10:49:00 GMT-0700 (PDT)
 
 /*
  Licensed to the Apache Software Foundation (ASF) under one
@@ -262,7 +262,7 @@ var cordova = {
      */
     callbackSuccess: function(callbackId, args) {
         try {
-            cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback);
+            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
         } catch (e) {
             console.log("Error in error callback: " + callbackId + " = "+e);
         }
@@ -275,7 +275,7 @@ var cordova = {
         // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
         // Derive success from status.
         try {
-            cordova.callbackFromNative(callbackId, false, args.status, args.message, args.keepCallback);
+            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
         } catch (e) {
             console.log("Error in error callback: " + callbackId + " = "+e);
         }
@@ -284,13 +284,13 @@ var cordova = {
     /**
      * Called by native code when returning the result from an action.
      */
-    callbackFromNative: function(callbackId, success, status, message, keepCallback) {
+    callbackFromNative: function(callbackId, success, status, args, keepCallback) {
         var callback = cordova.callbacks[callbackId];
         if (callback) {
             if (success && status == cordova.callbackStatus.OK) {
-                callback.success && callback.success(message);
+                callback.success && callback.success.apply(null, args);
             } else if (!success) {
-                callback.fail && callback.fail(message);
+                callback.fail && callback.fail.apply(null, args);
             }
 
             // Clear callback if not expecting any more results
@@ -724,6 +724,9 @@ channel.createSticky('onCordovaInfoReady');
 // Event to indicate that the connection property has been set.
 channel.createSticky('onCordovaConnectionReady');
 
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
 // Event to indicate that Cordova is ready
 channel.createSticky('onDeviceReady');
 
@@ -900,7 +903,7 @@ androidExec.nativeToJsModes = nativeToJsModes;
 
 androidExec.setJsToNativeBridgeMode = function(mode) {
     if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
-        console.log('Falling back on PROMPT mode since _cordovaNative is missing.');
+        console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
         mode = jsToNativeModes.PROMPT;
     }
     nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
@@ -958,10 +961,12 @@ function processMessage(message) {
                     arraybuffer[i] = bytes.charCodeAt(i);
                 }
                 payload = arraybuffer.buffer;
+            } else if (payloadKind == 'S') {
+                payload = window.atob(message.slice(nextSpaceIdx + 2));
             } else {
                 payload = JSON.parse(message.slice(nextSpaceIdx + 1));
             }
-            cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
+            cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
         } else {
             console.log("processMessage failed: invalid message:" + message);
         }
@@ -1203,9 +1208,10 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
     var correctOrientation = !!options.correctOrientation;
     var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
     var popoverOptions = getValue(options.popoverOptions, null);
+    var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
 
     var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
-                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
 
     exec(successCallback, errorCallback, "Camera", "takePicture", args);
     return new CameraPopoverHandle();
@@ -1248,6 +1254,10 @@ module.exports = {
       ARROW_LEFT : 4,
       ARROW_RIGHT : 8,
       ARROW_ANY : 15
+  },
+  Direction:{
+      BACK: 0,
+      FRONT: 1
   }
 };
 
@@ -2439,14 +2449,7 @@ FileReader.prototype.readAsText = function(file, encoding) {
     // Default encoding is UTF-8
     var enc = encoding ? encoding : "UTF-8";
     var me = this;
-    var execArgs = [this._fileName, enc];
-
-    // Maybe add slice parameters.
-    if (file.end < file.size) {
-        execArgs.push(file.start, file.end);
-    } else if (file.start > 0) {
-        execArgs.push(file.start);
-    }
+    var execArgs = [this._fileName, enc, file.start, file.end];
 
     // Read file
     exec(
@@ -2515,14 +2518,7 @@ FileReader.prototype.readAsDataURL = function(file) {
     }
 
     var me = this;
-    var execArgs = [this._fileName];
-
-    // Maybe add slice parameters.
-    if (file.end < file.size) {
-        execArgs.push(file.start, file.end);
-    } else if (file.start > 0) {
-        execArgs.push(file.start);
-    }
+    var execArgs = [this._fileName, file.start, file.end];
 
     // Read file
     exec(
@@ -2585,9 +2581,59 @@ FileReader.prototype.readAsBinaryString = function(file) {
     if (initRead(this, file)) {
         return this._realReader.readAsBinaryString(file);
     }
-    // TODO - Can't return binary data to browser.
-    console.log('method "readAsBinaryString" is not supported at this time.');
-    this.abort();
+
+    var me = this;
+    var execArgs = [this._fileName, file.start, file.end];
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me._readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me._readyState = FileReader.DONE;
+
+            me._result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // 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;
+
+            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", "readAsBinaryString", execArgs);
 };
 
 /**
@@ -2599,9 +2645,59 @@ FileReader.prototype.readAsArrayBuffer = function(file) {
     if (initRead(this, file)) {
         return this._realReader.readAsArrayBuffer(file);
     }
-    // TODO - Can't return binary data to browser.
-    console.log('This method is not supported at this time.');
-    this.abort();
+
+    var me = this;
+    var execArgs = [this._fileName, file.start, file.end];
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me._readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me._readyState = FileReader.DONE;
+
+            me._result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // 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;
+
+            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", "readAsArrayBuffer", execArgs);
 };
 
 module.exports = FileReader;
@@ -2647,6 +2743,38 @@ function newProgressEvent(result) {
     return pe;
 }
 
+function getBasicAuthHeader(urlString) {
+    var header =  null;
+
+    if (window.btoa) {
+        // parse the url using the Location object
+        var url = document.createElement('a');
+        url.href = urlString;
+
+        var credentials = null;
+        var protocol = url.protocol + "//";
+        var origin = protocol + url.host;
+
+        // check whether there are the username:password credentials in the url
+        if (url.href.indexOf(origin) != 0) { // credentials found
+            var atIndex = url.href.indexOf("@");
+            credentials = url.href.substring(protocol.length, atIndex);
+        }
+
+        if (credentials) {
+            var authHeader = "Authorization";
+            var authHeaderValue = "Basic " + window.btoa(credentials);
+
+            header = {
+                name : authHeader,
+                value : authHeaderValue
+            };
+        }
+    }
+
+    return header;
+}
+
 var idCounter = 0;
 
 /**
@@ -2677,6 +2805,18 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
     var params = null;
     var chunkedMode = true;
     var headers = null;
+
+    var basicAuthHeader = getBasicAuthHeader(server);
+    if (basicAuthHeader) {
+        if (!options) {
+            options = new FileUploadOptions();
+        }
+        if (!options.headers) {
+            options.headers = {};
+        }
+        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+    }
+
     if (options) {
         fileKey = options.fileKey;
         fileName = options.fileName;
@@ -2694,7 +2834,7 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
     }
 
     var fail = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
         errorCallback(error);
     };
 
@@ -2718,10 +2858,28 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
  * @param successCallback (Function}  Callback to be invoked when upload has completed
  * @param errorCallback {Function}    Callback to be invoked upon error
  * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+ * @param options {FileDownloadOptions} Optional parameters such as headers
  */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) {
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
     argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
     var self = this;
+
+    var basicAuthHeader = getBasicAuthHeader(source);
+    if (basicAuthHeader) {
+        if (!options) {
+            options = {};
+        }
+        if (!options.headers) {
+            options.headers = {};
+        }
+        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+    }
+
+    var headers = null;
+    if (options) {
+        headers = options.headers || null;
+    }
+
     var win = function(result) {
         if (typeof result.lengthComputable != "undefined") {
             if (self.onprogress) {
@@ -2744,11 +2902,11 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
     };
 
     var fail = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
         errorCallback(error);
     };
 
-    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]);
+    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
 };
 
 /**
@@ -3146,6 +3304,7 @@ function InAppBrowser() {
    this.channels = {
         'loadstart': channel.create('loadstart'),
         'loadstop' : channel.create('loadstop'),
+        'loaderror' : channel.create('loaderror'),
         'exit' : channel.create('exit')
    };
 }
@@ -3176,7 +3335,7 @@ module.exports = function(strUrl, strWindowName, strWindowFeatures) {
     var cb = function(eventname) {
        iab._eventHandler(eventname);
     };
-    exec(cb, null, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
+    exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
     return iab;
 };
 
@@ -4940,7 +5099,8 @@ modulemapper.merges('cordova/plugin/android/device', 'device');
 // file: lib/common/plugin/echo.js
 define("cordova/plugin/echo", function(require, exports, module) {
 
-var exec = require('cordova/exec');
+var exec = require('cordova/exec'),
+    utils = require('cordova/utils');
 
 /**
  * Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.
@@ -4950,11 +5110,25 @@ var exec = require('cordova/exec');
  * @param forceAsync  Whether to force an async return value (for testing native->js bridge).
  */
 module.exports = function(successCallback, errorCallback, message, forceAsync) {
-    var action = forceAsync ? 'echoAsync' : 'echo';
-    if (!forceAsync && message.constructor == ArrayBuffer) {
-        action = 'echoArrayBuffer';
+    var action = 'echo';
+    var messageIsMultipart = (utils.typeName(message) == "Array");
+    var args = messageIsMultipart ? message : [message];
+
+    if (utils.typeName(message) == 'ArrayBuffer') {
+        if (forceAsync) {
+            console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.');
+        }
+        action += 'ArrayBuffer';
+    } else if (messageIsMultipart) {
+        if (forceAsync) {
+            console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.');
+        }
+        action += 'MultiPart';
+    } else if (forceAsync) {
+        action += 'Async';
     }
-    exec(successCallback, errorCallback, "Echo", action, [message]);
+
+    exec(successCallback, errorCallback, "Echo", action, args);
 };
 
 
@@ -5950,6 +6124,7 @@ modulemapper.defaults('cordova/plugin/Connection', 'Connection');
 define("cordova/plugin/notification", function(require, exports, module) {
 
 var exec = require('cordova/exec');
+var platform = require('cordova/platform');
 
 /**
  * Provides access to notifications on the device.
@@ -5978,15 +6153,53 @@ module.exports = {
      * @param {String} message              Message to print in the body of the alert
      * @param {Function} resultCallback     The callback that is called when user clicks on a button.
      * @param {String} title                Title of the alert dialog (default: Confirm)
-     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+     * @param {Array} buttonLabels          Array of the labels of the buttons (default: ['OK', 'Cancel'])
      */
     confirm: function(message, resultCallback, title, buttonLabels) {
         var _title = (title || "Confirm");
-        var _buttonLabels = (buttonLabels || "OK,Cancel");
+        var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);
+
+        // Strings are deprecated!
+        if (typeof _buttonLabels === 'string') {
+            console.log("Notification.confirm(string, function, string, string) is deprecated.  Use Notification.confirm(string, function, string, array).");
+        }
+
+        // Android and iOS take an array of button label names.
+        // Other platforms take a comma separated list.
+        // For compatibility, we convert to the desired type based on the platform.
+        if (platform.id == "android" || platform.id == "ios") {
+            if (typeof _buttonLabels === 'string') {
+                var buttonLabelString = _buttonLabels;
+                _buttonLabels = buttonLabelString.split(",");
+            }
+        } else {
+            if (Array.isArray(_buttonLabels)) {
+                var buttonLabelArray = _buttonLabels;
+                _buttonLabels = buttonLabelArray.toString();
+            }
+        }
         exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
     },
 
     /**
+     * Open a native prompt dialog, with a customizable title and button text.
+     * The following results are returned to the result callback:
+     *  buttonIndex     Index number of the button selected.
+     *  input1          The text entered in the prompt dialog box.
+     *
+     * @param {String} message              Dialog message to display (default: "Prompt message")
+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the dialog (default: "Prompt")
+     * @param {Array} buttonLabels          Array of strings for the button labels (default: ["OK","Cancel"])
+     */
+    prompt: function(message, resultCallback, title, buttonLabels) {
+        var _message = (message || "Prompt message");
+        var _title = (title || "Prompt");
+        var _buttonLabels = (buttonLabels || ["OK","Cancel"]);
+        exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels]);
+    },
+
+    /**
      * Causes the device to vibrate.
      *
      * @param {Integer} mills       The number of milliseconds to vibrate for.
@@ -6409,53 +6622,160 @@ window.cordova = require('cordova');
 (function (context) {
     // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
     // We replace it so that properties that can't be clobbered can instead be overridden.
-    if (context.navigator) {
+    function replaceNavigator(origNavigator) {
         var CordovaNavigator = function() {};
-        CordovaNavigator.prototype = context.navigator;
-        context.navigator = new CordovaNavigator();
+        CordovaNavigator.prototype = origNavigator;
+        var newNavigator = new CordovaNavigator();
+        // This work-around really only applies to new APIs that are newer than Function.bind.
+        // Without it, APIs such as getGamepads() break.
+        if (CordovaNavigator.bind) {
+            for (var key in origNavigator) {
+                if (typeof origNavigator[key] == 'function') {
+                    newNavigator[key] = origNavigator[key].bind(origNavigator);
+                }
+            }
+        }
+        return newNavigator;
     }
+    if (context.navigator) {
+        context.navigator = replaceNavigator(context.navigator);
+    }
+
+    var channel = require("cordova/channel");
+
+    // _nativeReady is global variable that the native side can set
+    // to signify that the native code is ready. It is a global since
+    // it may be called before any cordova JS is ready.
+    if (window._nativeReady) {
+        channel.onNativeReady.fire();
+    }
+
+    /**
+     * Create all cordova objects once page has fully loaded and native side is ready.
+     */
+    channel.join(function() {
+        var builder = require('cordova/builder'),
+            platform = require('cordova/platform');
+
+        builder.buildIntoButDoNotClobber(platform.defaults, context);
+        builder.buildIntoAndClobber(platform.clobbers, context);
+        builder.buildIntoAndMerge(platform.merges, context);
+
+        // Call the platform-specific initialization
+        platform.initialize();
+
+        // Fire event to notify that all objects are created
+        channel.onCordovaReady.fire();
+
+        // Fire onDeviceReady event once all constructors have run and
+        // cordova info has been received from native side.
+        channel.join(function() {
+            require('cordova').fireDocumentEvent('deviceready');
+        }, channel.deviceReadyChannelsArray);
+
+    }, [ channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady ]);
 
-    var channel = require("cordova/channel"),
-        _self = {
-            boot: function () {
-                /**
-                 * Create all cordova objects once page has fully loaded and native side is ready.
-                 */
-                channel.join(function() {
-                    var builder = require('cordova/builder'),
-                        platform = require('cordova/platform');
+}(window));
 
-                    builder.buildIntoButDoNotClobber(platform.defaults, context);
-                    builder.buildIntoAndClobber(platform.clobbers, context);
-                    builder.buildIntoAndMerge(platform.merges, context);
+// file: lib/scripts/plugin_loader.js
 
-                    // Call the platform-specific initialization
-                    platform.initialize();
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+(function (context) {
+    // To be populated with the handler by handlePluginsObject.
+    var onScriptLoadingComplete;
+
+    var scriptCounter = 0;
+    function scriptLoadedCallback() {
+        scriptCounter--;
+        if (scriptCounter === 0) {
+            onScriptLoadingComplete && onScriptLoadingComplete();
+        }
+    }
 
-                    // Fire event to notify that all objects are created
-                    channel.onCordovaReady.fire();
+    // Helper function to inject a <script> tag.
+    function injectScript(path) {
+        scriptCounter++;
+        var script = document.createElement("script");
+        script.onload = scriptLoadedCallback;
+        script.src = path;
+        document.head.appendChild(script);
+    }
+
+    // Called when:
+    // * There are plugins defined and all plugins are finished loading.
+    // * There are no plugins to load.
+    function finishPluginLoading() {
+        context.cordova.require('cordova/channel').onPluginsReady.fire();
+    }
+
+    // Handler for the cordova_plugins.json content.
+    // See plugman's plugin_loader.js for the details of this object.
+    // This function is only called if the really is a plugins array that isn't empty.
+    // Otherwise the XHR response handler will just call finishPluginLoading().
+    function handlePluginsObject(modules) {
+        // First create the callback for when all plugins are loaded.
+        var mapper = context.cordova.require('cordova/modulemapper');
+        onScriptLoadingComplete = function() {
+            // Loop through all the plugins and then through their clobbers and merges.
+            for (var i = 0; i < modules.length; i++) {
+                var module = modules[i];
+                if (!module) continue;
+
+                if (module.clobbers && module.clobbers.length) {
+                    for (var j = 0; j < module.clobbers.length; j++) {
+                        mapper.clobbers(module.id, module.clobbers[j]);
+                    }
+                }
 
-                    // Fire onDeviceReady event once all constructors have run and
-                    // cordova info has been received from native side.
-                    channel.join(function() {
-                        require('cordova').fireDocumentEvent('deviceready');
-                    }, channel.deviceReadyChannelsArray);
+                if (module.merges && module.merges.length) {
+                    for (var k = 0; k < module.merges.length; k++) {
+                        mapper.merges(module.id, module.merges[k]);
+                    }
+                }
 
-                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+                // Finally, if runs is truthy we want to simply require() the module.
+                // This can be skipped if it had any merges or clobbers, though,
+                // since the mapper will already have required the module.
+                if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+                    context.cordova.require(module.id);
+                }
             }
-        };
 
-    // boot up once native side is ready
-    channel.onNativeReady.subscribe(_self.boot);
+            finishPluginLoading();
+        };
 
-    // _nativeReady is global variable that the native side can set
-    // to signify that the native code is ready. It is a global since
-    // it may be called before any cordova JS is ready.
-    if (window._nativeReady) {
-        channel.onNativeReady.fire();
+        // Now inject the scripts.
+        for (var i = 0; i < modules.length; i++) {
+            injectScript(modules[i].file);
+        }
     }
 
+    // Try to XHR the cordova_plugins.json file asynchronously.
+    var xhr = new context.XMLHttpRequest();
+    xhr.onreadystatechange = function() {
+        if (this.readyState != 4) { // not DONE
+            return;
+        }
+
+        // If the response is a JSON string which composes an array, call handlePluginsObject.
+        // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
+        if (this.status == 200) {
+            var obj = JSON.parse(this.responseText);
+            if (obj && obj instanceof Array && obj.length > 0) {
+                handlePluginsObject(obj);
+            } else {
+                finishPluginLoading();
+            }
+        } else {
+            finishPluginLoading();
+        }
+    };
+    xhr.open('GET', 'cordova_plugins.json', true); // Async
+    xhr.send();
 }(window));
 
 
+
 })();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/assets/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/assets/www/index.html b/lib/cordova-android/framework/assets/www/index.html
index a10905d..3b15a4e 100644
--- a/lib/cordova-android/framework/assets/www/index.html
+++ b/lib/cordova-android/framework/assets/www/index.html
@@ -19,7 +19,7 @@
 <html>
   <head>
     <title></title>
-    <script src="cordova-2.5.0.js"></script>
+    <script src="cordova-2.6.0rc1.js"></script>
   </head>
   <body>
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java b/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
index ed5757f..fd8c9df 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
@@ -68,13 +68,13 @@ public class AudioHandler extends CordovaPlugin {
         String result = "";
 
         if (action.equals("startRecordingAudio")) {
-            this.startRecordingAudio(args.getString(0), FileUtils.stripFileProtocol(args.getString(1)));
+            this.startRecordingAudio(args.getString(0), FileHelper.stripFileProtocol(args.getString(1)));
         }
         else if (action.equals("stopRecordingAudio")) {
             this.stopRecordingAudio(args.getString(0));
         }
         else if (action.equals("startPlayingAudio")) {
-            this.startPlayingAudio(args.getString(0), FileUtils.stripFileProtocol(args.getString(1)));
+            this.startPlayingAudio(args.getString(0), FileHelper.stripFileProtocol(args.getString(1)));
         }
         else if (action.equals("seekToAudio")) {
             this.seekToAudio(args.getString(0), args.getInt(1));
@@ -102,7 +102,7 @@ public class AudioHandler extends CordovaPlugin {
         }
         else if (action.equals("create")) {
             String id = args.getString(0);
-            String src = FileUtils.stripFileProtocol(args.getString(1));
+            String src = FileHelper.stripFileProtocol(args.getString(1));
             AudioPlayer audio = new AudioPlayer(this, id, src);
             this.players.put(id, audio);
         }

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java b/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
index 99dbb3d..0170728 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
@@ -167,13 +167,18 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     public void moveFile(String file) {
         /* this is a hack to save the file as the specified name */
         File f = new File(this.tempFile);
-        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            f.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath()
-                    + File.separator + file));
-        } else {
-            f.renameTo(new File("/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/" + file));
+
+        if (!file.startsWith("/")) {
+            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                file = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + file;
+            } else {
+                file = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/" + file;
+            }
         }
 
+        String logMsg = "renaming " + this.tempFile + " to " + file;
+        Log.d(LOG_TAG, logMsg);
+        if (!f.renameTo(new File(file))) Log.e(LOG_TAG, "FAILED " + logMsg);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java b/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
index aec0def..9473828 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
@@ -289,7 +289,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
 
                     // If sending base64 image back
                     if (destType == DATA_URL) {
-                        bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
+                        bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
                         if (bitmap == null) {
                             // Try to get the bitmap from intent.
                             bitmap = (Bitmap)intent.getExtras().get("data");
@@ -329,7 +329,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
 
                             this.callbackContext.success(uri.toString());
                         } else {
-                            bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
+                            bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
 
                             if (rotate != 0 && this.correctOrientation) {
                                 bitmap = getRotatedBitmap(rotate, bitmap, exif);
@@ -344,7 +344,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
                             if (this.encodingType == JPEG) {
                                 String exifPath;
                                 if (this.saveToPhotoAlbum) {
-                                    exifPath = FileUtils.getRealPathFromURI(uri, this.cordova);
+                                    exifPath = FileHelper.getRealPath(uri, this.cordova);
                                 } else {
                                     exifPath = uri.getPath();
                                 }
@@ -395,8 +395,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
                         this.callbackContext.success(uri.toString());
                     } else {
                         // Get the path to the image. Makes loading so much easier.
-                        String imagePath = FileUtils.getRealPathFromURI(uri, this.cordova);
-                        String mimeType = FileUtils.getMimeType(imagePath);
+                        String imagePath = FileHelper.getRealPath(uri, this.cordova);
+                        String mimeType = FileHelper.getMimeType(imagePath, this.cordova);
                         // Log.d(LOG_TAG, "Real path = " + imagePath);
                         // Log.d(LOG_TAG, "mime type = " + mimeType);
                         // If we don't have a valid image so quit.
@@ -458,7 +458,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
 
                                     // Restore exif data to file
                                     if (this.encodingType == JPEG) {
-                                        exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.cordova));
+                                        exif.createOutFile(FileHelper.getRealPath(uri, this.cordova));
                                         exif.writeExifData();
                                     }
 
@@ -521,7 +521,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
      */
     private void writeUncompressedImage(Uri uri) throws FileNotFoundException,
             IOException {
-        FileInputStream fis = new FileInputStream(FileUtils.stripFileProtocol(imageUri.toString()));
+        FileInputStream fis = new FileInputStream(FileHelper.stripFileProtocol(imageUri.toString()));
         OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
         byte[] buffer = new byte[4096];
         int len;
@@ -685,7 +685,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
         }
 
         // Clean up initial camera-written image file.
-        (new File(FileUtils.stripFileProtocol(oldImage.toString()))).delete();
+        (new File(FileHelper.stripFileProtocol(oldImage.toString()))).delete();
 
         checkForDuplicateImage(imageType);
         // Scan for the gallery to update pic refs in gallery

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Capture.java b/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
index 3eecf37..5f737ca 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
@@ -23,6 +23,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import android.os.Build;
 import org.apache.cordova.api.CallbackContext;
 import org.apache.cordova.api.CordovaPlugin;
 import org.apache.cordova.api.LOG;
@@ -128,7 +129,7 @@ public class Capture extends CordovaPlugin {
         // If the mimeType isn't set the rest will fail
         // so let's see if we can determine it.
         if (mimeType == null || mimeType.equals("") || "null".equals(mimeType)) {
-            mimeType = FileUtils.getMimeType(filePath);
+            mimeType = FileHelper.getMimeType(filePath, cordova);
         }
         Log.d(LOG_TAG, "Mime type = " + mimeType);
 
@@ -155,7 +156,7 @@ public class Capture extends CordovaPlugin {
     private JSONObject getImageData(String filePath, JSONObject obj) throws JSONException {
         BitmapFactory.Options options = new BitmapFactory.Options();
         options.inJustDecodeBounds = true;
-        BitmapFactory.decodeFile(FileUtils.stripFileProtocol(filePath), options);
+        BitmapFactory.decodeFile(FileHelper.stripFileProtocol(filePath), options);
         obj.put("height", options.outHeight);
         obj.put("width", options.outWidth);
         return obj;
@@ -216,9 +217,10 @@ public class Capture extends CordovaPlugin {
      */
     private void captureVideo(double duration) {
         Intent intent = new Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
-        // Introduced in API 8
-        //intent.putExtra(android.provider.MediaStore.EXTRA_DURATION_LIMIT, duration);
 
+        if(Build.VERSION.SDK_INT > 8){
+            intent.putExtra("android.intent.extra.durationLimit", duration);
+        }
         this.cordova.startActivityForResult((CordovaPlugin) this, intent, CAPTURE_VIDEO);
     }
 
@@ -346,7 +348,7 @@ public class Capture extends CordovaPlugin {
      * @throws IOException
      */
     private JSONObject createMediaFile(Uri data) {
-        File fp = new File(FileUtils.getRealPathFromURI(data, this.cordova));
+        File fp = new File(FileHelper.getRealPath(data, this.cordova));
         JSONObject obj = new JSONObject();
 
         try {
@@ -363,7 +365,7 @@ public class Capture extends CordovaPlugin {
                     obj.put("type", VIDEO_3GPP);
                 }
             } else {
-                obj.put("type", FileUtils.getMimeType(fp.getAbsolutePath()));
+                obj.put("type", FileHelper.getMimeType(fp.getAbsolutePath(), cordova));
             }
 
             obj.put("lastModifiedDate", fp.lastModified());

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/Config.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Config.java b/lib/cordova-android/framework/src/org/apache/cordova/Config.java
index 01eb2bb..f5de38d 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/Config.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Config.java
@@ -143,6 +143,16 @@ public class Config {
                         boolean value = xml.getAttributeValue(null, "value").equals("true");
                         action.getIntent().putExtra(name, value);
                     }
+                    else if(name.equals("InAppBrowserStorageEnabled"))
+                    {
+                        boolean value = xml.getAttributeValue(null, "value").equals("true");
+                        action.getIntent().putExtra(name, value);
+                    }
+                    else if(name.equals("disallowOverscroll"))
+                    {
+                        boolean value = xml.getAttributeValue(null, "value").equals("true");
+                        action.getIntent().putExtra(name, value);
+                    }
                     else
                     {
                         String value = xml.getAttributeValue(null, "value");

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
index 3a8b7c0..d40d26e 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
@@ -20,6 +20,7 @@ package org.apache.cordova;
 
 import org.json.JSONArray;
 import org.json.JSONException;
+import org.json.JSONObject;
 
 import android.util.Base64;
 
@@ -52,7 +53,7 @@ public class CordovaArgs {
         return baseArgs.getJSONArray(index);
     }
 
-    public Object getJSONObject(int index) throws JSONException {
+    public JSONObject getJSONObject(int index) throws JSONException {
         return baseArgs.getJSONObject(index);
     }
 
@@ -85,7 +86,7 @@ public class CordovaArgs {
         return baseArgs.optJSONArray(index);
     }
 
-    public Object optJSONObject(int index) {
+    public JSONObject optJSONObject(int index) {
         return baseArgs.optJSONObject(index);
     }
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
index e650781..fb6d45f 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -205,7 +205,7 @@ public class CordovaChromeClient extends WebChromeClient {
         // Security check to make sure any requests are coming from the page initially
         // loaded in webview and not another loaded in an iframe.
         boolean reqOk = false;
-        if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
+        if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
             reqOk = true;
         }
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
index 4731adb..e653a95 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
@@ -47,6 +47,7 @@ import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
 import android.webkit.WebBackForwardList;
 import android.webkit.WebHistoryItem;
 import android.webkit.WebChromeClient;
@@ -74,12 +75,7 @@ public class CordovaWebView extends WebView {
     @SuppressWarnings("unused")
     private CordovaChromeClient chromeClient;
 
-    //This is for the polyfill history
     private String url;
-    String baseUrl;
-    private Stack<String> urls = new Stack<String>();
-
-    boolean useBrowserHistory = true;
 
     // Flag to track that a loadUrl timeout occurred
     int loadUrlTimeout = 0;
@@ -211,7 +207,8 @@ public class CordovaWebView extends WebView {
 
 
     private void initWebViewClient(CordovaInterface cordova) {
-        if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
+        if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB ||
+                android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
         {
             this.setWebViewClient(new CordovaWebViewClient(this.cordova, this));
         }
@@ -254,14 +251,23 @@ public class CordovaWebView extends WebView {
             Log.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore.");
         }
 
+        //We don't save any form data in the application
+        settings.setSaveFormData(false);
+        settings.setSavePassword(false);
+        
         // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
         // while we do this
         if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
             Level16Apis.enableUniversalAccess(settings);
         // Enable database
-        settings.setDatabaseEnabled(true);
+        // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
         String databasePath = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
-        settings.setDatabasePath(databasePath);
+        if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
+        {
+            settings.setDatabaseEnabled(true);
+            settings.setDatabasePath(databasePath);
+        }
+        
         settings.setGeolocationDatabasePath(databasePath);
 
         // Enable DOM storage
@@ -360,7 +366,7 @@ public class CordovaWebView extends WebView {
             String initUrl = this.getProperty("url", null);
 
             // If first page of app, then set URL to load to be the one passed in
-            if (initUrl == null || (this.urls.size() > 0)) {
+            if (initUrl == null) {
                 this.loadUrlIntoView(url);
             }
             // Otherwise use the URL specified in the activity's extras bundle
@@ -381,7 +387,7 @@ public class CordovaWebView extends WebView {
         String initUrl = this.getProperty("url", null);
 
         // If first page of app, then set URL to load to be the one passed in
-        if (initUrl == null || (this.urls.size() > 0)) {
+        if (initUrl == null) {
             this.loadUrlIntoView(url, time);
         }
         // Otherwise use the URL specified in the activity's extras bundle
@@ -399,21 +405,8 @@ public class CordovaWebView extends WebView {
         LOG.d(TAG, ">>> loadUrl(" + url + ")");
 
         this.url = url;
-        if (this.baseUrl == null) {
-            int i = url.lastIndexOf('/');
-            if (i > 0) {
-                this.baseUrl = url.substring(0, i + 1);
-            }
-            else {
-                this.baseUrl = this.url + "/";
-            }
-
-            this.pluginManager.init();
+        this.pluginManager.init();
 
-            if (!this.useBrowserHistory) {
-                this.urls.push(url);
-            }
-        }
 
         // Create a timeout timer for loadUrl
         final CordovaWebView me = this;
@@ -468,7 +461,7 @@ public class CordovaWebView extends WebView {
         if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
             LOG.d(TAG, ">>> loadUrlNow()");
         }
-        if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
+        if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
             super.loadUrl(url);
         }
     }
@@ -484,7 +477,7 @@ public class CordovaWebView extends WebView {
 
         // If not first page of app, then load immediately
         // Add support for browser history if we use it.
-        if ((url.startsWith("javascript:")) || this.urls.size() > 0 || this.canGoBack()) {
+        if ((url.startsWith("javascript:")) || this.canGoBack()) {
         }
 
         // If first page, then show splashscreen
@@ -532,25 +525,6 @@ public class CordovaWebView extends WebView {
         }
     }
 
-    /**
-     * Returns the top url on the stack without removing it from
-     * the stack.
-     */
-    public String peekAtUrlStack() {
-        if (this.urls.size() > 0) {
-            return this.urls.peek();
-        }
-        return "";
-    }
-
-    /**
-     * Add a url to the stack
-     *
-     * @param url
-     */
-    public void pushUrl(String url) {
-        this.urls.push(url);
-    }
 
     /**
      * Go to previous page in history.  (We manage our own history)
@@ -561,37 +535,15 @@ public class CordovaWebView extends WebView {
 
         // Check webview first to see if there is a history
         // This is needed to support curPage#diffLink, since they are added to appView's history, but not our history url array (JQMobile behavior)
-        if (super.canGoBack() && this.useBrowserHistory) {
+        if (super.canGoBack()) {
             printBackForwardList();
             super.goBack();
             
             return true;
         }
-        // If our managed history has prev url
-        else if (this.urls.size() > 1 && !this.useBrowserHistory) {
-            this.urls.pop();                // Pop current url
-            String url = this.urls.pop();   // Pop prev url that we want to load, since it will be added back by loadUrl()
-            this.loadUrl(url);
-            return true;
-        }
-
         return false;
     }
 
-    /**
-     * Return true if there is a history item.
-     *
-     * @return
-     */
-    public boolean canGoBack() {
-        if (super.canGoBack() && this.useBrowserHistory) {
-            return true;
-        }
-        else if (this.urls.size() > 1) {
-            return true;
-        }
-        return false;
-    }
 
     /**
      * Load the specified URL in the Cordova webview or a new browser instance.
@@ -615,14 +567,8 @@ public class CordovaWebView extends WebView {
         if (!openExternal) {
 
             // Make sure url is in whitelist
-            if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
+            if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
                 // TODO: What about params?
-
-                // Clear out current url from history, since it will be replacing it
-                if (clearHistory) {
-                    this.urls.clear();
-                }
-
                 // Load new URL
                 this.loadUrl(url);
             }
@@ -659,13 +605,6 @@ public class CordovaWebView extends WebView {
      *      <log level="DEBUG" />
      */
     private void loadConfiguration() {
-        // Config has already been loaded, and it stores these preferences on the Intent.
-        if("false".equals(this.getProperty("useBrowserHistory", "true")))
-        {
-            //Switch back to the old browser history and state the six month policy
-            this.useBrowserHistory = false;
-            Log.w(TAG, "useBrowserHistory=false is deprecated as of Cordova 2.2.0 and will be removed six months after the 2.2.0 release.  Please use the browser history and use history.back().");
-        }
  
         if ("true".equals(this.getProperty("fullscreen", "false"))) {
             this.cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
@@ -719,13 +658,20 @@ public class CordovaWebView extends WebView {
         }
         else if(keyCode == KeyEvent.KEYCODE_BACK)
         {
-            //Because exit is fired on the keyDown and not the key up on Android 4.x
-            //we need to check for this.
-            //Also, I really wished "canGoBack" worked!
-            if(this.useBrowserHistory)
-                return !(this.startOfHistory()) || this.bound;
-            else
-                return this.urls.size() > 1 || this.bound;
+            return !(this.startOfHistory()) || this.bound;
+        }
+        else if(keyCode == KeyEvent.KEYCODE_MENU)
+        {
+            //How did we get here?  Is there a childView?
+            View childView = this.getFocusedChild();
+            if(childView != null)
+            {
+                //Make sure we close the keyboard if it's present
+                InputMethodManager imm = (InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+                imm.hideSoftInputFromWindow(childView.getWindowToken(), 0);
+                cordova.getActivity().openOptionsMenu();
+            }
+            return true;
         }
         
         return super.onKeyDown(keyCode, event);