diff --git a/ring-android/app/src/main/java/cx/ring/client/CallActivity.java b/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
index c481bca870427e4f1bd697ffa9852e2ca48213a4..9375f6c26bde5d423b757cbb637992b2c845654a 100644
--- a/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/CallActivity.java
@@ -38,6 +38,7 @@ import android.util.Log;
 import cx.ring.R;
 import cx.ring.fragments.CallFragment;
 import cx.ring.model.Conversation;
+import cx.ring.model.SipUri;
 import cx.ring.model.TextMessage;
 import cx.ring.model.account.Account;
 import cx.ring.model.CallContact;
@@ -153,6 +154,10 @@ public class CallActivity extends Activity implements LocalService.Callbacks, Ca
 
                 if(!checkExternalCall()) {
                     mDisplayedConference = getIntent().getParcelableExtra("conference");
+                    if (!mDisplayedConference.hasMultipleParticipants()) {
+                        Conversation conv = service.startConversation(mDisplayedConference.getParticipants().get(0).getContact());
+                        mDisplayedConference.getParticipants().get(0).setContact(conv.getContact());
+                    }
                 }
                 Log.i(TAG, "CallActivity onCreate in:" + mDisplayedConference.isIncoming() + " out:" + mDisplayedConference.isOnGoing() + " contact" + mDisplayedConference.getParticipants().get(0).getContact().getDisplayName());
                 init = true;
