Merge "FTP: Handle Abort exception in onPut Request."
diff --git a/src/org/codeaurora/bluetooth/btcservice/BTCEventProvider.java b/src/org/codeaurora/bluetooth/btcservice/BTCEventProvider.java
index 3ec668c..0e317d3 100644
--- a/src/org/codeaurora/bluetooth/btcservice/BTCEventProvider.java
+++ b/src/org/codeaurora/bluetooth/btcservice/BTCEventProvider.java
@@ -53,8 +53,8 @@
 
 public class BTCEventProvider extends BroadcastReceiver {
     private static final String TAG = "BTCEventProvider";
-    private static final boolean D = /*Constants.DEBUG*/true;
-    private static final boolean V = true/*Constants.VERBOSE*/;
+    private static final boolean D = /*Constants.DEBUG*/false;
+    private static final boolean V = false/*Constants.VERBOSE*/;
     private int state;
     BTCService.BTCEvent event = BTCService.BTCEvent.BLUETOOTH_NONE;
 
@@ -72,7 +72,7 @@
                 if (service != null) {
                     event =  BTCService.BTCEvent.BLUETOOTH_ON;
                 } else {
-                    Log.e(TAG, "Could Not Start BTC Service ");
+                    if (D) Log.d(TAG, "Could Not Start BTC Service ");
                     return;
                 }
             } else if (BluetoothAdapter.STATE_OFF == state) {
@@ -125,10 +125,10 @@
             if (V) Log.v(TAG, "BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED");
             state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR);
             if (BluetoothA2dp.STATE_PLAYING == state) {
-                if (V) Log.v(TAG, "A2DP. PLAYING_STATE_CHANGED: CONNECTED");
+                if (V) Log.v(TAG, "A2DP. PLAYING_STATE_CHANGED: PLAYING");
                 event =  BTCService.BTCEvent.BLUETOOTH_SINK_STREAM_STARTED;
             } else if (BluetoothA2dp.STATE_NOT_PLAYING == state) {
-                if (V) Log.v(TAG, "A2DP.PLAYING_STATE_CHANGED: DISCONNECTED");
+                if (V) Log.v(TAG, "A2DP.PLAYING_STATE_CHANGED: PLAYING_STOPPED");
                 event =  BTCService.BTCEvent.BLUETOOTH_SINK_STREAM_STOPPED;
             }
         } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
@@ -150,10 +150,10 @@
               if (V) Log.v(TAG, "Event:" + event.getValue() + "Written Succesfully");
            }
            else {
-              Log.e(TAG, "Error while sending Event:" + event.getValue());
+              if (D) Log.d(TAG, "Error while sending Event:" + event.getValue());
            }
            if (event ==  BTCService.BTCEvent.BLUETOOTH_OFF) {
-               Log.v(TAG, "Stop the BTC Service");
+               if (V) Log.v(TAG, "Stop the BTC Service");
                context.stopService(new Intent(context, BTCService.class));
            }
         }
diff --git a/src/org/codeaurora/bluetooth/btcservice/BTCService.java b/src/org/codeaurora/bluetooth/btcservice/BTCService.java
index c1a8c82..ff3c6df 100644
--- a/src/org/codeaurora/bluetooth/btcservice/BTCService.java
+++ b/src/org/codeaurora/bluetooth/btcservice/BTCService.java
@@ -79,6 +79,8 @@
     private static OutputStream mOutputStream = null;
     private static Thread mSocketAcceptThread;
     private static boolean mLocalConnectInitiated = false;
+    private static final boolean D = false/*Constants.DEBUG*/;
+    private static final boolean V = false/*Constants.VERBOSE*/;
     private static final Object mLock = new Object();
 
     public enum BTCEvent {
@@ -119,16 +121,16 @@
         if (mSocket != null) {
             mSocket.close();
             mSocket = null;
-            Log.v(LOGTAG, "Server Socket closed");
+            if (V) Log.v(LOGTAG, "Server Socket closed");
         }
         if (mRemoteSocket != null) {
             mRemoteSocket.close();
             mRemoteSocket = null;
-            Log.v(LOGTAG, "Client Socket closed");
+            if (V) Log.v(LOGTAG, "Client Socket closed");
         }
         if( mSocketAcceptThread != null ) {
             mSocketAcceptThread.interrupt();
-            Log.v(LOGTAG, "Acceptor thread stopped");
+            if (V) Log.v(LOGTAG, "Acceptor thread stopped");
         }
     }
     }
