diff --git a/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java b/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java
index a493abdf6f2479b600adab2d7e24f516be1b9d86..1e3f315f91c01a72d46bb2dcc4e885f35ce3a0f4 100644
--- a/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java
@@ -52,7 +52,6 @@ import android.widget.TextView;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -101,18 +100,20 @@ public class ConversationActivity extends AppCompatActivity {
             conversation = service.getConversation(conv_id);
             if (conversation == null) {
                 long contact_id = CallContact.contactIdFromId(conv_id);
-                CallContact contact;
+                CallContact contact = null;
                 if (contact_id >= 0)
                     contact = service.findContactById(contact_id);
-                else if (preferredNumber != null && !preferredNumber.isEmpty()) {
-                    contact = service.findContactByNumber(preferredNumber);
-                    if (contact == null)
-                        contact = CallContact.ContactBuilder.buildUnknownContact(conv_id);
-                } else {
-                    contact = service.findContactByNumber(conv_id);
-                    if (contact == null)
-                        contact = CallContact.ContactBuilder.buildUnknownContact(conv_id);
-                    preferredNumber = conv_id;
+                if (contact == null) {
+                    if (preferredNumber != null && !preferredNumber.isEmpty()) {
+                        contact = service.findContactByNumber(preferredNumber);
+                        if (contact == null)
+                            contact = CallContact.buildUnknown(conv_id);
+                    } else {
+                        contact = service.findContactByNumber(conv_id);
+                        if (contact == null)
+                            contact = CallContact.buildUnknown(conv_id);
+                        preferredNumber = conv_id;
+                    }
                 }
                 conversation = service.startConversation(contact);
             }
diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
index ffd2c5c46a9639af892018f862d2891da220b521..de2090da95e09ee3f35d14153f0a8ac79993074f 100644
--- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
@@ -138,21 +138,6 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_home);
 
-        // Bind to LocalService
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(LocalService.ACTION_CONF_UPDATE);
-        intentFilter.addAction(LocalService.ACTION_ACCOUNT_UPDATE);
-        registerReceiver(receiver, intentFilter);
-
-        if (!mBound && LocalService.checkContactPermissions(this)) {
-            Log.i(TAG, "onStart: Binding service...");
-            /*Intent intent = new Intent(this, SipService.class);
-            startService(intent);
-            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);*/
-            Intent intent = new Intent(this, LocalService.class);
-            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
-        }
 
         toolbar = (Toolbar) findViewById(R.id.main_toolbar);
         setSupportActionBar(toolbar);
@@ -184,6 +169,20 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
 
         mNavigationDrawer.setDrawerListener(mDrawerToggle);
 
+        // Bind to LocalService
+
+        String[] toRequest = LocalService.checkRequiredPermissions(this);
+        if (toRequest.length > 0) {
+            ActivityCompat.requestPermissions(this, toRequest, LocalService.PERMISSIONS_REQUEST);
+        } else if (!mBound) {
+            Log.i(TAG, "onCreate: Binding service...");
+            /*Intent intent = new Intent(this, SipService.class);
+            startService(intent);
+            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);*/
+            Intent intent = new Intent(this, LocalService.class);
+            startService(intent);
+            bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+        }
     }
 
     final BroadcastReceiver receiver = new BroadcastReceiver() {
@@ -229,13 +228,24 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
         Log.w(TAG, "onRequestPermissionsResult");
 
         switch (requestCode) {
-            case LocalService.PERMISSIONS_REQUEST_READ_CONTACTS: {
+            case LocalService.PERMISSIONS_REQUEST: {
+                if (grantResults.length == 0) {
+                    finish();
+                    return;
+                }
+                for (int grantResult : grantResults) {
+                    if (grantResult != PackageManager.PERMISSION_GRANTED) {
+                        finish();
+                        return;
+                    }
+                }
                 // If request is cancelled, the result arrays are empty.
                 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                     Log.w(TAG, "onRequestPermissionsResult granted");
 
                     if (!mBound) {
                         Intent intent = new Intent(this, LocalService.class);
+                        startService(intent);
                         bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
                     }
 
@@ -370,8 +380,8 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        unregisterReceiver(receiver);
         if (mBound) {
+            unregisterReceiver(receiver);
             unbindService(mConnection);
             mBound = false;
         }
@@ -402,6 +412,10 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
             Log.i(TAG, "onServiceConnected " + className.getClassName());
             LocalService.LocalBinder binder = (LocalService.LocalBinder) s;
             service = binder.getService();
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(LocalService.ACTION_CONF_UPDATE);
+            intentFilter.addAction(LocalService.ACTION_ACCOUNT_UPDATE);
+            registerReceiver(receiver, intentFilter);
 
             fContent = new CallListFragment();
             if (fMenuHead != null)
@@ -590,7 +604,7 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call
             args.putParcelable(SipCall.ACCOUNT, usedAccount);
             args.putInt(SipCall.STATE, SipCall.State.NONE);
             args.putInt(SipCall.TYPE, SipCall.Direction.OUTGOING);
-            args.putParcelable(SipCall.CONTACT, CallContact.ContactBuilder.buildUnknownContact(to));
+            args.putParcelable(SipCall.CONTACT, CallContact.ContactBuilder.buildUnknown(to));
 
             try {
                 launchCallActivity(new SipCall(args));
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java
index bc842b04e9b117ae0077f97d976674179a4b3a9d..327c8a5fd26c1dbe3695ff5a95723a05e75aa2bf 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java
@@ -60,7 +60,6 @@ import cx.ring.R;
 import cx.ring.adapters.ContactPictureTask;
 import cx.ring.adapters.ContactsAdapter;
 import cx.ring.adapters.StarredContactsAdapter;
-import cx.ring.client.AccountWizard;
 import cx.ring.client.ConversationActivity;
 import cx.ring.client.HomeActivity;
 import cx.ring.client.NewConversationActivity;
@@ -260,7 +259,7 @@ public class CallListFragment extends Fragment implements SearchView.OnQueryText
         getLoaderManager().restartLoader(LoaderConstants.CONTACT_LOADER, b, this);
         newcontact.setVisibility(View.VISIBLE);
         ((TextView)newcontact.findViewById(R.id.display_name)).setText("Call \"" + query + "\"");
-        CallContact contact = CallContact.ContactBuilder.buildUnknownContact(query);
+        CallContact contact = CallContact.buildUnknown(query);
         newcontact.setTag(contact);
         return true;
     }
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java
index 02ce5e7af762769b11eec9adc74192b1b0750e74..cc41c2a6fec37d97172b264c02c37f3e3bdf57b4 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java
@@ -51,10 +51,8 @@ import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.MeasureSpec;
-import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
@@ -66,8 +64,6 @@ import android.widget.SearchView;
 import android.widget.SearchView.OnQueryTextListener;
 import android.widget.TextView;
 
-import java.util.ArrayList;
-
 public class ContactListFragment extends Fragment implements OnQueryTextListener, LoaderManager.LoaderCallbacks<ContactsLoader.Result> {
     public static final String TAG = "ContactListFragment";
     ContactsAdapter mListAdapter;
@@ -206,7 +202,7 @@ public class ContactListFragment extends Fragment implements OnQueryTextListener
         getLoaderManager().restartLoader(LoaderConstants.CONTACT_LOADER, b, this);
         newcontact.setVisibility(View.VISIBLE);
         ((TextView)newcontact.findViewById(R.id.display_name)).setText("Call \"" + newText + "\"");
-        CallContact contact = CallContact.ContactBuilder.buildUnknownContact(newText);
+        CallContact contact = CallContact.buildUnknown(newText);
         newcontact.setTag(contact);
         return true;
     }
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java
index 808aa2cc2789c3f4466920775f796aa35cc1ae1c..e1805a492f51dbb165589bc2e03324c1eec4dc39 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java
@@ -187,7 +187,7 @@ public class MenuFragment extends Fragment {
             }
         });
 
-        CallContact user = CallContact.ContactBuilder.buildUserContact(getActivity().getContentResolver());
+        CallContact user = CallContact.buildUserContact(getActivity());
         new ContactPictureTask(getActivity(), (ImageView) inflatedView.findViewById(R.id.user_photo), user).run();
 
         ((TextView) inflatedView.findViewById(R.id.user_name)).setText(user.getDisplayName());
diff --git a/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java b/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java
index 0a08ba3da47ee29b52b66faf1b5f1cdd88702775..243a508f9f0a3e12ebb48cd7e6e2af064ff6c02a 100644
--- a/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java
+++ b/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java
@@ -24,7 +24,9 @@ package cx.ring.loaders;
 import java.util.ArrayList;
 
 import cx.ring.model.CallContact;
+import cx.ring.service.LocalService;
 
+import android.Manifest;
 import android.content.AsyncTaskLoader;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -86,12 +88,14 @@ public class ContactsLoader extends AsyncTaskLoader<ContactsLoader.Result>
     }
 
     @Override
-    public Result loadInBackground() {
-        ContentResolver cr = getContext().getContentResolver();
-
+    public Result loadInBackground()
+    {
         long startTime = System.nanoTime();
         final Result res = new Result();
+        if (!LocalService.checkPermission(getContext(), Manifest.permission.READ_CONTACTS))
+            return res;
 
+        ContentResolver cr = getContext().getContentResolver();
         if (baseUri != null) {
             Cursor result = cr.query(baseUri, CONTACTS_ID_PROJECTION, SELECT, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
             if (result == null)
diff --git a/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java b/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java
index c33bc3651a9182a0acafa704aa9d17b5aef48397..6dd99e219ee3d7e2e0696e356632c2c8ae332e59 100644
--- a/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java
+++ b/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java
@@ -67,11 +67,10 @@ public class HistoryLoader extends AsyncTaskLoader<ArrayList<HistoryEntry>> {
 
         try {
             List<HistoryCall> list = historyManager.getAll();
-            CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance();
             for (HistoryCall call : list) {
                 CallContact contact;
                 if (call.getContactID() == CallContact.DEFAULT_ID) {
-                    contact = CallContact.ContactBuilder.buildUnknownContact(call.getNumber());
+                    contact = CallContact.buildUnknown(call.getNumber());
                 } else {
                     Cursor result = getContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
                             ContactsContract.Contacts._ID + " = ?",
@@ -82,11 +81,10 @@ public class HistoryLoader extends AsyncTaskLoader<ArrayList<HistoryEntry>> {
                     int iPhoto = result.getColumnIndex(ContactsContract.Contacts.PHOTO_ID);
 
                     if (result.moveToFirst()) {
-                        builder.startNewContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
-                        builder.addPhoneNumber(call.getNumber(), 0, null);
-                        contact = builder.build();
+                        contact = new CallContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
+                        contact.addPhoneNumber(call.getNumber(), 0);
                     } else {
-                        contact = CallContact.ContactBuilder.buildUnknownContact(call.getNumber());
+                        contact = CallContact.buildUnknown(call.getNumber());
                     }
                     result.close();
                 }
@@ -130,7 +128,7 @@ public class HistoryLoader extends AsyncTaskLoader<ArrayList<HistoryEntry>> {
                 String contactName = entry.get(ServiceConstants.history.DISPLAY_NAME_KEY);
                 String number_called = entry.get(ServiceConstants.history.PEER_NUMBER_KEY);
                 if (contactName.isEmpty()) {
-                    contact = ContactBuilder.buildUnknownContact(number_called);
+                    contact = ContactBuilder.buildUnknown(number_called);
                 } else {
                     contact = ContactBuilder.getInstance().buildSimpleContact(contactName, number_called);
                 }
diff --git a/ring-android/app/src/main/java/cx/ring/model/CallContact.java b/ring-android/app/src/main/java/cx/ring/model/CallContact.java
index 396cf20fac647b6f46b983f1179faef4948a0871..d1e06a66793dc898187cc0a27cf0b4556b2d9ce2 100644
--- a/ring-android/app/src/main/java/cx/ring/model/CallContact.java
+++ b/ring-android/app/src/main/java/cx/ring/model/CallContact.java
@@ -46,9 +46,15 @@ import android.provider.ContactsContract;
 import android.provider.ContactsContract.Profile;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.support.annotation.NonNull;
+import android.util.Log;
 
-public class CallContact implements Parcelable {
-    public static int DEFAULT_ID = 0;
+import cx.ring.R;
+
+public class CallContact implements Parcelable
+{
+    static final String TAG = CallContact.class.getSimpleName();
+    public static final int DEFAULT_ID = 0;
+    private static final String[] PROFILE_PROJECTION = new String[] { Profile._ID, Profile.LOOKUP_KEY, Profile.DISPLAY_NAME_PRIMARY, Profile.PHOTO_ID };
 
     private long id;
     private String key;
@@ -78,6 +84,41 @@ public class CallContact implements Parcelable {
         isUser = user;
     }
 
+    public static CallContact buildUnknown(String to) {
+        ArrayList<Phone> phones = new ArrayList<>();
+        phones.add(new Phone(to, 0));
+
+        return new CallContact(-1, null, to, 0, phones, "", false);
+    }
+
+    public static CallContact buildUnknown(String to, int type) {
+        ArrayList<Phone> phones = new ArrayList<>();
+        phones.add(new Phone(to, type));
+        return new CallContact(-1, null, to, 0, phones, "", false);
+    }
+
+    public static CallContact buildUserContact(Context c) {
+        CallContact result = null;
+        try {
+            Cursor mProfileCursor = c.getContentResolver().query(Profile.CONTENT_URI, PROFILE_PROJECTION, null, null, null);
+            if (mProfileCursor != null) {
+                if (mProfileCursor.moveToFirst()) {
+                    String key = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.LOOKUP_KEY));
+                    String displayName = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.DISPLAY_NAME_PRIMARY));
+
+                    if (displayName == null || displayName.isEmpty())
+                        displayName = c.getResources().getString(R.string.me);
+                    result = new CallContact(mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile._ID)), key, displayName,
+                            mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile.PHOTO_ID)), new ArrayList<Phone>(), "", true);
+                }
+                mProfileCursor.close();
+            }
+        } catch (Exception e) {
+            Log.w(TAG, e);
+        }
+        return result == null ? new CallContact(-1, null, c.getResources().getString(R.string.me), 0, new ArrayList<Phone>(), "", true) : result;
+    }
+
     public void setContactInfos(String k, String displayName, long photo_id) {
         key = k;
         mDisplayName = displayName;
@@ -188,74 +229,6 @@ public class CallContact implements Parcelable {
         return stared;
     }
 
-    public static class ContactBuilder {
-
-        long contactID;
-        String key;
-        String contactName;
-        long contactPhoto;
-        ArrayList<Phone> phones;
-        String contactMail;
-
-        public ContactBuilder startNewContact(long id, String k, String displayName, long photo_id) {
-            contactID = id;
-            key = k;
-            contactName = displayName;
-            contactPhoto = photo_id;
-            phones = new ArrayList<>();
-            return this;
-        }
-
-        public ContactBuilder addPhoneNumber(String num, int type, String label) {
-            phones.add(new Phone(num, type, label));
-            return this;
-        }
-
-        public ContactBuilder addSipNumber(String num, int type, String label) {
-            phones.add(new Phone(num, type, label, NumberType.SIP));
-            return this;
-        }
-
-        public CallContact build() {
-            return new CallContact(contactID, key, contactName, contactPhoto, phones, contactMail, false);
-        }
-
-        public static ContactBuilder getInstance() {
-            return new ContactBuilder();
-        }
-
-        public static CallContact buildUnknownContact(String to) {
-            ArrayList<Phone> phones = new ArrayList<>();
-            phones.add(new Phone(to, 0));
-
-            return new CallContact(-1, null, to, 0, phones, "", false);
-        }
-        public static CallContact buildUnknownContact(String to, int type) {
-            ArrayList<Phone> phones = new ArrayList<>();
-            phones.add(new Phone(to, type));
-            return new CallContact(-1, null, to, 0, phones, "", false);
-        }
-
-        public static CallContact buildUserContact(ContentResolver c) {
-            String[] mProjection = new String[] { Profile._ID, Profile.LOOKUP_KEY, Profile.DISPLAY_NAME_PRIMARY, Profile.PHOTO_ID };
-            Cursor mProfileCursor = c.query(Profile.CONTENT_URI, mProjection, null, null, null);
-            CallContact result;
-            if (mProfileCursor.getCount() > 0) {
-                mProfileCursor.moveToFirst();
-                String key = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.LOOKUP_KEY));
-                String displayName = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.DISPLAY_NAME_PRIMARY));
-
-                result = new CallContact(mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile._ID)), key, displayName,
-                        mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile.PHOTO_ID)), new ArrayList<Phone>(), "", true);
-            } else {
-                result = new CallContact(-1, null, "Me", 0, new ArrayList<Phone>(), "", true);
-            }
-            mProfileCursor.close();
-            return result;
-        }
-
-    }
-
     @Override
     public int describeContents() {
         return 0;
diff --git a/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java b/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java
index 4da8065b763d56226dbc5fb7c83fab3c54afbaf1..c0b1615d952077c7ccab84e233ab90f444eac274 100644
--- a/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java
+++ b/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java
@@ -131,7 +131,7 @@ public class CallManagerCallBack extends Callback {
             toSend.setClass(mService, CallActivity.class);
             toSend.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
-            CallContact unknown = CallContact.ContactBuilder.buildUnknownContact(from);
+            CallContact unknown = CallContact.buildUnknown(from);
 
             SipCall newCall = new SipCall(callID, accountID, from, SipCall.Direction.INCOMING);
             newCall.setContact(unknown);
diff --git a/ring-android/app/src/main/java/cx/ring/service/LocalService.java b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
index 34e5a91b27870a5e3ac575259ae450fb28efa46c..3da1a133d423c8f8c697062370aa61f21d32ad22 100644
--- a/ring-android/app/src/main/java/cx/ring/service/LocalService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
@@ -86,7 +86,9 @@ public class LocalService extends Service
 
     public static final String AUTHORITY = "cx.ring";
     public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
-    public static final int PERMISSIONS_REQUEST_READ_CONTACTS = 57;
+    public static final int PERMISSIONS_REQUEST = 57;
+
+    public final static String[] REQUIRED_RUNTIME_PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.RECORD_AUDIO};
 
     private ISipService mService = null;
     private final ContactsContentObserver contactContentObserver = new ContactsContentObserver();
@@ -288,8 +290,17 @@ public class LocalService extends Service
         return super.onUnbind(intent);
     }
 