@@ -185,7 +190,8 @@ public class CallActivity extends Activity implements LocalService.Callbacks, Ca
         if (u != null) {
             String number = u.getSchemeSpecificPart();
             Log.w(TAG, "number " + number);
-            number = CallContact.canonicalNumber(number);
+            SipUri uri = new SipUri(number);
+            number = uri.getRawUriString();
             Log.w(TAG, "canonicalNumber " + number);
             CallContact c = service.findContactByNumber(number);
             Conversation conv = service.getByContact(c);
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 023bcbb65b545eba333419b150cd41a904db32e1..23fcf437f647b85491248d58c01342f51048eeff 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
@@ -63,7 +63,7 @@ public class ConversationActivity extends Activity {
     private ServiceConnection mConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName className, IBinder binder) {
-            service = ((LocalService.LocalBinder)binder).getService();
+            service = ((LocalService.LocalBinder) binder).getService();
             IntentFilter intentFilter = new IntentFilter();
             intentFilter.addAction(LocalService.ACTION_CONF_UPDATE);
             registerReceiver(receiver, intentFilter);
@@ -127,7 +127,9 @@ public class ConversationActivity extends Activity {
         public void onReceive(Context context, Intent intent) {
             Log.w(TAG, "onReceive " + intent.getAction() + " " + intent.getDataString());
             //conversation = service.getConversation(conversation.getId());
-            conversation = service.getByContact(conversation.getContact());
+            Conversation newc = service.getByContact(conversation.getContact());
+            if (newc != null)
+                conversation = newc;
             adapter.updateDataset(conversation.getHistory());
             scrolltoBottom();
             Conference conf = conversation.getCurrentCall();
@@ -231,16 +233,16 @@ public class ConversationActivity extends Activity {
 
                 boolean sep = false;
                 boolean sep_same = false;
-                if (position > 0 && texts.get(position-1).text != null) {
-                    TextMessage msg = texts.get(position-1).text;
+                if (position > 0 && texts.get(position - 1).text != null) {
+                    TextMessage msg = texts.get(position - 1).text;
                     if (msg.isIncoming() && txt.text.isIncoming() && msg.getNumber().equals(txt.text.getNumber()))
                         sep_same = true;
                 }
-                if (position > 0 && texts.get(position-1).text != null && position < texts.size()-1) {
-                    TextMessage msg = texts.get(position+1).text;
+                if (position > 0 && texts.get(position - 1).text != null && position < texts.size() - 1) {
+                    TextMessage msg = texts.get(position + 1).text;
                     if (msg != null) {
                         long diff = msg.getTimestamp() - txt.text.getTimestamp();
-                        if (diff > 30*1000)
+                        if (diff > 30 * 1000)
                             sep = true;
                     } else {
                         sep = true;
@@ -345,7 +347,7 @@ public class ConversationActivity extends Activity {
             if (number == null || number.isEmpty())
                 number = conversation.contact.getPhones().get(0).getNumber();
             try {
-                service.getRemoteService().sendAccountTextMessage(account, number, txt);
+                service.getRemoteService().sendAccountTextMessage(account, CallContact.canonicalNumber(number), txt);
             } catch (RemoteException e) {
                 e.printStackTrace();
             }
@@ -359,7 +361,7 @@ public class ConversationActivity extends Activity {
     }
 
     private void onAudioCall() {
-        Conference conf = conversation.getCurrentCall();
+        Conference conf = conversation == null ? null : conversation.getCurrentCall();
         if (conf != null) {
             startActivity(new Intent(ConversationActivity.this.getApplicationContext(), CallActivity.class).putExtra("conference", conversation.getCurrentCall()));
             return;
@@ -370,7 +372,7 @@ public class ConversationActivity extends Activity {
             return;
         }
 
-        Account usedAccount = service.getAccounts().get(0);
+        Account usedAccount = null;
         CallContact contact = null;
         if (conversation != null) {
             String last_used = conversation.getLastAccountUsed();
@@ -387,33 +389,30 @@ public class ConversationActivity extends Activity {
                 }
             }
             contact = conversation.getContact();
-        }   
+        }
 
         String number = preferredNumber;
-        if (number == null)
-            number = conversation.getLastNumberUsed(usedAccount.getAccountID());
-        if (number == null && contact != null)
-            number = contact.getPhones().get(0).getNumber();
-
-        //conversation.getHistory().getAccountID()
-        //if (usedAccount.isRegistered() || usedAccount.isIP2IP()) {
-         /*   Bundle args = new Bundle();
-            args.putParcelable(SipCall.ACCOUNT, usedAccount);
-            args.putInt(SipCall.STATE, SipCall.State.NONE);
-            args.putInt(SipCall.TYPE, SipCall.Direction.OUTGOING);
-            args.putParcelable(SipCall.CONTACT, contact);*/
+        if (usedAccount != null) {
+            if (number == null)
+                number = conversation.getLastNumberUsed(usedAccount.getAccountID());
+            if (number == null && contact != null)
+                number = contact.getPhones().get(0).getNumber();
+        } else {
+            if (number == null && contact != null)
+                number = contact.getPhones().get(0).getNumber();
+            usedAccount = service.guessAccount(contact, number);
+        }
+        number = CallContact.canonicalNumber(number);
+
         SipCall call = new SipCall(null, usedAccount.getAccountID(), number, SipCall.Direction.OUTGOING);
         call.setContact(contact);
 
-            try {
-                launchCallActivity(call);
-            } catch (Exception e) {
-                e.printStackTrace();
-                Log.e(TAG, e.toString());
-            }
-        /*} else {
-            createNotRegisteredDialog().show();
-        }*/
+        try {
+            launchCallActivity(call);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Log.e(TAG, e.toString());
+        }
 
     }
 }
diff --git a/ring-android/app/src/main/java/cx/ring/history/HistoryEntry.java b/ring-android/app/src/main/java/cx/ring/history/HistoryEntry.java
index bf7c89f26ab6cad5f22904d75034343ea7617684..97f946149881bb6317e2713926c2dc475e344c0a 100644
--- a/ring-android/app/src/main/java/cx/ring/history/HistoryEntry.java
+++ b/ring-android/app/src/main/java/cx/ring/history/HistoryEntry.java
@@ -176,12 +176,28 @@ public class HistoryEntry implements Parcelable {
                 return c;
         return null;
     }
+    public HistoryCall getLastIncomingCall() {
+        for (HistoryCall c : calls.descendingMap().values())
+            if (c.isIncoming())
+                return c;
+        return null;
+    }
+    public TextMessage getLastIncomingText() {
+        for (TextMessage c : text_messages.descendingMap().values())
+            if (c.isIncoming())
+                return c;
+        return null;
+    }
 
     public String getLastNumberUsed() {
         HistoryCall call = getLastOutgoingCall();
         TextMessage text = getLastOutgoingText();
-        if (call == null && text == null)
-            return null;
+        if (call == null && text == null) {
+            call = getLastIncomingCall();
+            text = getLastIncomingText();
+            if (call == null && text == null)
+                return null;
+        }
         if (call == null)
             return text.getNumber();
         if (text == null)
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 e11861c073d1924cf4756aa2ece06f3c4221e13c..90edf823e42f01201865d1da46c4c39984c09dff 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
@@ -32,7 +32,6 @@ package cx.ring.model;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -44,25 +43,28 @@ import android.os.Parcelable;
 import android.provider.ContactsContract.Profile;
 import android.support.annotation.NonNull;
 
-import cx.ring.client.ConversationActivity;
-import cx.ring.service.LocalService;
-
 public class CallContact implements Parcelable {
-    static public final Pattern ANGLE_BRACKETS_PATTERN = Pattern.compile("(?:[^<>]+<)?([^<>]+)>?\\s*");
-    public static final Pattern RING_ID_PATTERN = Pattern.compile("^\\s*(?:ring(?:[\\s\\:]+))?(\\p{XDigit}{40})(?:@ring\\.dht)?\\s*$", Pattern.CASE_INSENSITIVE);
-
     public static int DEFAULT_ID = 0;
 
     private long id;
     private String key;
     private String mDisplayName;
     private long photo_id;
-    private ArrayList<Phone> phones/*, sip_phones*/;
+    private final ArrayList<Phone> phones;
     private String mEmail;
     private boolean isUser;
     private WeakReference<Bitmap> contact_photo = new WeakReference<>(null);
+    private boolean stared = false;
+
+    public CallContact(long cID) {
+        this(cID, null, null, -1);
+    }
+
+    public CallContact(long cID, String k, String displayName, long photoID) {
+        this(cID, k, displayName, photoID, new ArrayList<Phone>(), null, false);
+    }
 
-    private CallContact(long cID, String k, String displayName, long photoID, ArrayList<Phone> p, String mail, boolean user) {
+    public CallContact(long cID, String k, String displayName, long photoID, ArrayList<Phone> p, String mail, boolean user) {
         id = cID;
         key = k;
         mDisplayName = displayName;
@@ -72,19 +74,14 @@ public class CallContact implements Parcelable {
         isUser = user;
     }
 
-    private static String nobracketsNumber(@NonNull String number) {
-        Matcher m = ANGLE_BRACKETS_PATTERN.matcher(number);
-        if (m.find())
-            return m.group(1);
-        return number;
+    public void setContactInfos(String k, String displayName, long photo_id) {
+        key = k;
+        mDisplayName = displayName;
+        this.photo_id = photo_id;
     }
 
     public static String canonicalNumber(@NonNull String number) {
-        number = nobracketsNumber(number);
-        Matcher m = RING_ID_PATTERN.matcher(number);
-        if (m.find())
-            return "ring:"+m.group(1);
-        return number;
+        return new SipUri(number).getRawUriString();
     }
 
     public ArrayList<String> getIds() {
@@ -107,6 +104,7 @@ public class CallContact implements Parcelable {
     }
 
     public CallContact(Parcel in) {
+        phones = new ArrayList<>();
         readFromParcel(in);
     }
 
@@ -119,8 +117,6 @@ public class CallContact implements Parcelable {
             return mDisplayName;
         if (!phones.isEmpty())
             return phones.get(0).getNumber();
-        /*if (!sip_phones.isEmpty())
-            return sip_phones.get(0).getNumber();*/
         return "";
     }
 
@@ -136,9 +132,9 @@ public class CallContact implements Parcelable {
         return phones;
     }
 
-    public void setPhones(ArrayList<Phone> phones) {
+    /*public void setPhones(ArrayList<Phone> phones) {
         this.phones = phones;
-    }
+    }*/
 
     public String getEmail() {
         return mEmail;
@@ -175,6 +171,17 @@ public class CallContact implements Parcelable {
         return key;
     }
 
+    public void setStared(boolean stared) {
+        this.stared = stared;
+    }
+    public void setStared() {
+        this.stared = true;
+    }
+
+    public boolean isStared() {
+        return stared;
+    }
+
     public static class ContactBuilder {
 
         long contactID;
@@ -223,9 +230,9 @@ public class CallContact implements Parcelable {
             return new CallContact(-1, null, to, 0, phones, "", false);
         }
 
-        public static CallContact buildUserContact(ContentResolver cr) {
+        public static CallContact buildUserContact(ContentResolver c) {
             String[] mProjection = new String[] { Profile._ID, Profile.LOOKUP_KEY, Profile.DISPLAY_NAME_PRIMARY, Profile.PHOTO_ID };
-            Cursor mProfileCursor = cr.query(Profile.CONTENT_URI, mProjection, null, null, null);
+            Cursor mProfileCursor = c.query(Profile.CONTENT_URI, mProjection, null, null, null);
             CallContact result;
             if (mProfileCursor.getCount() > 0) {
                 mProfileCursor.moveToFirst();
@@ -257,7 +264,7 @@ public class CallContact implements Parcelable {
         dest.writeTypedList(phones);
         dest.writeString(mEmail);
         dest.writeByte((byte) (isUser ? 1 : 0));
-
+        dest.writeByte(stared ? (byte)1 : (byte)0);
     }
 
     private void readFromParcel(Parcel in) {
@@ -265,10 +272,11 @@ public class CallContact implements Parcelable {
         key = in.readString();
         mDisplayName = in.readString();
         photo_id = in.readLong();
-        phones = new ArrayList<>();
+        phones.clear();
         in.readTypedList(phones, Phone.CREATOR);
         mEmail = in.readString();
-        isUser = in.readByte() == 1;
+        isUser = in.readByte() != 0;
+        stared = in.readByte() != 0;
     }
 
     public static final Parcelable.Creator<CallContact> CREATOR = new Parcelable.Creator<CallContact>() {
@@ -302,12 +310,6 @@ public class CallContact implements Parcelable {
                     return v;
             return UNKNOWN;
         }
-        /*public static NumberType guess(String num) {
-            String canon = canonicalNumber(num);
-            Matcher m = URI_NUMBER_REGEX.matcher(canon);
-
-            return UNKNOWN;
-        }*/
     }
 
     public static class Phone implements Parcelable {
@@ -392,9 +394,7 @@ public class CallContact implements Parcelable {
     }
 
     public boolean hasPhoto() {
-        if (contact_photo.get() != null)
-            return true;
-        return false;
+        return contact_photo.get() != null;
     }
 
     public Bitmap getPhoto() {
diff --git a/ring-android/app/src/main/java/cx/ring/model/SipUri.java b/ring-android/app/src/main/java/cx/ring/model/SipUri.java
new file mode 100644
index 0000000000000000000000000000000000000000..12a0746c781f21697fa9303023dba929790d1600
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/model/SipUri.java
@@ -0,0 +1,87 @@
+package cx.ring.model;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import cx.ring.utils.Utilities;
+
+public class SipUri {
+    public String display_name = null;
+    public String sheme = null;
+    public String username = null;
+    public String host = null;
+    public String port = null;
+
+    public static final Pattern ANGLE_BRACKETS_PATTERN = Pattern.compile("^(?:([^<>]+)\\s*<)?([^<>]+)>?\\s*$");
+    public static final Pattern RING_ID_PATTERN = Pattern.compile("^\\p{XDigit}{40}$", Pattern.CASE_INSENSITIVE);
+    public static final Pattern RING_URI_PATTERN = Pattern.compile("^\\s*(?:ring(?:[\\s\\:]+))?(\\p{XDigit}{40})(?:@ring\\.dht)?\\s*$", Pattern.CASE_INSENSITIVE);
+    public static final Pattern URI_PATTERN = Pattern.compile("^\\s*(\\w+:)?(?:([\\w.]+)@)?(?:([\\d\\w\\.]+)(?::(\\d+))?)\\s*$", Pattern.CASE_INSENSITIVE);
+
+    public SipUri() {}
+
+    public SipUri(String uri) {
+        parseUri(uri);
+    }
+
+    public String getRawUriString() {
+        if (host != null && RING_ID_PATTERN.matcher(host).find())
+            return "ring:" + host;
+        else if (username != null &&  RING_ID_PATTERN.matcher(username).find())
+            return "ring:" + username;
+
+        StringBuilder builder = new StringBuilder(64);
+        if (sheme != null)
+            builder.append(sheme);
+        if (username != null && !username.isEmpty())
+            builder.append(username).append("@");
+        if (host != null)
+            builder.append(host);
+        if (port != null && !port.isEmpty())
+            builder.append(":").append(port);
+        return builder.toString();
+    }
+
+    public String getUriString() {
+        if (display_name == null || display_name.isEmpty())
+            return getRawUriString();
+        return display_name+" <"+getRawUriString()+">";
+    }
+
+    public String toString() {
+        return getUriString();
+    }
+
+    public boolean isSingleIp() {
+        return (username == null || username.isEmpty()) && Utilities.isIpAddress(host);
+    }
+
+    public boolean isRingId() {
+        if (host != null && RING_ID_PATTERN.matcher(host).find())
+            return true;
+        else if (username != null && RING_ID_PATTERN.matcher(username).find())
+            return true;
+        return false;
+    }
+
+    private void parseUri(String uri) {
+        Matcher m = ANGLE_BRACKETS_PATTERN.matcher(uri);
+        if (m.find()) {
+            display_name = m.group(1);
+            parseUriRaw(m.group(2));
+        } else {
+            parseUriRaw(uri);
+        }
+    }
+
+    private void parseUriRaw(String uri) {
+        Matcher m = URI_PATTERN.matcher(uri);
+        if (m.find()) {
+            sheme = m.group(1);
+            username = m.group(2);
+            host = m.group(3);
+            port = m.group(4);
+        } else {
+            host = uri;
+        }
+    }
+}
diff --git a/ring-android/app/src/main/res/layout/frag_call_list.xml b/ring-android/app/src/main/res/layout/frag_call_list.xml
index 91d86862901af4f4b8873d363b193b8c86ff618b..75c02d9edbf5662f9c14c6096b69d16b6eae81b1 100644
--- a/ring-android/app/src/main/res/layout/frag_call_list.xml
+++ b/ring-android/app/src/main/res/layout/frag_call_list.xml
@@ -38,13 +38,29 @@ as that of the covered work.
     android:paddingTop="@dimen/padding_small"
     android:background="@android:color/white">
 
-    <ListView
-        android:id="@+id/confs_list"
-        android:layout_width="match_parent"
+    <ViewSwitcher
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:divider="@null"
-        tools:listitem="@layout/item_calllist">
-    </ListView>
+        android:id="@+id/list_switcher" >
+
+        <ListView
+            android:id="@+id/confs_list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:divider="@null"
+            tools:listitem="@layout/item_calllist">
+        </ListView>
+
+        <se.emilsjolander.stickylistheaders.StickyListHeadersListView
+            android:id="@+id/contacts_stickylv"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:drawSelectorOnTop="true"
+            android:fastScrollEnabled="true"
+            android:scrollbarStyle="outsideOverlay"
+            android:divider="@null" />
+
+    </ViewSwitcher>
 
     <android.support.design.widget.FloatingActionButton
         android:id="@+id/newconv_fab"