diff --git a/framework/src/org/apache/cordova/AudioPlayer.java b/framework/src/org/apache/cordova/AudioPlayer.java
index 72efcdae..856cc7b7 100755
--- a/framework/src/org/apache/cordova/AudioPlayer.java
+++ b/framework/src/org/apache/cordova/AudioPlayer.java
@@ -37,8 +37,8 @@ import java.io.IOException;
  * Only one file can be played or recorded per class instance.
  * 
  * Local audio files must reside in one of two places:
- * 		android_asset: 		file name must start with /android_asset/sound.mp3
- * 		sdcard:				file name is just sound.mp3
+ *      android_asset:      file name must start with /android_asset/sound.mp3
+ *      sdcard:             file name is just sound.mp3
  */
 public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener {
 
@@ -56,43 +56,47 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     private static int MEDIA_DURATION = 2;
     private static int MEDIA_POSITION = 3;
     private static int MEDIA_ERROR = 9;
-
+    
     // Media error codes
-    private static int MEDIA_ERR_NONE_ACTIVE = 0;
-    private static int MEDIA_ERR_ABORTED = 1;
-//    private static int MEDIA_ERR_NETWORK = 2;
-//    private static int MEDIA_ERR_DECODE = 3;
-//    private static int MEDIA_ERR_NONE_SUPPORTED = 4;
+    private static int MEDIA_ERR_NONE_ACTIVE    = 0;
+    private static int MEDIA_ERR_ABORTED        = 1;
+    private static int MEDIA_ERR_NETWORK        = 2;
+    private static int MEDIA_ERR_DECODE         = 3;
+    private static int MEDIA_ERR_NONE_SUPPORTED = 4;
+    
+    private AudioHandler handler;                   // The AudioHandler object
+    private String id;                              // The id of this player (used to identify Media object in JavaScript)
+    private int state = MEDIA_NONE;                 // State of recording or playback
+    private String audioFile = null;                // File name to play or record to
+    private float duration = -1;                    // Duration of audio
 
-    private AudioHandler handler;					// The AudioHandler object
-    private String id;								// The id of this player (used to identify Media object in JavaScript)
-    private int state = MEDIA_NONE;					// State of recording or playback
-    private String audioFile = null;				// File name to play or record to
-    private float duration = -1;					// Duration of audio
-
-    private MediaRecorder recorder = null;			// Audio recording object
-    private String tempFile = null;					// Temporary recording file name
-
-    private MediaPlayer mPlayer = null;				// Audio player object
+    private MediaRecorder recorder = null;          // Audio recording object
+    private String tempFile = null;                 // Temporary recording file name
+    
+    private MediaPlayer mPlayer = null;             // Audio player object
     private boolean prepareOnly = false;
 
     /**
      * Constructor.
      * 
-     * @param handler			The audio handler object
-     * @param id				The id of this audio player
+     * @param handler           The audio handler object
+     * @param id                The id of this audio player
      */
     public AudioPlayer(AudioHandler handler, String id) {
         this.handler = handler;
         this.id = id;
-        this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3";
-    }
+        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3";
+        } else {
+            this.tempFile = "/data/data/" + handler.ctx.getPackageName() + "/cache/tmprecording.mp3";
+        }
+    }   
 
     /**
      * Destroy player and stop audio playing or recording.
      */
     public void destroy() {
-
+        
         // Stop any play or record
         if (this.mPlayer != null) {
             if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) {
@@ -112,14 +116,14 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     /**
      * Start recording the specified file.
      * 
-     * @param file				The name of the file
+     * @param file              The name of the file
      */
     public void startRecording(String file) {
         if (this.mPlayer != null) {
             Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
-            this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
+            this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
         }
-
+        
         // Make sure we're not already recording
         else if (this.recorder == null) {
             this.audioFile = file;
@@ -138,26 +142,31 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
             } catch (IOException e) {
                 e.printStackTrace();
             }
-            this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
+            this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");            
         }
         else {
             Log.d(LOG_TAG, "AudioPlayer Error: Already recording.");
-            this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
+            this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");            
         }
     }
-
+    
     /**
      * Save temporary recorded file to specified name
      * 
      * @param file
      */
-    public void moveFile(String file) {
-
+    public void moveFile(String file) { 
         /* this is a hack to save the file as the specified name */
         File f = new File(this.tempFile);
-        f.renameTo(new File("/sdcard/" + file));
+        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.ctx.getPackageName() + "/cache/" + file));
+        }
+        
     }