-    public static boolean checkContactPermissions(Context c) {
-        return ContextCompat.checkSelfPermission(c, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
+    public static boolean checkPermission(Context c, String permission) {
+        return ContextCompat.checkSelfPermission(c, permission) == PackageManager.PERMISSION_GRANTED;
+    }
+
+    public static String[] checkRequiredPermissions(Context c) {
+        ArrayList<String> perms = new ArrayList<>();
+        for (String p : REQUIRED_RUNTIME_PERMISSIONS) {
+            if (!checkPermission(c, p))
+                perms.add(p);
+        }
+        return perms.toArray(new String[perms.size()]);
     }
 
     public ISipService getRemoteService() {
@@ -299,6 +310,8 @@ public class LocalService extends Service
     public List<Account> getAccounts() { return accounts; }
     public List<Account> getIP2IPAccount() { return ip2ip_account; }
     public Account getAccount(String account_id) {
+        if (account_id == null || account_id.isEmpty())
+            return null;
         for (Account acc : all_accounts)
             if (acc.getAccountID().equals(account_id))
                 return acc;
@@ -445,97 +458,102 @@ public class LocalService extends Service
 
     private static void lookupDetails(@NonNull ContentResolver res, @NonNull CallContact c) {
         Log.w(TAG, "lookupDetails " + c.getKey());
-
-        Cursor cPhones = res.query(
-                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
-                CONTACTS_PHONES_PROJECTION, ID_SELECTION,
-                new String[]{String.valueOf(c.getId())}, null);
-        if (cPhones != null) {
-            final int iNum =  cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
-            final int iType =  cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
-            final int iLabel =  cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL);
-            while (cPhones.moveToNext()) {
-                c.addNumber(cPhones.getString(iNum), cPhones.getInt(iType), cPhones.getString(iLabel), CallContact.NumberType.TEL);
-                Log.w(TAG,"Phone:"+cPhones.getString(cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
+        try {
+            Cursor cPhones = res.query(
+                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                    CONTACTS_PHONES_PROJECTION, ID_SELECTION,
+                    new String[]{String.valueOf(c.getId())}, null);
+            if (cPhones != null) {
+                final int iNum =  cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
+                final int iType =  cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
+                final int iLabel =  cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL);
+                while (cPhones.moveToNext()) {
+                    c.addNumber(cPhones.getString(iNum), cPhones.getInt(iType), cPhones.getString(iLabel), CallContact.NumberType.TEL);
+                    Log.w(TAG,"Phone:"+cPhones.getString(cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
+                }
+                cPhones.close();
             }
-            cPhones.close();
-        }
-
-        Uri baseUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, c.getId());
-        Uri targetUri = Uri.withAppendedPath(baseUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
-        Cursor cSip = res.query(targetUri,
-                CONTACTS_SIP_PROJECTION,
-                ContactsContract.Data.MIMETYPE + "=?",
-                new String[]{ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null);
-        if (cSip != null) {
-            final int iSip =  cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
-            final int iType =  cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.TYPE);
-            final int iLabel =  cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.LABEL);
-            while (cSip.moveToNext()) {
-                c.addNumber(cSip.getString(iSip), cSip.getInt(iType), cSip.getString(iLabel), CallContact.NumberType.SIP);
-                Log.w(TAG, "SIP phone:" + cSip.getString(iSip));
+
+            Uri baseUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, c.getId());
+            Uri targetUri = Uri.withAppendedPath(baseUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
+            Cursor cSip = res.query(targetUri,
+                    CONTACTS_SIP_PROJECTION,
+                    ContactsContract.Data.MIMETYPE + "=?",
+                    new String[]{ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null);
+            if (cSip != null) {
+                final int iSip =  cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
+                final int iType =  cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.TYPE);
+                final int iLabel =  cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.LABEL);
+                while (cSip.moveToNext()) {
+                    c.addNumber(cSip.getString(iSip), cSip.getInt(iType), cSip.getString(iLabel), CallContact.NumberType.SIP);
+                    Log.w(TAG, "SIP phone:" + cSip.getString(iSip));
+                }
+                cSip.close();
             }
-            cSip.close();
+        } catch(Exception e) {
+            Log.w(TAG, e);
         }
     }
 
     public static CallContact findByKey(@NonNull ContentResolver res, String key) {
         Log.e(TAG, "findByKey " + key);
-
-        final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance();
-        Cursor result = res.query(Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, key), CONTACT_PROJECTION,
-                null, null, null);
-
         CallContact contact = null;
-        if (result != null && result.moveToFirst()) {
-            int iID = result.getColumnIndex(ContactsContract.Data._ID);
-            int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
-            int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
-            int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID);
-            int iStared = result.getColumnIndex(ContactsContract.Data.STARRED);
-            long cid = result.getLong(iID);
-
-            Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey));
-
-            builder.startNewContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
+        try {
+            Cursor result = res.query(Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, key), CONTACT_PROJECTION,
+                    null, null, null);
+            if (result == null)
+                return null;
+            if (result.moveToFirst()) {
+                int iID = result.getColumnIndex(ContactsContract.Data._ID);
+                int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
+                int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
+                int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID);
+                int iStared = result.getColumnIndex(ContactsContract.Data.STARRED);
+                long cid = result.getLong(iID);
+
+                Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey));
+
+                contact = new CallContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
+                if (result.getInt(iStared) != 0)
+                    contact.setStared();
+                lookupDetails(res, contact);
+            }
             result.close();
-
-            contact = builder.build();
-            if (result.getInt(iStared) != 0)
-                contact.setStared();
-            lookupDetails(res, contact);
+        } catch(Exception e) {
+            Log.w(TAG, e);
         }
         return contact;
     }
 
      public static CallContact findById(@NonNull ContentResolver res, long id) {
          Log.e(TAG, "findById " + id);
-
-         final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance();
-         Cursor result = res.query(ContactsContract.Contacts.CONTENT_URI, CONTACT_PROJECTION,
-                 ContactsContract.Contacts._ID + " = ?",
-                 new String[]{String.valueOf(id)}, null);
-         if (result == null)
-             return null;
-
          CallContact contact = null;
-         if (result.moveToFirst()) {
-             int iID = result.getColumnIndex(ContactsContract.Data._ID);
-             int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
-             int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
-             int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID);
-             int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED);
-             long cid = result.getLong(iID);
-
-             Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey));
-
-             builder.startNewContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
-             contact = builder.build();
-             if (result.getInt(iStared) != 0)
-                 contact.setStared();
-             lookupDetails(res, contact);
+         try {
+             Cursor result = res.query(ContactsContract.Contacts.CONTENT_URI, CONTACT_PROJECTION,
+                     ContactsContract.Contacts._ID + " = ?",
+                     new String[]{String.valueOf(id)}, null);
+             if (result == null)
+                 return null;
+
+             if (result.moveToFirst()) {
+                 int iID = result.getColumnIndex(ContactsContract.Data._ID);
+                 int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
+                 int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
+                 int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID);
+                 int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED);
+                 long cid = result.getLong(iID);
+
+                 Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey));
+
+                 contact = new CallContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
+                 if (result.getInt(iStared) != 0)
+                     contact.setStared();
+                 lookupDetails(res, contact);
+             }
+             result.close();
+         } catch(Exception e) {
+             Log.w(TAG, e);
          }