@@ -142,9 +144,9 @@
      *        -2 when there is issue while writing on client socket.
      */
     static public int sendEvent(BTCEvent event) {
-        Log.v(LOGTAG, "sendEvent: " + event.getValue());
+        if (V) Log.v(LOGTAG, "sendEvent: " + event.getValue());
         if (mRemoteSocket == null) {
-            Log.v(LOGTAG, "No Valid Connection" );
+            if(D) Log.d(LOGTAG, "No Valid Connection" );
             return -1;
         }
 
@@ -155,8 +157,8 @@
             mOutputStream.write(buffer.array());
         }
         catch (java.io.IOException e) {
-            Log.e(LOGTAG, "Error while posting the event: " + event + "Error:" + e);
-            Log.e(LOGTAG, "connectoin is closed for Unknown reason, restart the acceptor thread ");
+            if (D) Log.d(LOGTAG, "Error while posting the event: " + event + "Error:" + e);
+            if (D) Log.d(LOGTAG, "connectoin is closed for Unknown reason, restart the acceptor thread ");
             startListener();
             return -2;
         }
@@ -176,7 +178,7 @@
         public void run() {
         do {
            try {
-               Log.v(LOGTAG, "Waiting for connection...");
+               if (V) Log.v(LOGTAG, "Waiting for connection...");
                try {
                    mRemoteSocket = mSocket.accept();
                } catch (java.io.IOException e) {
@@ -187,7 +189,7 @@
                if (mLocalConnectInitiated) {
                    //This is just a local connection
                    //to unblock the accept
-                   Log.e(LOGTAG, "Terminator in action: ");
+                   if (D) Log.d(LOGTAG, "Terminator in action: ");
                    cleanupService();
                    mLocalConnectInitiated = false;
                    return;
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasAppEmail.java b/src/org/codeaurora/bluetooth/map/BluetoothMasAppEmail.java
index 27fc0cd..7d1f99e 100644
--- a/src/org/codeaurora/bluetooth/map/BluetoothMasAppEmail.java
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasAppEmail.java
@@ -82,9 +82,9 @@
 
     private ContentObserver mObserver;
     private static final int[] SPECIAL_MAILBOX_TYPES
-            = {TYPE_DELETED, TYPE_DRAFT, TYPE_INBOX, TYPE_OUTBOX, TYPE_SENT};
+            = {TYPE_INBOX, TYPE_DRAFT, TYPE_OUTBOX, TYPE_SENT, TYPE_DELETED};
     private static final String[] SPECIAL_MAILBOX_MAP_NAME
-            = {DELETED, DRAFT, INBOX, OUTBOX, SENT};
+            = {INBOX, DRAFT, OUTBOX, SENT, DELETED};
     private HashMap<Integer, String> mSpecialMailboxName = new HashMap<Integer, String>();
 
     public BluetoothMasAppEmail(Context context, Handler handler, BluetoothMns mnsClient,
@@ -160,7 +160,7 @@
                 curType = SPECIAL_MAILBOX_TYPES[i];
                 if (V) Log.v(TAG, " getCompleteFolderList: Current Type: " + curType);
                 for (String str : list) {
-                    type = EmailUtils.getTypeForFolder(mContext, id, str);
+                    type = EmailUtils.getTypeForFolderAtPath(mContext, id, str);
                     if (V) Log.v(TAG, " getCompleteFolderList: type: " + type);
                     if (type == curType) {
                         if (V) Log.v(TAG, " getCompleteFolderList: removing folder : " + str);
@@ -170,16 +170,13 @@
                 }
                 if (!list.contains(SPECIAL_MAILBOX_MAP_NAME[i])) {
                     if (V) Log.v(TAG, " getCompleteFolderList: adding default folder : "
-                        + SPECIAL_MAILBOX_MAP_NAME[i]);
-                    list.add(SPECIAL_MAILBOX_MAP_NAME[i]);
+                        + SPECIAL_MAILBOX_MAP_NAME[i] + "i:" + i);
+                    list.add(i,SPECIAL_MAILBOX_MAP_NAME[i]);
                 }
             }
             for (String str : list) {
-                type = EmailUtils.getTypeForFolder(mContext, id, str);
-                if (type <= ((EmailUtils.TYPE_DELETED) + 1)) {
                     if (V) Log.v(TAG, " getCompleteFolderList: Adding a valid folder:" + str);
                     finalList.add(str);
-                }
             }
         }
         else {
@@ -191,7 +188,6 @@
                 String folderStr = str.substring(path.length()+ 1);
                 String folder[] = folderStr.split("/");
                 if(folder.length == 1){
-                    type = EmailUtils.getTypeForFolder(mContext, id, folder[0]);
                     if (V) Log.v(TAG, " getCompleteFolderList: Add Folder:" + folder[0]);
                     finalList.add(folder[0]);
                 }
@@ -502,6 +498,7 @@
         if (accountId == -1) {
             accountId = EmailUtils.getAccountId(mMasId);
         }
+        String whereClause = "UPPER(displayName) = '"+folder.toUpperCase().trim()+"'";
         if (DRAFT.equalsIgnoreCase(folder)) {
             List<String> folders = EmailUtils.getFoldersForType(mContext, accountId,
                     EmailUtils.TYPE_DRAFT);
@@ -515,9 +512,9 @@
             } else {
                 folder = folders.get(0);
             }
+            whereClause = "TYPE = '"+EmailUtils.TYPE_DRAFT+"'";
         }
 
-        String whereClause = "UPPER(displayName) = '"+folder.toUpperCase().trim()+"'";
         cr = mContext.getContentResolver().query(
                 Uri.parse("content://com.android.email.provider/mailbox"),
                 null, whereClause, null, null);
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasAppSmsMms.java b/src/org/codeaurora/bluetooth/map/BluetoothMasAppSmsMms.java
index 69fe818..68fa1e6 100644
--- a/src/org/codeaurora/bluetooth/map/BluetoothMasAppSmsMms.java
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasAppSmsMms.java
@@ -39,6 +39,7 @@
 import android.telephony.SmsManager;
 import android.telephony.SmsMessage;
 import android.telephony.TelephonyManager;
+import android.provider.Telephony.Threads;
 import android.text.format.Time;
 import android.util.Log;
 import android.util.TimeFormatException;
@@ -772,8 +773,9 @@
             String address = cr.getString(cr.getColumnIndex("address"));
 
             // Search the database for the given address
-            Cursor crThreadId = mContext.getContentResolver().query(Uri.parse("content://sms/"),
-                    null, "address = " + address + " AND thread_id != -1", null, null);
+            String whereClause = "address = '" + address + "' AND thread_id != -1" ;
+            Cursor crThreadId = mContext.getContentResolver().query(Uri.parse("content://sms/"),null,
+                                    whereClause, null, null);
             if (crThreadId != null && crThreadId.moveToFirst()) {
                 // A thread for the given address exists in the database
                 String threadIdStr = crThreadId.getString(crThreadId.getColumnIndex("thread_id"));
@@ -1255,6 +1257,63 @@
         }
         return folderName;
     }
+    /**
+     * Get SMS RecipientAddresses for DRAFT folder based on threadId
+     *
+    */
+    private String getMessageSmsRecipientAddress(int threadId){
+       String [] RECIPIENT_ID_PROJECTION = { "recipient_ids" };
+        /*
+         1. Get Recipient Ids from Threads.CONTENT_URI
+         2. Get Recipient Address for corresponding Id from canonical-addresses table.
+        */
+
+        Uri sAllCanonical = Uri.parse("content://mms-sms/canonical-addresses");
+        Uri sAllThreadsUri =  Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true").build();
+        Cursor cr = null;
+        String recipientAddress= "";
+        String recipientIds = null;
+        String whereClause = "_id="+threadId;
+        cr = mContext.getContentResolver().query(sAllThreadsUri, RECIPIENT_ID_PROJECTION, whereClause, null,
+                null);
+        if (cr != null && cr.moveToFirst()) {
+            recipientIds = cr.getString(0);
+            if (V) Log.v(TAG, "cursor.getCount(): " + cr.getCount() + "recipientIds: "+ recipientIds +"whrClus: "+ whereClause );
+        }
+        if(cr != null){
+            cr.close();
+            cr = null;
+        }
+
+        if (V) Log.v(TAG, "recipientIds with spaces: "+ recipientIds +"\n");
+
+        if(recipientIds != null) {
+           String recipients[] = null;
+           whereClause = "";
+           recipients = recipientIds.split(" ");
+           for (String id: recipients) {
+                if(whereClause.length() != 0)
+                   whereClause +=" OR ";
+                whereClause +="_id="+id;
+           }
+           cr = mContext.getContentResolver().query(sAllCanonical , null, whereClause, null, null);
+           if (cr != null && cr.moveToFirst()) {
+              do {
+                //TODO: Multiple Recipeints are appended with ";" for now.
+                if(recipientAddress.length() != 0 )
+                   recipientAddress+=";";
+                recipientAddress+=cr.getString(cr.getColumnIndex("address"));
+              } while(cr.moveToNext());
+           }
+           if(cr != null)
+              cr.close();
+
+        }
+
+        if(V) Log.v(TAG,"Final recipientAddress : "+ recipientAddress);
+        return recipientAddress;
+
+     }
 
     /**
      * Build an MMS bMessage when given a message handle
@@ -2046,6 +2105,7 @@
             int subjectInd = cursor.getColumnIndex("subject");
             int typeInd = cursor.getColumnIndex("type");
             int bodyInd = cursor.getColumnIndex("body");
+            int threadIdInd = cursor.getColumnIndex("thread_id");
 
             do {
                 /*
@@ -2146,6 +2206,11 @@
                 String timestampSms = cursor.getString(dateInd);
                 String addressSms = cursor.getString(addressInd);
                 String readStatusSms = cursor.getString(readInd);
+                String threadIdStr = cursor.getString(threadIdInd);
+                if(addressSms == null &&( DRAFT.equalsIgnoreCase(folder) || DRAFTS.equalsIgnoreCase(folder))) {
+                      addressSms = getMessageSmsRecipientAddress(Integer.valueOf(threadIdStr));
+                      if(V)  Log.v(TAG, "threadId = " + threadIdStr + " adressSms:" + addressSms +"\n");
+                }
 
                 MsgListingConsts ml = bldSmsMsgLstItem(appParams, subjectSms,
                                 timestampSms, addressSms, msgIdSms,
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasService.java b/src/org/codeaurora/bluetooth/map/BluetoothMasService.java
old mode 100644
new mode 100755
index 416d462..08e518d
--- a/src/org/codeaurora/bluetooth/map/BluetoothMasService.java
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasService.java
@@ -79,9 +79,6 @@
      */
     public static final boolean DEBUG = true;
     public static final boolean VERBOSE = true;
-  //  public static final boolean DEBUG = false;
-    //public static final boolean VERBOSE = false;
-
     /**
      * Intent indicating incoming connection request which is sent to
      * BluetoothMasActivity
@@ -423,6 +420,7 @@
                }
             }
 
+            removeTimeoutMsg = false;
         } else {
             removeTimeoutMsg = false;
         }
@@ -547,12 +545,12 @@
             getString(R.string.map_notif_ticker), System.currentTimeMillis());
         notification.setLatestEventInfo(this, getString(R.string.map_notif_ticker),
                 getString(R.string.map_notif_message, name), PendingIntent
-                        .getActivity(this, 0, clickIntent, 0));
+                        .getActivity(this, 0, clickIntent, PendingIntent.FLAG_ONE_SHOT));
 
         notification.flags |= Notification.FLAG_AUTO_CANCEL;
         notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
         notification.defaults = Notification.DEFAULT_SOUND;
-        notification.deleteIntent = PendingIntent.getBroadcast(this, 0, deleteIntent, 0);
+        notification.deleteIntent = PendingIntent.getBroadcast(this, 0, deleteIntent, PendingIntent.FLAG_ONE_SHOT);
         nm.notify(NOTIFICATION_ID_ACCESS, notification);
 
 
@@ -766,7 +764,6 @@
             // It's possible that create will fail in some cases. retry for 10 times
             for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) {
                 try {
-                    //mServerSocket = mAdapter.listenUsingRfcommOn(mPortNum);
                     if(mPortNum == MAS1_PORT_NUM)
                        mServerSocket  = mAdapter.listenUsingRfcommWithServiceRecord("Email Message Access", MessageAccessServer.getUuid());
                     else
@@ -990,11 +987,9 @@
                         }
                         stopped = true; // job done ,close this thread;
                     } catch (IOException ex) {
-                        if (stopped) {
-                            break;
-                        }
                         if (VERBOSE)
                             Log.v(TAG, "Accept exception: " + ex.toString());
+                        stopped = true; // close this thread from exception.
                     }
                 }
             }
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMnsObexSession.java b/src/org/codeaurora/bluetooth/map/BluetoothMnsObexSession.java
index 6430ecc..fdd9285 100644
--- a/src/org/codeaurora/bluetooth/map/BluetoothMnsObexSession.java
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMnsObexSession.java
@@ -174,9 +174,7 @@
                          val);
         request.setHeader(HeaderSet.TYPE, TYPE_EVENT);
         request.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getAPPparam());
-
-        request.mConnectionID = new byte[4];
-        System.arraycopy(hsConnect.mConnectionID, 0, request.mConnectionID, 0, 4);
+        request.setHeader(HeaderSet.CONNECTION_ID, hsConnect.mConnectionID);
 
         ClientOperation putOperation = null;
         OutputStream outputStream = null;
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/EmailUtils.java b/src/org/codeaurora/bluetooth/map/MapUtils/EmailUtils.java
index 62da953..dde8b25 100755
--- a/src/org/codeaurora/bluetooth/map/MapUtils/EmailUtils.java
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/EmailUtils.java
@@ -611,6 +611,16 @@
                         bmsg.setRecipientVcard_email(multiRecepients.trim());
                     }
                 }
+                else if(recipientName.contains(",")){
+                    multiRecepients = recipientName.replace(',', ';');
+                    if(multiRecepients != null){
+                        if (V){
+                            Log.v(TAG, " ::Recepient name :: " + multiRecepients);
+                        }
+                        bmsg.setRecipientVcard_name(multiRecepients.trim());
+                        bmsg.setRecipientVcard_email(multiRecepients.trim());
+                    }
+                }
                 else{
                     bmsg.setRecipientVcard_name(recipientName.trim());
                     bmsg.setRecipientVcard_email(recipientName.trim());
@@ -631,8 +641,6 @@
             StringBuilder sb = new StringBuilder();
             String emailBody = null;
 
-            //Set content type according to content from body table
-            String contenType = "text/plain";
             if (cr2.getCount() > 0) {
                 cr2.moveToFirst();
                 emailBody = cr2.getString(cr2.getColumnIndex("textContent"));
@@ -1054,4 +1062,19 @@
         sb.append("'"+folderName+"'");
         return SqlHelper.getFirstIntForColumn(context, EMAIL_BOX_URI, TYPE, sb.toString(), null);
     }
+    public static int getTypeForFolderAtPath(Context context, long id, String path) {
+
+        if (V) Log.v(TAG, "getTypeForFolder: id = " + id + ", folderName = " + path);
+        StringBuilder sb = new StringBuilder();
+        if (id > 0) {
+            sb.append(ACCOUNT_KEY);
+            sb.append("=");
+            sb.append(id);
+            sb.append(" AND ");
+        }
+        sb.append(SERVER_ID);
+        sb.append("=");
+        sb.append("'"+path+"'");
+        return SqlHelper.getFirstIntForColumn(context, EMAIL_BOX_URI, TYPE, sb.toString(), null);
+    }
 }
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/MapUtils.java b/src/org/codeaurora/bluetooth/map/MapUtils/MapUtils.java
old mode 100644
new mode 100755
index f2f6f31..45656a9
--- a/src/org/codeaurora/bluetooth/map/MapUtils/MapUtils.java
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/MapUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -835,36 +835,73 @@
             // End Originator
 
             sb.append("BEGIN:BENV").append("\r\n");
+            if ((bmsg.recipient_vcard_email != null) &&
+                            (bmsg.recipient_vcard_email.contains(";"))) {
+                if (V) Log.v (TAG, "recipient_vcard_name:" + bmsg.recipient_vcard_name);
+                if (V) Log.v (TAG, "recipient_vcard_phone_number:" + bmsg.recipient_vcard_email);
+                String emailTokens[] = bmsg.recipient_vcard_email.split(";");
+                String nameTokens[] = bmsg.recipient_vcard_name.split(";");
+                if (V) Log.v (TAG, "Length:name:" + nameTokens.length + "number:" + emailTokens.length);
+                for (int i=0; i < emailTokens.length; i++) {
+                    // Recipient
+                    sb.append("BEGIN:VCARD").append("\r\n");
 
-            // Recipient
-            sb.append("BEGIN:VCARD").append("\r\n");
+                    if (bmsg.vcard_version != null) {
+                        sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+                    } else {
 
-            if (bmsg.vcard_version != null) {
-                sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+                    }
+
+                    if (nameTokens[i] != null) {
+                        sb.append("N:").append(nameTokens[i])
+                            .append("\r\n");
+                        sb.append("FN:").append(nameTokens[i])
+                           .append("\r\n");
+                    } else {
+
+                    }
+                    sb.append("TEL:").append("\r\n");
+
+                    if (emailTokens[i] != null) {
+                        sb.append("EMAIL:").append(emailTokens[i])
+                            .append("\r\n");
+                    } else {
+
+                    }
+
+                    sb.append("END:VCARD").append("\r\n");
+                    // End Recipient
+                }
             } else {
+                // Recipient
+                sb.append("BEGIN:VCARD").append("\r\n");
+                if (bmsg.vcard_version != null) {
+                   sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+                } else {
 
-            }
-            if (bmsg.recipient_vcard_name != null) {
-                sb.append("N:").append(bmsg.recipient_vcard_name)
+                }
+                if (bmsg.recipient_vcard_name != null) {
+                   sb.append("N:").append(bmsg.recipient_vcard_name)
                         .append("\r\n");
-            } else {
+                } else {
 
-            }
-            if (bmsg.recipient_vcard_name != null) {
-                sb.append("FN:").append(bmsg.recipient_vcard_name)
+                }
+                if (bmsg.recipient_vcard_name != null) {
+                   sb.append("FN:").append(bmsg.recipient_vcard_name)
                         .append("\r\n");
-            } else {
+                } else {
 
-            }
-            sb.append("TEL:").append("\r\n");
-            if (bmsg.recipient_vcard_email != null) {
-                sb.append("EMAIL:").append(bmsg.recipient_vcard_email)
+                }
+                sb.append("TEL:").append("\r\n");
+                if (bmsg.recipient_vcard_email != null) {
+                   sb.append("EMAIL:").append(bmsg.recipient_vcard_email)
                         .append("\r\n");
-            } else {
+                } else {
 
+                }
+                sb.append("END:VCARD").append("\r\n");
+                // End Recipient
             }
-            sb.append("END:VCARD").append("\r\n");
-            // End Recipient
 
             sb.append("BEGIN:BBODY").append("\r\n");
 
@@ -922,7 +959,7 @@
 
         RecipientVCard recipient = parseVCard(vCard);
         if (recipient.mTel.length() == 0 || recipient.mTel.contains(",") || recipient.mTel.contains(";")) {
-            throw new BadRequestException("No TEL in vCard");
+            throw new BadRequestException("Invalid TEL in vCard");
         }
         bMsgObj.setRecipientVcard_phone_number(recipient.mTel);
         if (V) Log.v(TAG, "Tel: " + recipient.mTel);
@@ -975,11 +1012,11 @@
         RecipientVCard recipient = parseVCard(vCard);
         if (recipient.mEmail.length() > 0) {
             phoneNumber = recipient.mEmail;
-        } else if (recipient.mTel.length() == 0 || recipient.mTel.contains(",")
-            || recipient.mTel.contains(";")) {
+        } else if (!(recipient.mTel.length() == 0 || recipient.mTel.contains(",")
+            || recipient.mTel.contains(";"))) {
             phoneNumber = recipient.mTel;
         } else {
-            throw new BadRequestException("No Email/Tel in vCard");
+            throw new BadRequestException("Invalid Email/Tel in vCard");
         }
 
         if (V) Log.v(TAG, "Email: " + recipient.mEmail);
@@ -1509,8 +1546,11 @@
         if (pos > 0) {
             int beginVersionPos = pos
                     + (("BEGIN:MSG").length() + CRLF.length());
-            int endVersionPos = (body.indexOf("END:MSG", beginVersionPos) - CRLF
-                    .length());
+            int endVersionPos = body.lastIndexOf("\r\nEND:MSG");
+            if(endVersionPos == -1){
+                Log.v(TAG, "ill-Formatted END:MSG bMessage");
+                return "";
+            }
             return body.substring(beginVersionPos, endVersionPos);
         } else {
             return "";