-
+    
     /**
      * Stop recording and save to the file specified when recording started.
      */
@@ -178,7 +187,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     /**
      * Start or resume playing audio file.
      * 
-     * @param file				The name of the audio file.
+     * @param file              The name of the audio file.
      */
     public void startPlaying(String file) {
         if (this.recorder != null) {
@@ -297,7 +306,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     /**
      * Callback to be invoked when playback of a media source has completed.
      * 
-     * @param mPlayer			The MediaPlayer that reached the end of the file 
+     * @param mPlayer           The MediaPlayer that reached the end of the file 
      */
     public void onCompletion(MediaPlayer mPlayer) {
         this.setState(MEDIA_STOPPED);
@@ -306,7 +315,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     /**
      * Get current position of playback.
      * 
-     * @return 					position in msec or -1 if not playing
+     * @return                  position in msec or -1 if not playing
      */
     public long getCurrentPosition() {
         if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) {
@@ -323,8 +332,8 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
      * Determine if playback file is streaming or local.
      * It is streaming if file name starts with "http://"
      * 
-     * @param file				The file name
-     * @return					T=streaming, F=local
+     * @param file              The file name
+     * @return                  T=streaming, F=local
      */
     public boolean isStreaming(String file) {
         if (file.contains("http://") || file.contains("https://")) {
@@ -338,10 +347,10 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     /**
       * Get the duration of the audio file.
       * 
-      * @param file				The name of the audio file.
-      * @return					The duration in msec.
-      * 							-1=can't be determined
-      * 							-2=not allowed
+      * @param file             The name of the audio file.
+      * @return                 The duration in msec.
+      *                             -1=can't be determined
+      *                             -2=not allowed
       */
     public float getDuration(String file) {
 
@@ -369,7 +378,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
     /**
      * Callback to be invoked when the media source is ready for playback. 
      * 
-     * @param mPlayer			The MediaPlayer that is ready for playback 
+     * @param mPlayer           The MediaPlayer that is ready for playback 
      */
     public void onPrepared(MediaPlayer mPlayer) {
         // Listen for playback completion
@@ -407,9 +416,9 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
      * Callback to be invoked when there has been an error during an asynchronous operation
      *  (other errors will throw exceptions at method call time).
      *  
-     * @param mPlayer			the MediaPlayer the error pertains to
-     * @param arg1				the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED)
-     * @param arg2				an extra code, specific to the error.
+     * @param mPlayer           the MediaPlayer the error pertains to
+     * @param arg1              the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED)
+     * @param arg2              an extra code, specific to the error.
      */
     public boolean onError(MediaPlayer mPlayer, int arg1, int arg2) {
         Log.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")");
diff --git a/framework/src/org/apache/cordova/ContactAccessor.java b/framework/src/org/apache/cordova/ContactAccessor.java
index 99c375af..f4ceed1d 100644
--- a/framework/src/org/apache/cordova/ContactAccessor.java
+++ b/framework/src/org/apache/cordova/ContactAccessor.java
@@ -18,8 +18,7 @@ package org.apache.cordova;
 
 import java.util.HashMap;
 
-//import android.app.Activity;
-//import android.content.Context;
+import android.content.Context;
 import android.util.Log;
 import android.webkit.WebView;
 
@@ -48,19 +47,19 @@ public abstract class ContactAccessor {
      * @param map created by running buildPopulationSet.
      * @return true if the key data is required
      */
-    protected boolean isRequired(String key, HashMap<String, Boolean> map) {
+    protected boolean isRequired(String key, HashMap<String,Boolean> map) {
         Boolean retVal = map.get(key);
         return (retVal == null) ? false : retVal.booleanValue();
     }
-
+    
     /**
      * Create a hash map of what data needs to be populated in the Contact object
      * @param fields the list of fields to populate
      * @return the hash map of required data
      */
-    protected HashMap<String, Boolean> buildPopulationSet(JSONArray fields) {
-        HashMap<String, Boolean> map = new HashMap<String, Boolean>();
-
+    protected HashMap<String,Boolean> buildPopulationSet(JSONArray fields) {
+        HashMap<String,Boolean> map = new HashMap<String,Boolean>();
+    
         String key;
         try {
             if (fields.length() == 1 && fields.getString(0).equals("*")) {
@@ -77,9 +76,9 @@ public abstract class ContactAccessor {
                 map.put("urls", true);
                 map.put("photos", true);
                 map.put("categories", true);
-            }
+           } 
             else {
-                for (int i = 0; i < fields.length(); i++) {
+                for (int i=0; i<fields.length(); i++) {
                     key = fields.getString(i);
                     if (key.startsWith("displayName")) {
                         map.put("displayName", true);
@@ -123,12 +122,13 @@ public abstract class ContactAccessor {
                     }
                 }
             }
-        } catch (JSONException e) {
+       }
+        catch (JSONException e) {
             Log.e(LOG_TAG, e.getMessage(), e);
         }
         return map;
     }
-
+  
     /**
      * Convenience method to get a string from a JSON object.  Saves a 
      * lot of try/catch writing.
@@ -148,9 +148,10 @@ public abstract class ContactAccessor {
                     value = null;
                 }
             }
-        } catch (JSONException e) {
+       }
+        catch (JSONException e) {
             Log.d(LOG_TAG, "Could not get = " + e.getMessage());
-        }
+        }   
         return value;
     }
 
@@ -176,25 +177,21 @@ public abstract class ContactAccessor {
      */
     public abstract boolean remove(String id);
 
-    /**
+   /**
      * A class that represents the where clause to be used in the database query 
      */
     class WhereOptions {
         private String where;
         private String[] whereArgs;
-
         public void setWhere(String where) {
             this.where = where;
         }
-
         public String getWhere() {
             return where;
         }
-
         public void setWhereArgs(String[] whereArgs) {
             this.whereArgs = whereArgs;
         }
-
         public String[] getWhereArgs() {
             return whereArgs;
         }
diff --git a/framework/src/org/apache/cordova/ContactAccessorSdk5.java b/framework/src/org/apache/cordova/ContactAccessorSdk5.java
index 0f41814b..ec7b39fd 100644
--- a/framework/src/org/apache/cordova/ContactAccessorSdk5.java
+++ b/framework/src/org/apache/cordova/ContactAccessorSdk5.java
@@ -25,7 +25,10 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -85,39 +88,39 @@ public class ContactAccessorSdk5 extends ContactAccessor {
      */
     private static final Map<String, String> dbMap = new HashMap<String, String>();
     static {
-        dbMap.put("id", ContactsContract.Data.CONTACT_ID);
-        dbMap.put("displayName", ContactsContract.Contacts.DISPLAY_NAME);
-        dbMap.put("name", ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
-        dbMap.put("name.formatted", ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
-        dbMap.put("name.familyName", ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
-        dbMap.put("name.givenName", ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
-        dbMap.put("name.middleName", ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME);
-        dbMap.put("name.honorificPrefix", ContactsContract.CommonDataKinds.StructuredName.PREFIX);
-        dbMap.put("name.honorificSuffix", ContactsContract.CommonDataKinds.StructuredName.SUFFIX);
-        dbMap.put("nickname", ContactsContract.CommonDataKinds.Nickname.NAME);
-        dbMap.put("phoneNumbers", ContactsContract.CommonDataKinds.Phone.NUMBER);
-        dbMap.put("phoneNumbers.value", ContactsContract.CommonDataKinds.Phone.NUMBER);
-        dbMap.put("emails", ContactsContract.CommonDataKinds.Email.DATA);
-        dbMap.put("emails.value", ContactsContract.CommonDataKinds.Email.DATA);
-        dbMap.put("addresses", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS);
-        dbMap.put("addresses.formatted", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS);
-        dbMap.put("addresses.streetAddress", ContactsContract.CommonDataKinds.StructuredPostal.STREET);
-        dbMap.put("addresses.locality", ContactsContract.CommonDataKinds.StructuredPostal.CITY);
-        dbMap.put("addresses.region", ContactsContract.CommonDataKinds.StructuredPostal.REGION);
-        dbMap.put("addresses.postalCode", ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE);
-        dbMap.put("addresses.country", ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY);
-        dbMap.put("ims", ContactsContract.CommonDataKinds.Im.DATA);
-        dbMap.put("ims.value", ContactsContract.CommonDataKinds.Im.DATA);
-        dbMap.put("organizations", ContactsContract.CommonDataKinds.Organization.COMPANY);
-        dbMap.put("organizations.name", ContactsContract.CommonDataKinds.Organization.COMPANY);
-        dbMap.put("organizations.department", ContactsContract.CommonDataKinds.Organization.DEPARTMENT);
-        dbMap.put("organizations.title", ContactsContract.CommonDataKinds.Organization.TITLE);
-        dbMap.put("birthday", ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
-        dbMap.put("note", ContactsContract.CommonDataKinds.Note.NOTE);
-        dbMap.put("photos.value", ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
-        //dbMap.put("categories.value", null);
-        dbMap.put("urls", ContactsContract.CommonDataKinds.Website.URL);
-        dbMap.put("urls.value", ContactsContract.CommonDataKinds.Website.URL);
+      dbMap.put("id", ContactsContract.Data.CONTACT_ID);
+      dbMap.put("displayName", ContactsContract.Contacts.DISPLAY_NAME);
+      dbMap.put("name", ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
+      dbMap.put("name.formatted", ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
+      dbMap.put("name.familyName", ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
+      dbMap.put("name.givenName", ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
+      dbMap.put("name.middleName", ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME);
+      dbMap.put("name.honorificPrefix", ContactsContract.CommonDataKinds.StructuredName.PREFIX);
+      dbMap.put("name.honorificSuffix", ContactsContract.CommonDataKinds.StructuredName.SUFFIX);
+      dbMap.put("nickname", ContactsContract.CommonDataKinds.Nickname.NAME);
+      dbMap.put("phoneNumbers", ContactsContract.CommonDataKinds.Phone.NUMBER);
+      dbMap.put("phoneNumbers.value", ContactsContract.CommonDataKinds.Phone.NUMBER);
+      dbMap.put("emails", ContactsContract.CommonDataKinds.Email.DATA);
+      dbMap.put("emails.value", ContactsContract.CommonDataKinds.Email.DATA);
+      dbMap.put("addresses", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS);
+      dbMap.put("addresses.formatted", ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS);
+      dbMap.put("addresses.streetAddress", ContactsContract.CommonDataKinds.StructuredPostal.STREET);
+      dbMap.put("addresses.locality", ContactsContract.CommonDataKinds.StructuredPostal.CITY);
+      dbMap.put("addresses.region", ContactsContract.CommonDataKinds.StructuredPostal.REGION);
+      dbMap.put("addresses.postalCode", ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE);
+      dbMap.put("addresses.country", ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY);
+      dbMap.put("ims", ContactsContract.CommonDataKinds.Im.DATA);
+      dbMap.put("ims.value", ContactsContract.CommonDataKinds.Im.DATA);
+      dbMap.put("organizations", ContactsContract.CommonDataKinds.Organization.COMPANY);
+      dbMap.put("organizations.name", ContactsContract.CommonDataKinds.Organization.COMPANY);
+      dbMap.put("organizations.department", ContactsContract.CommonDataKinds.Organization.DEPARTMENT);
+      dbMap.put("organizations.title", ContactsContract.CommonDataKinds.Organization.TITLE);
+      dbMap.put("birthday", ContactsContract.CommonDataKinds.Event.START_DATE);
+      dbMap.put("note", ContactsContract.CommonDataKinds.Note.NOTE);
+      dbMap.put("photos.value", ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
+      //dbMap.put("categories.value", null);
+      dbMap.put("urls", ContactsContract.CommonDataKinds.Website.URL);
+      dbMap.put("urls.value", ContactsContract.CommonDataKinds.Website.URL);
     }
 
     /**
@@ -536,67 +539,71 @@ public class ContactAccessorSdk5 extends ContactAccessor {
                     where.add("(" + dbMap.get(key) + " LIKE ? )");
                     whereArgs.add(searchTerm);
                 }
-                else if (key.startsWith("name")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
-                }
-                else if (key.startsWith("nickname")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE);
-                }
-                else if (key.startsWith("phoneNumbers")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
-                }
-                else if (key.startsWith("emails")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
-                }
-                else if (key.startsWith("addresses")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE);
-                }
-                else if (key.startsWith("ims")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
-                }
-                else if (key.startsWith("organizations")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
-                }
-                //        else if (key.startsWith("birthday")) {
-//          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
-//              + ContactsContract.Data.MIMETYPE + " = ? )");                 
-//        }
-                else if (key.startsWith("note")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE);
-                }
-                else if (key.startsWith("urls")) {
-                    where.add("(" + dbMap.get(key) + " LIKE ? AND "
-                            + ContactsContract.Data.MIMETYPE + " = ? )");
-                    whereArgs.add(searchTerm);
-                    whereArgs.add(ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE);
-                }
+        else if (key.startsWith("name")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
+        }
+        else if (key.startsWith("nickname")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");       
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE);
+        }
+        else if (key.startsWith("phoneNumbers")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");       
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
+        }
+        else if (key.startsWith("emails")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");       
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
+        }
+        else if (key.startsWith("addresses")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");       
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE);
+        }
+        else if (key.startsWith("ims")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");       
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
+        }
+        else if (key.startsWith("organizations")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");       
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
+        }
+        else if (key.startsWith("birthday")) {
+            try {
+                SimpleDateFormat format = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
+                Date searchDate = format.parse(searchTerm.substring(1, searchTerm.length()-1));
+                // Have to subtract one from the month as JavaScript's January is 01
+                // while Java's January is 00.
+                searchDate.setMonth(searchDate.getMonth()-1);
+                SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd");
+                
+                where.add("(" + dbMap.get(key) + " = ? AND " 
+                    + ContactsContract.Data.MIMETYPE + " = ? )");                 
+                whereArgs.add(newFormat.format(searchDate));
+                whereArgs.add(ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
             }
-        } catch (JSONException e) {
-            Log.e(LOG_TAG, e.getMessage(), e);
+            catch (ParseException e) {
+                Log.d(LOG_TAG, "Bad romance format");
+            }
+        }
+        else if (key.startsWith("note")) {
+          where.add("(" + dbMap.get(key) + " LIKE ? AND " 
+              + ContactsContract.Data.MIMETYPE + " = ? )");       
+          whereArgs.add(searchTerm);
+          whereArgs.add(ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE);
         }
 
         // Creating the where string
@@ -1128,18 +1135,47 @@ public class ContactAccessorSdk5 extends ContactAccessor {
             Log.d(LOG_TAG, "Could not get emails");
         }
 
-        // Modify note
-        String note = getJsonString(contact, "note");
-        ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
-                .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " +
-                        ContactsContract.Data.MIMETYPE + "=?",
-                        new String[] { id, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE })
-                .withValue(ContactsContract.CommonDataKinds.Note.NOTE, note)
-                .build());
+    // Modify note
+    String note = getJsonString(contact, "note");
+    ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+        .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + 
+            ContactsContract.Data.MIMETYPE + "=?", 
+            new String[]{id,ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE})
+            .withValue(ContactsContract.CommonDataKinds.Note.NOTE, note)
+        .build());
 
-        // Modify nickname
-        String nickname = getJsonString(contact, "nickname");
-        if (nickname != null) {
+    // Modify nickname
+    String nickname = getJsonString(contact, "nickname");
+    if (nickname != null) {
+      ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
+          .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + 
+              ContactsContract.Data.MIMETYPE + "=?", 
+              new String[]{id,ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE})
+              .withValue(ContactsContract.CommonDataKinds.Nickname.NAME, nickname)
+              .build());
+    }
+      
+    // Modify urls  
+    JSONArray websites = null;
+    try {
+      websites = contact.getJSONArray("urls");
+      if (websites != null) {
+        for (int i=0; i<websites.length(); i++) {
+          JSONObject website = (JSONObject)websites.get(i);
+          String websiteId = getJsonString(website, "id");
+          // This is a new website so do a DB insert
+          if (websiteId==null) {
+            ContentValues contentValues = new ContentValues();
+              contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId);
+              contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE);
+              contentValues.put(ContactsContract.CommonDataKinds.Website.DATA, getJsonString(website, "value"));
+                contentValues.put(ContactsContract.CommonDataKinds.Website.TYPE, getContactType(getJsonString(website, "type")));
+
+              ops.add(ContentProviderOperation.newInsert(
+                      ContactsContract.Data.CONTENT_URI).withValues(contentValues).build());            
+          }
+          // This is an existing website so do a DB update
+          else {
             ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
                     .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " +
                             ContactsContract.Data.MIMETYPE + "=?",
diff --git a/framework/src/org/apache/cordova/api/PluginResult.java b/framework/src/org/apache/cordova/api/PluginResult.java
index 8f5f7fdb..4d05ddd3 100755
--- a/framework/src/org/apache/cordova/api/PluginResult.java
+++ b/framework/src/org/apache/cordova/api/PluginResult.java
@@ -27,12 +27,12 @@ public class PluginResult {
     private final int status;
     private final String message;
     private boolean keepCallback = false;
-
+    
     public PluginResult(Status status) {
         this.status = status.ordinal();
         this.message = "'" + PluginResult.StatusMessages[this.status] + "'";
     }
-
+    
     public PluginResult(Status status, String message) {
         this.status = status.ordinal();
         this.message = JSONObject.quote(message);
@@ -50,23 +50,23 @@ public class PluginResult {
 
     public PluginResult(Status status, int i) {
         this.status = status.ordinal();
-        this.message = "" + i;
+        this.message = ""+i;
     }
 
     public PluginResult(Status status, float f) {
         this.status = status.ordinal();
-        this.message = "" + f;
+        this.message = ""+f;
     }
 
     public PluginResult(Status status, boolean b) {
         this.status = status.ordinal();
-        this.message = "" + b;
+        this.message = ""+b;
     }
-
+    
     public void setKeepCallback(boolean b) {
         this.keepCallback = b;
     }
-
+    
     public int getStatus() {
         return status;
     }
@@ -74,36 +74,36 @@ public class PluginResult {
     public String getMessage() {
         return message;
     }
-
+    
     public boolean getKeepCallback() {
         return this.keepCallback;
     }
-
+    
     public String getJSONString() {
-        return "{status:" + this.status + ",message:" + this.message + ",keepCallback:" + this.keepCallback + "}";
+        return "{\"status\":" + this.status + ",\"message\":" + this.message + ",\"keepCallback\":" + this.keepCallback + "}";
     }
-
+    
     public String toSuccessCallbackString(String callbackId) {
-        return "cordova.callbackSuccess('" + callbackId + "'," + this.getJSONString() + ");";
+        return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
     }
-
+    
     public String toErrorCallbackString(String callbackId) {
-        return "cordova.callbackError('" + callbackId + "', " + this.getJSONString() + ");";
+        return "cordova.callbackError('"+callbackId+"', " + this.getJSONString()+ ");";
     }
-
+    
     public static String[] StatusMessages = new String[] {
-            "No result",
-            "OK",
-            "Class not found",
-            "Illegal access",
-            "Instantiation error",
-            "Malformed url",
-            "IO error",
-            "Invalid action",
-            "JSON error",
-            "Error"
+        "No result",
+        "OK",
+        "Class not found",
+        "Illegal access",
+        "Instantiation error",
+        "Malformed url",
+        "IO error",
+        "Invalid action",
+        "JSON error",
+        "Error"
     };
-
+    
     public enum Status {
         NO_RESULT,
         OK,