-         result.close();
          return contact;
     }
 
@@ -553,42 +571,39 @@ public class LocalService extends Service
 
     @NonNull
     public static CallContact findContactBySipNumber(@NonNull ContentResolver res, String number) {
-        final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance();
-        Cursor result = res.query(ContactsContract.Data.CONTENT_URI,
-                DATA_PROJECTION,
-                ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
-                new String[]{number, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null);
-        if (result == null)  {
-            Log.w(TAG, "findContactBySipNumber " + number + " can't find contact.");
-            return CallContact.ContactBuilder.buildUnknownContact(number);
-        }
-        int icID = result.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
-        int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
-        int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
-        int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID);
-        int iPhotoThumb = result.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI);
-        int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED);
-
         ArrayList<CallContact> contacts = new ArrayList<>(1);
-        while (result.moveToNext()) {
-            long cid = result.getLong(icID);
-            builder.startNewContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
-            CallContact contact = builder.build();
-            if (result.getInt(iStared) != 0)
-                contact.setStared();
-            lookupDetails(res, contact);
-            contacts.add(contact);
-        }
-        result.close();
-
-        //lookupDetails(res, contact);
-        /*if (contact == null) {
-            Log.w(TAG, "Can't find contact with number " + number);
-            contact = CallContact.ContactBuilder.buildUnknownContact(number);
-        }*/
+        try {
+            Cursor result = res.query(ContactsContract.Data.CONTENT_URI,
+                    DATA_PROJECTION,
+                    ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
+                    new String[]{number, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null);
+            if (result == null)  {
+                Log.w(TAG, "findContactBySipNumber " + number + " can't find contact.");
+                return CallContact.buildUnknown(number);
+            }
+            int icID = result.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
+            int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
+            int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
+            int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID);
+            int iPhotoThumb = result.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI);
+            int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED);
+
+            while (result.moveToNext()) {
+                long cid = result.getLong(icID);
+                CallContact contact = new CallContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
+                if (result.getInt(iStared) != 0)
+                    contact.setStared();
+                lookupDetails(res, contact);
+                contacts.add(contact);
+            }
+            result.close();
+            //lookupDetails(res, contact);
+        } catch(Exception e) {
+            Log.w(TAG, e);
+        }
         if (contacts.isEmpty()) {
             Log.w(TAG, "findContactBySipNumber " + number + " can't find contact.");
-            return CallContact.ContactBuilder.buildUnknownContact(number);
+            return CallContact.buildUnknown(number);
         }
         return contacts.get(0);
     }
@@ -596,34 +611,32 @@ public class LocalService extends Service
     @NonNull
     public static CallContact findContactByNumber(@NonNull ContentResolver res, String number) {
         //Log.w(TAG, "findContactByNumber " + number);
-
-        final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance();
-        Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
-        Cursor result = res.query(uri, PHONELOOKUP_PROJECTION, null, null, null);
-        if (result == null)  {
-            Log.w(TAG, "findContactByNumber " + number + " can't find contact.");
-            return findContactBySipNumber(res, number);
-        }
-        if (!result.moveToFirst())  {
+        CallContact c = null;
+        try {
+            Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
+            Cursor result = res.query(uri, PHONELOOKUP_PROJECTION, null, null, null);
+            if (result == null)  {
+                Log.w(TAG, "findContactByNumber " + number + " can't find contact.");
+                return findContactBySipNumber(res, number);
+            }
+            if (result.moveToFirst())  {
+                int iID = result.getColumnIndex(ContactsContract.Contacts._ID);
+                int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
+                int iName = result.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
+                int iPhoto = result.getColumnIndex(ContactsContract.Contacts.PHOTO_ID);
+                c = new CallContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
+                lookupDetails(res, c);
+                Log.w(TAG, "findContactByNumber " + number + " found " + c.getDisplayName());
+            }
             result.close();
+        } catch(Exception e) {
+            Log.w(TAG, e);
+        }
+        if (c == null) {
             Log.w(TAG, "findContactByNumber " + number + " can't find contact.");
-            return findContactBySipNumber(res, number);
-        }
-        int iID = result.getColumnIndex(ContactsContract.Contacts._ID);
-        int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
-        int iName = result.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
-        int iPhoto = result.getColumnIndex(ContactsContract.Contacts.PHOTO_ID);
-        builder.startNewContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto));
-        result.close();
-        CallContact contact = builder.build();
-        lookupDetails(res, contact);
-        /*if (contact == null) {
-            Log.w(TAG, "Can't find contact with number " + number);
-            contact = CallContact.ContactBuilder.buildUnknownContact(number);
-        }*/
-        Log.w(TAG, "findContactByNumber " + number + " found " + contact.getDisplayName());
-
-        return contact;
+            c = findContactBySipNumber(res, number);
+        }
+        return c;
     }
 
     private class ConversationLoader extends AsyncTask<Void, Void, Map<String, Conversation>> {