* #25268 Faster contact list loading
* #26286 conference creation/suppression working
diff --git a/src/com/savoirfairelinux/sflphone/client/CallActivity.java b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
index bdfd992..48c9943 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
@@ -33,6 +33,7 @@
 
 package com.savoirfairelinux.sflphone.client;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
 import android.app.Activity;
@@ -243,7 +244,7 @@
             map = (HashMap<String, SipCall>) service.getCallList();
             if (map.size() == 0) {
                 
-                finish();
+//                finish();
             }
         } catch (RemoteException e) {
             Log.e(TAG, e.toString());
@@ -267,16 +268,17 @@
     }
 
     @Override
-    public void onCallSelected(SipCall call) {
+    public void onCallSelected(ArrayList<SipCall> calls) {
 
         mCurrentCallFragment.getBubbleView().restartDrawing();
         mCurrentCallFragment = new CallFragment();
         Bundle b = new Bundle();
-        b.putParcelable("CallInfo", call);
+        
+        b.putParcelableArrayList("CallsInfo", calls);
         mCurrentCallFragment.setArguments(b);
         getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment).commit();
 
-        onCallResumed(call);
+//        onCallResumed(calls);
         slidingPaneLayout.setCurFragment(mCurrentCallFragment);
         slidingPaneLayout.closePane();
 
@@ -412,4 +414,26 @@
 
     }
 
+    @Override
+    public void confCreated(Intent intent) {
+        mCallsFragment.update();
+        
+    }
+
+    @Override
+    public void confRemoved(Intent intent) {
+        mCallsFragment.update();
+    }
+
+    @Override
+    public void confChanged(Intent intent) {
+        mCallsFragment.update();
+    }
+
+    @Override
+    public void onCallsTerminated() {
+        Toast.makeText(this, "No Calls ", Toast.LENGTH_SHORT).show();
+        
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index cc1300a..64abea2 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -31,6 +31,7 @@
  */
 package com.savoirfairelinux.sflphone.client;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -344,7 +345,9 @@
     public void launchCallActivity(SipCall infos) {
         Log.i(TAG, "Launch Call Activity");
         Bundle bundle = new Bundle();
-        bundle.putParcelable("CallInfo", infos);
+        ArrayList<SipCall> tmp = new ArrayList<SipCall>();
+        tmp.add(infos);
+        bundle.putParcelableArrayList("CallsInfo", tmp);
         Intent intent = new Intent().setClass(this, CallActivity.class);
 
         intent.putExtras(bundle);
@@ -580,4 +583,22 @@
         mDrawer.animateOpen();
     }
 
+    @Override
+    public void confCreated(Intent intent) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void confRemoved(Intent intent) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void confChanged(Intent intent) {
+        // TODO Auto-generated method stub
+        
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
index f454d99..a502bab 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
@@ -31,6 +31,7 @@
 
 package com.savoirfairelinux.sflphone.fragments;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
 import android.app.Activity;
@@ -65,7 +66,7 @@
     static final float BUBBLE_SIZE = 75;
     static final float ATTRACTOR_SIZE = 40;
 
-    private SipCall mCall;
+    private ArrayList<SipCall> mCalls;
 
     private TextView callStatusTxt;
     private BubblesView view;
@@ -75,7 +76,7 @@
 
     private HashMap<CallContact, Bubble> contacts = new HashMap<CallContact, Bubble>();
 
-    private CallContact myself;
+    private SipCall myself;
 
     private Bitmap hangup_icon;
     private Bitmap call_icon;
@@ -86,7 +87,7 @@
         model = new BubbleModel(getResources().getDisplayMetrics().density);
         Bundle b = getArguments();
 
-        mCall = b.getParcelable("CallInfo");
+        mCalls = b.getParcelableArrayList("CallsInfo");
 
     }
 
@@ -174,7 +175,7 @@
         // rootView.requestDisallowInterceptTouchEvent(true);
 
         mCallbacks = (Callbacks) activity;
-        myself = CallContact.ContactBuilder.buildUserContact(activity.getContentResolver(), "");
+        myself = SipCall.SipCallBuilder.buildMyselfCall(activity.getContentResolver(), "");
 
     }
 
@@ -212,19 +213,33 @@
 
         callStatusTxt.setText("0 min");
 
-
-
         getBubbleFor(myself, model.width / 2, model.height / 2);
 
-            getBubbleFor(mCall.getContact(), (int) (model.width / 2), (int) (model.height / 3));
-        
+        int angle_part = 360 / mCalls.size();
+        double dX = 0;
+        double dY = 0;
+        int radiusCalls = model.width / 2 - 150;
+        for (int i = 0; i < mCalls.size(); ++i) {
+            dX = Math.cos(Math.toRadians(angle_part * i) - 90) * radiusCalls;
+            dY = Math.sin(Math.toRadians(angle_part * i) - 90) * radiusCalls;
+            getBubbleFor(mCalls.get(i), (int) (model.width / 2 + dX), (int) (model.height / 2 + dY));
+        }
 
         model.clearAttractors();
-        model.addAttractor(new Attractor(new PointF(model.width / 2, model.height * .8f), ATTRACTOR_SIZE, new Attractor.Callback() {
+        model.addAttractor(new Attractor(new PointF(model.width / 1.1f, model.height * .1f), ATTRACTOR_SIZE, new Attractor.Callback() {
             @Override
             public boolean onBubbleSucked(Bubble b) {
                 Log.w(TAG, "Bubble sucked ! ");
-                mCallbacks.onCallEnded(mCall);
+                if(mCalls.size() == 1){
+                    mCallbacks.onCallEnded(b.associated_call);
+                } else {
+                    try {
+                        mCallbacks.getService().detachParticipant(b.associated_call.getCallId());
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
+                    }
+                }
+                
                 bubbleRemoved(b);
                 return true;
             }
@@ -237,21 +252,21 @@
 
         callStatusTxt.setText("Incomming call");
 
-        Bubble contact_bubble = getBubbleFor(mCall.getContact(), model.width / 2, model.height / 2);
-        contacts.put(mCall.getContact(), contact_bubble);
+        Bubble contact_bubble = getBubbleFor(mCalls.get(0), model.width / 2, model.height / 2);
+        contacts.put(mCalls.get(0).getContact(), contact_bubble);
 
         model.clearAttractors();
         model.addAttractor(new Attractor(new PointF(4 * model.width / 5, model.height / 2), ATTRACTOR_SIZE, new Attractor.Callback() {
             @Override
             public boolean onBubbleSucked(Bubble b) {
-                mCallbacks.onCallAccepted(mCall);
+                mCallbacks.onCallAccepted(mCalls.get(0));
                 return false;
             }
         }, call_icon));
         model.addAttractor(new Attractor(new PointF(model.width / 5, model.height / 2), ATTRACTOR_SIZE, new Attractor.Callback() {
             @Override
             public boolean onBubbleSucked(Bubble b) {
-                mCallbacks.onCallRejected(mCall);
+                mCallbacks.onCallRejected(mCalls.get(0));
                 bubbleRemoved(b);
                 return true;
             }
@@ -266,14 +281,14 @@
         // TODO off-thread image loading
         getBubbleFor(myself, model.width / 2, model.height / 2);
 
-        getBubbleFor(mCall.getContact(), (int) (model.width / 2), (int) (model.height / 3 ));
+        getBubbleFor(mCalls.get(0), (int) (model.width / 2), (int) (model.height / 3));
 
         model.clearAttractors();
-        model.addAttractor(new Attractor(new PointF(model.width / 2, model.height * .8f), 40, new Attractor.Callback() {
+        model.addAttractor(new Attractor(new PointF(model.width / 1.1f, model.height * .1f), 40, new Attractor.Callback() {
             @Override
             public boolean onBubbleSucked(Bubble b) {
                 Log.w(TAG, "Bubble sucked ! ");
-                mCallbacks.onCallEnded(mCall);
+                mCallbacks.onCallEnded(mCalls.get(0));
                 bubbleRemoved(b);
                 return true;
             }
@@ -283,32 +298,31 @@
     /**
      * Retrieves or create a bubble for a given contact. If the bubble exists, it is moved to the new location.
      * 
-     * @param contact
-     *            The contact
+     * @param call
+     *            The call associated to a contact
      * @param x
      *            Initial or new x position.
      * @param y
      *            Initial or new y position.
      * @return Bubble corresponding to the contact.
      */
-    private Bubble getBubbleFor(CallContact contact, float x, float y) {
-        Bubble contact_bubble = contacts.get(contact);
+    private Bubble getBubbleFor(SipCall call, float x, float y) {
+        Bubble contact_bubble = contacts.get(call.getContact());
         if (contact_bubble != null) {
             contact_bubble.attractor.set(x, y);
             return contact_bubble;
         }
 
         // TODO off-thread image loading
-        if (contact.getPhoto_id() > 0) {
-            Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), contact.getId());
-            contact_bubble = new Bubble(x, y, BUBBLE_SIZE, photo);
+        if (call.getContact().getPhoto_id() > 0) {
+            Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), call.getContact().getId());
+            contact_bubble = new Bubble(call, x, y, BUBBLE_SIZE, photo);
         } else {
-            contact_bubble = new Bubble(x, y, BUBBLE_SIZE, getActivity(), R.drawable.ic_contact_picture);
+            contact_bubble = new Bubble(call, x, y, BUBBLE_SIZE, getActivity(), R.drawable.ic_contact_picture);
         }
-        contact_bubble.contact = contact;
 
         model.addBubble(contact_bubble);
-        contacts.put(contact, contact_bubble);
+        contacts.put(call.getContact(), contact_bubble);
 
         return contact_bubble;
     }
@@ -317,23 +331,30 @@
      * Should be called when a bubble is removed from the model
      */
     void bubbleRemoved(Bubble b) {
-        if (b.contact == null) {
+        if (b.associated_call == null) {
             return;
         }
-
-        contacts.remove(b.contact);
+        contacts.remove(b.associated_call.getContact());
     }
 
     public void changeCallState(String callID, String newState) {
 
         Log.w(TAG, "Changing call state of " + callID);
-        mCall.printCallInfo();
-        if (!callID.equals(mCall.getCallId()))
-            return;
+        if (mCalls.size() == 1) {
+            if (callID.equals(mCalls.get(0).getCallId()))
+                mCalls.get(0).setCallState(newState);
 
-        mCall.setCallState(newState);
-        if (mCall.isOngoing()) {
-            initNormalStateDisplay();
+            if (mCalls.get(0).isOngoing()) {
+                initNormalStateDisplay();
+            }
+        } else {
+            for (int i = 0; i < mCalls.size(); ++i) {
+                mCalls.get(i).printCallInfo();
+
+                if (callID.equals(mCalls.get(i).getCallId()))
+                    mCalls.get(i).setCallState(newState);
+
+            }
         }
     }
 
@@ -343,29 +364,33 @@
 
     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-        Log.i(TAG, "Init fragment " + mCall.getCallId());
+        // Log.i(TAG, "Init fragment " + mCall.getCallId());
 
-        mCall.printCallInfo();
+        // mCall.printCallInfo();
+        if (mCalls.size() == 1) {
 
-        if (mCall.isIncoming() && mCall.isRinging()) {
-            initIncomingCallDisplay();
-        } else {
-            if (mCall.isRinging()) {
-                initOutGoingCallDisplay();
-            }
-            try {
-                if (mCall.isOutGoing() && mCallbacks.getService().getCall(mCall.getCallId()) == null) {
-                    mCallbacks.getService().placeCall(mCall);
-                    initOutGoingCallDisplay();
-                } else if (mCall.isOutGoing() && mCall.isRinging()) {
+            if (mCalls.get(0).isIncoming() && mCalls.get(0).isRinging()) {
+                initIncomingCallDisplay();
+            } else {
+                if (mCalls.get(0).isRinging()) {
                     initOutGoingCallDisplay();
                 }
-            } catch (RemoteException e) {
-                Log.e(TAG, e.toString());
+                try {
+                    if (mCalls.get(0).isOutGoing() && mCallbacks.getService().getCall(mCalls.get(0).getCallId()) == null) {
+                        mCallbacks.getService().placeCall(mCalls.get(0));
+                        initOutGoingCallDisplay();
+                    } else if (mCalls.get(0).isOutGoing() && mCalls.get(0).isRinging()) {
+                        initOutGoingCallDisplay();
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, e.toString());
+                }
             }
-        }
 
-        if (mCall.isOngoing()) {
+            if (mCalls.get(0).isOngoing()) {
+                initNormalStateDisplay();
+            }
+        } else {
             initNormalStateDisplay();
         }
 
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
index 68babaa..9ea78ee 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
@@ -48,7 +48,6 @@
 import android.view.ViewGroup;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
-import android.view.animation.RotateAnimation;
 import android.widget.BaseExpandableListAdapter;
 import android.widget.Button;
 import android.widget.ExpandableListView;
@@ -58,11 +57,12 @@
 import android.widget.Toast;
 
 import com.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.service.ISipService;
 
 public class CallListFragment extends Fragment {
-    static final String TAG = "CallFragment";
+    static final String TAG = CallListFragment.class.getSimpleName();
 
     private Callbacks mCallbacks = sDummyCallbacks;
 
@@ -90,7 +90,11 @@
         }
 
         @Override
-        public void onCallSelected(SipCall call) {
+        public void onCallSelected(ArrayList<SipCall> call) {
+        }
+
+        @Override
+        public void onCallsTerminated() {
         }
     };
 
@@ -101,7 +105,9 @@
     public interface Callbacks {
         public ISipService getService();
 
-        public void onCallSelected(SipCall call);
+        public void onCallSelected(ArrayList<SipCall> call);
+
+        public void onCallsTerminated();
 
     }
 
@@ -140,8 +146,40 @@
 
     public void update() {
         try {
+            Log.w(TAG, "Updating");
             HashMap<String, SipCall> list = (HashMap<String, SipCall>) mCallbacks.getService().getCallList();
-            mAdapter.update(list);
+
+            Toast.makeText(getActivity(), "Calls: "+list.size(), Toast.LENGTH_SHORT).show();
+            ArrayList<Conference> conferences = new ArrayList<Conference>();
+            ArrayList<String> tmp = (ArrayList<String>) mCallbacks.getService().getConferenceList();
+            for (String confid : tmp) {
+                Log.w(TAG, "Conference:"+confid);
+                Conference toAdd = new Conference(confid);
+                
+                toAdd.setState(mCallbacks.getService().getConferenceDetails(confid));
+                Toast.makeText(getActivity(), "State of Conf: "+toAdd.getState(), Toast.LENGTH_SHORT).show();
+                ArrayList<String> conf_participants = (ArrayList<String>) mCallbacks.getService().getParticipantList(confid);
+                for (String part : conf_participants) {
+                    Log.w(TAG, "participant:"+part);
+                    toAdd.getParticipants().add(list.get(part));
+                    list.remove(part);
+                }
+                conferences.add(toAdd);
+            }
+
+            ArrayList<SipCall> simple_calls = new ArrayList<SipCall>(list.values());
+            for (SipCall call : simple_calls) {
+                Log.w(TAG, "SimpleCall:"+call.getCallId());
+                Conference confOne = new Conference("-1");
+                confOne.getParticipants().add(call);
+                conferences.add(confOne);
+            }
+            
+            if(conferences.isEmpty()){
+                mCallbacks.onCallsTerminated();
+            }
+
+            mAdapter.update(conferences);
         } catch (RemoteException e) {
             Log.e(TAG, e.toString());
         }
@@ -152,25 +190,33 @@
         FragmentManager fm = getFragmentManager();
         TransferDFragment editNameDialog = new TransferDFragment();
 
-        Bundle b = new Bundle();
-        b.putParcelableArrayList("calls", mAdapter.getConcurrentCalls(groupPosition));
-        b.putParcelable("call_selected", mAdapter.getGroup(groupPosition));
-        editNameDialog.setArguments(b);
-        editNameDialog.setTargetFragment(this, REQUEST_TRANSFER);
-        editNameDialog.show(fm, "dialog");
+        if (mAdapter.getGroup(groupPosition).getParticipants().size() == 1) {
+            Bundle b = new Bundle();
+            b.putParcelableArrayList("calls", mAdapter.getConcurrentCalls(groupPosition));
+            b.putParcelable("call_selected", mAdapter.getGroup(groupPosition).getParticipants().get(0));
+            editNameDialog.setArguments(b);
+            editNameDialog.setTargetFragment(this, REQUEST_TRANSFER);
+            editNameDialog.show(fm, "dialog");
+        } else {
+            Toast.makeText(getActivity(), "Transfer a Conference ?", Toast.LENGTH_SHORT).show();
+        }
 
     }
 
     private void makeConferenceDialog(int groupPosition) {
         FragmentManager fm = getFragmentManager();
-        ConferenceDFragment confDialog = new ConferenceDFragment();
+        ConferenceDFragment confDialog = ConferenceDFragment.newInstance();
 
-        Bundle b = new Bundle();
-        b.putParcelableArrayList("calls", mAdapter.getConcurrentCalls(groupPosition));
-        b.putParcelable("call_selected", mAdapter.getGroup(groupPosition));
-        confDialog.setArguments(b);
-        confDialog.setTargetFragment(this, REQUEST_CONF);
-        confDialog.show(fm, "dialog");
+        if (mAdapter.getGroup(groupPosition).getParticipants().size() == 1) {
+            Bundle b = new Bundle();
+            b.putParcelableArrayList("calls", mAdapter.getConcurrentCalls(groupPosition));
+            b.putParcelable("call_selected", mAdapter.getGroup(groupPosition));
+            confDialog.setArguments(b);
+            confDialog.setTargetFragment(this, REQUEST_CONF);
+            confDialog.show(fm, "dialog");
+        } else {
+            Toast.makeText(getActivity(), "Already a Conference", Toast.LENGTH_SHORT).show();
+        }
 
     }
 
@@ -200,8 +246,7 @@
                 String to = data.getStringExtra("to_number");
                 transfer = data.getParcelableExtra("transfer");
                 try {
-                    Toast.makeText(getActivity(), "Transferring " + transfer.getContact().getmDisplayName() + " to " + to, Toast.LENGTH_SHORT)
-                            .show();
+                    Toast.makeText(getActivity(), "Transferring " + transfer.getContact().getmDisplayName() + " to " + to, Toast.LENGTH_SHORT).show();
                     mCallbacks.getService().transfer(transfer.getCallId(), to);
 
                 } catch (RemoteException e) {
@@ -216,11 +261,11 @@
         } else if (requestCode == REQUEST_CONF) {
             switch (resultCode) {
             case 0:
-                SipCall call1 = data.getParcelableExtra("call1");
-                SipCall call2 = data.getParcelableExtra("call2");
+                Conference call1 = data.getParcelableExtra("call1");
+                Conference call2 = data.getParcelableExtra("call2");
                 try {
 
-                    mCallbacks.getService().joinParticipant(call1.getCallId(), call2.getCallId());
+                    mCallbacks.getService().joinParticipant(call1.getParticipants().get(0).getCallId(), call2.getParticipants().get(0).getCallId());
 
                     // ArrayList<String> tmp = new ArrayList<String>();
                     // tmp.add(call1.getCallId());
@@ -246,14 +291,14 @@
      * 
      */
     public class CallListAdapter extends BaseExpandableListAdapter {
-        // Sample data set. children[i] contains the children (String[]) for groups[i].
-        private ArrayList<SipCall> calls;
+
+        private ArrayList<Conference> calls;
 
         private Context mContext;
         private int lastExpandedGroupPosition;
 
         public CallListAdapter(Context activity) {
-            calls = new ArrayList<SipCall>();
+            calls = new ArrayList<Conference>();
             mContext = activity;
         }
 
@@ -262,16 +307,16 @@
 
         }
 
-        public String getCurrentCall() {
-            for (int i = 0; i < calls.size(); ++i) {
-                if (calls.get(i).getCallStateInt() == SipCall.state.CALL_STATE_CURRENT)
-                    return calls.get(i).getCallId();
-            }
-            return "";
-        }
+        // public String getCurrentCall() {
+        // for (int i = 0; i < calls.size(); ++i) {
+        // if (calls.get(i).getCallStateInt() == SipCall.state.CALL_STATE_CURRENT)
+        // return calls.get(i).getCallId();
+        // }
+        // return "";
+        // }
 
-        public ArrayList<SipCall> getConcurrentCalls(int position) {
-            ArrayList<SipCall> toReturn = new ArrayList<SipCall>();
+        public ArrayList<Conference> getConcurrentCalls(int position) {
+            ArrayList<Conference> toReturn = new ArrayList<Conference>();
             for (int i = 0; i < calls.size(); ++i) {
                 if (position != i)
                     toReturn.add(calls.get(i));
@@ -279,7 +324,7 @@
             return toReturn;
         }
 
-        public ArrayList<SipCall> getCalls() {
+        public ArrayList<Conference> getCalls() {
             return calls;
         }
 
@@ -306,7 +351,11 @@
                 @Override
                 public void onClick(View v) {
                     try {
-                        mCallbacks.getService().hangUp(getGroup(groupPosition).getCallId());
+                        if (getGroup(groupPosition).getParticipants().size() == 1) {
+                            mCallbacks.getService().hangUp(getGroup(groupPosition).getParticipants().get(0).getCallId());
+                        } else {
+                            mCallbacks.getService().hangUpConference(getGroup(groupPosition).getId());
+                        }
                     } catch (RemoteException e) {
                         e.printStackTrace();
                     }
@@ -321,10 +370,19 @@
 
                     try {
                         if (((Button) v).getText().toString().contentEquals("Hold")) {
-                            mCallbacks.getService().hold(getGroup(groupPosition).getCallId());
+                            if (getGroup(groupPosition).getParticipants().size() == 1) {
+                                mCallbacks.getService().hold(getGroup(groupPosition).getParticipants().get(0).getCallId());
+                            } else {
+                                mCallbacks.getService().holdConference(getGroup(groupPosition).getId());
+                            }
+
                             ((Button) v).setText("Unhold");
                         } else {
-                            mCallbacks.getService().unhold(getGroup(groupPosition).getCallId());
+                            if (getGroup(groupPosition).getParticipants().size() == 1) {
+                                mCallbacks.getService().unhold(getGroup(groupPosition).getParticipants().get(0).getCallId());
+                            } else {
+                                mCallbacks.getService().unholdConference(getGroup(groupPosition).getId());
+                            }
                             ((Button) v).setText("Hold");
                         }
                     } catch (RemoteException e) {
@@ -356,7 +414,7 @@
         }
 
         @Override
-        public SipCall getGroup(int groupPosition) {
+        public Conference getGroup(int groupPosition) {
             return calls.get(groupPosition);
         }
 
@@ -393,15 +451,19 @@
             if (convertView == null)
                 convertView = LayoutInflater.from(mContext).inflate(R.layout.item_calllist, null);
 
-            SipCall call = getGroup(groupPosition);
-            ((TextView) convertView.findViewById(R.id.call_title)).setText(call.getContact().getmDisplayName());
-            ((TextView) convertView.findViewById(R.id.call_status)).setText("" + call.getCallStateString());
+            Conference call = getGroup(groupPosition);
+            if (call.getParticipants().size() == 1) {
+                ((TextView) convertView.findViewById(R.id.call_title)).setText(call.getParticipants().get(0).getContact().getmDisplayName());
+                ((TextView) convertView.findViewById(R.id.call_status)).setText(call.getParticipants().get(0).getCallStateString());
+            } else {
+                ((TextView) convertView.findViewById(R.id.call_title)).setText("Conference with "+call.getParticipants().size()+" participants");
+            }
 
             ((RelativeLayout) convertView.findViewById(R.id.call_entry)).setOnClickListener(new OnClickListener() {
 
                 @Override
                 public void onClick(View v) {
-                    mCallbacks.onCallSelected(getGroup(groupPosition));
+                    mCallbacks.onCallSelected(getGroup(groupPosition).getParticipants());
 
                 }
             });
@@ -440,9 +502,9 @@
             return false;
         }
 
-        public void update(HashMap<String, SipCall> list) {
+        public void update(ArrayList<Conference> list) {
             calls.clear();
-            calls.addAll(list.values());
+            calls.addAll(list);
             notifyDataSetChanged();
 
         }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java b/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java
index 9f0b4e5..06a4d72 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java
@@ -1,8 +1,6 @@
 package com.savoirfairelinux.sflphone.fragments;
 
-import java.io.IOException;
 import java.util.ArrayList;
-import java.util.List;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -10,11 +8,8 @@
 import android.app.LoaderManager;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.DialogInterface.OnShowListener;
 import android.content.Intent;
 import android.content.Loader;
-import android.location.Address;
-import android.location.Geocoder;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
@@ -23,19 +18,14 @@
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.AutoCompleteTextView;
 import android.widget.BaseAdapter;
-import android.widget.Button;
-import android.widget.Filter;
-import android.widget.Filterable;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import com.savoirfairelinux.sflphone.R;
 import com.savoirfairelinux.sflphone.loaders.ContactsLoader;
 import com.savoirfairelinux.sflphone.model.CallContact;
+import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
 
 public class ConferenceDFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Bundle> {
@@ -46,7 +36,7 @@
     /**
      * Create a new instance of CallActionsDFragment
      */
-    static ConferenceDFragment newInstance(int num) {
+    static ConferenceDFragment newInstance() {
         ConferenceDFragment f = new ConferenceDFragment();
         return f;
     }
@@ -64,8 +54,8 @@
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_conference, null);
 
-        ArrayList<SipCall> calls = getArguments().getParcelableArrayList("calls");
-        final SipCall call_selected = getArguments().getParcelable("call_selected");
+        ArrayList<Conference> calls = getArguments().getParcelableArrayList("calls");
+        final Conference call_selected = getArguments().getParcelable("call_selected");
 
         mAdapter = new SimpleCallListAdapter(getActivity(), calls);
         ListView list = (ListView) rootView.findViewById(R.id.concurrent_calls);
@@ -87,7 +77,7 @@
 
         
 
-        final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView).setTitle("Transfer " + call_selected.getContact())
+        final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView).setTitle("Transfer " + call_selected.getParticipants().get(0).getContact())
                 .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int whichButton) {
 
@@ -130,9 +120,9 @@
     private class SimpleCallListAdapter extends BaseAdapter {
 
         private LayoutInflater mInflater;
-        ArrayList<SipCall> calls;
+        ArrayList<Conference> calls;
 
-        public SimpleCallListAdapter(final Context context, ArrayList<SipCall> calls2) {
+        public SimpleCallListAdapter(final Context context, ArrayList<Conference> calls2) {
             super();
             mInflater = LayoutInflater.from(context);
             calls = calls2;
@@ -147,7 +137,12 @@
                 tv = (TextView) mInflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
             }
 
-            tv.setText(calls.get(position).getContact().getmDisplayName());
+            if(calls.get(position).getParticipants().size() == 1){
+                tv.setText(calls.get(position).getParticipants().get(0).getContact().getmDisplayName());
+            } else {
+                tv.setText("Conference with "+ calls.get(position).getParticipants().size() + " participants");
+            }
+            
             return tv;
         }
 
@@ -157,7 +152,7 @@
         }
 
         @Override
-        public SipCall getItem(int pos) {
+        public Conference getItem(int pos) {
             return calls.get(pos);
         }
 
diff --git a/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java b/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
index dfc190e..ded9c96 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
@@ -50,9 +50,7 @@
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.service.ISipService;
 
-/**
- * Main list of Call Elements. We don't manage contacts ourself so they are
- */
+
 public class HomeFragment extends Fragment {
     private static final String TAG = HomeFragment.class.getSimpleName();
 
@@ -123,38 +121,6 @@
         mCallbacks = sDummyCallbacks;
     }
 
-    /**
-     * Runnable that fill information in a contact card asynchroniously.
-     */
-    /*
-     * public static class InfosLoader implements Runnable { private View view; private long cid; private ContentResolver cr;
-     * 
-     * public InfosLoader(Context context, View element, long contact_id) { cid = contact_id; cr = context.getContentResolver(); view = element; }
-     * 
-     * public static Bitmap loadContactPhoto(ContentResolver cr, long id) { Uri uri =
-     * ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id); InputStream input =
-     * ContactsContract.Contacts.openContactPhotoInputStream(cr, uri); if (input == null) { return null; } return BitmapFactory.decodeStream(input); }
-     * 
-     * @Override public void run() { final Bitmap photo_bmp = loadContactPhoto(cr, cid);
-     * 
-     * Cursor phones = cr.query(CommonDataKinds.Phone.CONTENT_URI, CONTACTS_PHONES_PROJECTION, CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]
-     * { Long.toString(cid) }, null);
-     * 
-     * final List<String> numbers = new ArrayList<String>(); while (phones.moveToNext()) { String number =
-     * phones.getString(phones.getColumnIndex(CommonDataKinds.Phone.NUMBER)); // int type =
-     * phones.getInt(phones.getColumnIndex(CommonDataKinds.Phone.TYPE)); numbers.add(number); } phones.close(); // TODO: same for SIP adresses.
-     * 
-     * final Bitmap bmp = photo_bmp; view.post(new Runnable() {
-     * 
-     * @Override public void run() { } }); } }
-     */
-
-
-    // public void removeCall(SipCall c) {
-    // Log.i(TAG, "Removing call " + c.mCallInfo.mDisplayName);
-    // mAdapter.remove(c);
-    // }
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -183,22 +149,6 @@
 
     }
 
-//    private static final int REQUEST_CODE_PREFERENCES = 1;
-//
-//    @Override
-//    public boolean onOptionsItemSelected(MenuItem item) {
-//        Log.i(TAG, "onOptionsItemSelected " + item.getItemId());
-//        switch (item.getItemId()) {
-//        case R.id.menu_settings:
-//            Intent launchPreferencesIntent = new Intent().setClass(getActivity(), SFLPhonePreferenceActivity.class);
-//            startActivityForResult(launchPreferencesIntent, SFLPhoneHomeActivity.REQUEST_CODE_PREFERENCES);
-//            break;
-//        }
-//
-//        return super.onOptionsItemSelected(item);
-//    }
-
-
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -225,63 +175,6 @@
 
             }
         });
-        
-        
-
-        // ((Button) inflatedView.findViewById(R.id.button_attended)).setOnClickListener(new OnClickListener() {
-        //
-        // @Override
-        // public void onClick(View v) {
-        // if (mAdapter.getCount() == 2) {
-        // try {
-        // service.attendedTransfer(mAdapter.getItem(0).getCallId(), mAdapter.getItem(1).getCallId());
-        // mAdapter.clear();
-        // } catch (RemoteException e) {
-        // Log.e(TAG, e.toString());
-        // }
-        // } else {
-        // Toast.makeText(getActivity(), "You need two calls one on Hold the other current to bind them", Toast.LENGTH_LONG).show();
-        // }
-        //
-        // }
-        // });
-
-        // ((Button) inflatedView.findViewById(R.id.button_conf)).setOnClickListener(new OnClickListener() {
-        //
-        // @Override
-        // public void onClick(View v) {
-        // if (mAdapter.getCount() == 2) {
-        // try {
-        // service.joinParticipant(mAdapter.getItem(0).getCallId(), mAdapter.getItem(1).getCallId());
-        // } catch (RemoteException e) {
-        // Log.e(TAG, e.toString());
-        // }
-        // } else {
-        // Toast.makeText(getActivity(), "You need two calls one on Hold the other current to create a conference", Toast.LENGTH_LONG)
-        // .show();
-        // }
-        // }
-        // });
-
-        // ((ToggleButton) inflatedView.findViewById(R.id.switch_hold)).setOnCheckedChangeListener(new OnCheckedChangeListener() {
-        //
-        // @Override
-        // public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-        // try {
-        // ArrayList<String> confList = (ArrayList<String>) service.getConferenceList();
-        // if (!confList.isEmpty()) {
-        // if (isChecked) {
-        // service.holdConference(confList.get(0));
-        // } else {
-        // service.unholdConference(confList.get(0));
-        // }
-        // }
-        // } catch (RemoteException e) {
-        // Log.e(TAG, e.toString());
-        // }
-        //
-        // }
-        // });
 
         return inflatedView;
     }
diff --git a/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java b/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java
index bf50872..ce89fda 100644
--- a/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java
+++ b/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java
@@ -9,5 +9,11 @@
     public void callStateChanged(Intent callState);
 
     public void incomingText(Intent msg);
+
+    public void confCreated(Intent intent);
+
+    public void confRemoved(Intent intent);
+
+    public void confChanged(Intent intent);
     
 }
diff --git a/src/com/savoirfairelinux/sflphone/model/Bubble.java b/src/com/savoirfairelinux/sflphone/model/Bubble.java
index 6294dab..b71c618 100644
--- a/src/com/savoirfairelinux/sflphone/model/Bubble.java
+++ b/src/com/savoirfairelinux/sflphone/model/Bubble.java
@@ -15,10 +15,11 @@
 import com.savoirfairelinux.sflphone.R;
 
 public class Bubble {
-    public CallContact contact;
+
     // A Bitmap object that is going to be passed to the BitmapShader
     private Bitmap internalBMP, externalBMP;
 
+    public SipCall associated_call;
     private PointF pos = new PointF();
     private RectF bounds;
     public float target_scale = 1.f;
@@ -39,11 +40,11 @@
         this.attractor = attractor;
     }
 
-    public Bubble(float x, float y, float size, Bitmap photo) {
+    public Bubble(SipCall call, float x, float y, float size, Bitmap photo) {
         saved_photo = photo;
         internalBMP = Bitmap.createScaledBitmap(photo, (int) size, (int) size, false);
         int w = internalBMP.getWidth(), h = internalBMP.getHeight();
-
+        associated_call = call;
         pos.set(x, y);
         radius = w / 2;
         bounds = new RectF(pos.x - radius, pos.y - radius, pos.x + radius, pos.y + radius);
@@ -65,9 +66,9 @@
         canvas.drawBitmap(circle, 0, 0, circlePaint);
     }
 
-    public Bubble(float x, float y, float rad, Context c, int resID) {
+    public Bubble(SipCall call, float x, float y, float rad, Context c, int resID) {
         // Initialize the bitmap object by loading an image from the resources folder
-        this(x, y, rad, BitmapFactory.decodeResource(c.getResources(), resID == -1 ? resID : R.drawable.ic_contact_picture));
+        this(call, x, y, rad, BitmapFactory.decodeResource(c.getResources(), resID == -1 ? resID : R.drawable.ic_contact_picture));
     }
 
     public Bitmap getBitmap() {
diff --git a/src/com/savoirfairelinux/sflphone/model/BubblesView.java b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
index 8accf4c..0f1b33f 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubblesView.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
@@ -259,7 +259,7 @@
                     for (int i = 0, n = bubbles.size(); i < n; i++) {

                         Bubble b = bubbles.get(i);

                         canvas.drawBitmap(b.getBitmap(), null, b.getBounds(), null);

-                        canvas.drawText(b.contact.getmDisplayName(), b.getPosX(), b.getPosY() - 50 * density, name_paint);

+                        canvas.drawText(b.associated_call.getContact().getmDisplayName(), b.getPosX(), b.getPosY() - 50 * density, name_paint);

 

                     }

 

diff --git a/src/com/savoirfairelinux/sflphone/model/Conference.java b/src/com/savoirfairelinux/sflphone/model/Conference.java
index f7578f7..26ddf63 100644
--- a/src/com/savoirfairelinux/sflphone/model/Conference.java
+++ b/src/com/savoirfairelinux/sflphone/model/Conference.java
@@ -1,31 +1,98 @@
 package com.savoirfairelinux.sflphone.model;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 
-public class Conference {
-    
-    private long id;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class Conference implements Parcelable {
+
+    private String id;
     private String state;
     private ArrayList<SipCall> participants;
-    
-    
-    public long getId() {
+
+    public interface state {
+        int ACTIVE_ATTACHED = 0;
+        int ACTIVE_DETACHED = 1;
+        int ACTIVE_ATTACHED_REC = 2;
+        int ACTIVE_DETACHED_REC = 3;
+        int HOLD = 4;
+        int HOLD_REC = 5;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+
+        out.writeString(id);
+        out.writeString(state);
+        out.writeTypedList(participants);
+
+    }
+
+    public static final Parcelable.Creator<Conference> CREATOR = new Parcelable.Creator<Conference>() {
+        public Conference createFromParcel(Parcel in) {
+            return new Conference(in);
+        }
+
+        public Conference[] newArray(int size) {
+            return new Conference[size];
+        }
+    };
+
+    private Conference(Parcel in) {
+
+        participants = new ArrayList<SipCall>();
+        id = in.readString();
+        state = in.readString();
+        in.readTypedList(participants, SipCall.CREATOR);
+
+    }
+
+    public Conference(String cID) {
+        id = cID;
+        participants = new ArrayList<SipCall>();
+    }
+
+    public String getId() {
         return id;
     }
-    public void setId(long id) {
+
+    public void setId(String id) {
         this.id = id;
     }
+
     public String getState() {
         return state;
     }
+
     public void setState(String state) {
         this.state = state;
     }
+
     public ArrayList<SipCall> getParticipants() {
         return participants;
     }
-    public void setParticipants(ArrayList<SipCall> participants) {
-        this.participants = participants;
+
+    public boolean contains(String callID) {
+        for (int i = 0 ; i < participants.size() ; ++i){
+            if(participants.get(i).getCallId().contentEquals(callID))
+                return true;
+        }
+        return false;
+    }
+
+    public SipCall getCall(String callID) {
+        for (int i = 0 ; i < participants.size() ; ++i){
+            if(participants.get(i).getCallId().contentEquals(callID))
+                return participants.get(i);
+        }
+        return null;
     }
 
 }
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.java b/src/com/savoirfairelinux/sflphone/model/SipCall.java
index 42014f2..6b9da85 100644
--- a/src/com/savoirfairelinux/sflphone/model/SipCall.java
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.java
@@ -33,6 +33,7 @@
 import java.util.ArrayList;
 import java.util.Random;
 
+import android.content.ContentResolver;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
@@ -328,6 +329,12 @@
             return new SipCallBuilder();
         }
 
+        public static SipCall buildMyselfCall(ContentResolver cr, String displayName) {
+            return new SipCall("default", "default", SipCall.state.CALL_TYPE_UNDETERMINED, state.CALL_STATE_NONE, state.MEDIA_STATE_NONE,
+                    CallContact.ContactBuilder.buildUserContact(cr, ""));
+
+        }
+
     }
 
     public void printCallInfo() {
diff --git a/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java b/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java
index 78d3ebb..4642b54 100644
--- a/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java
+++ b/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java
@@ -57,7 +57,13 @@
 	        callback.incomingText(intent);
 	    } else if(intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)){
 	        callback.callStateChanged(intent);
-	    } else {
+	    } else if(intent.getAction().contentEquals(CallManagerCallBack.CONF_CREATED)){
+            callback.confCreated(intent);
+        }else if(intent.getAction().contentEquals(CallManagerCallBack.CONF_REMOVED)){
+            callback.confRemoved(intent);
+        }else if(intent.getAction().contentEquals(CallManagerCallBack.CONF_CHANGED)){
+            callback.confChanged(intent);
+        }else {
 	        Log.e(TAG, "Unknown action: "+intent.getAction());
 	    }
 
diff --git a/src/com/savoirfairelinux/sflphone/receivers/IncomingReceiver.java b/src/com/savoirfairelinux/sflphone/receivers/IncomingReceiver.java
index e3ac34f..536395f 100644
--- a/src/com/savoirfairelinux/sflphone/receivers/IncomingReceiver.java
+++ b/src/com/savoirfairelinux/sflphone/receivers/IncomingReceiver.java
@@ -1,17 +1,23 @@
 package com.savoirfairelinux.sflphone.receivers;
 
+import java.util.ArrayList;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.os.Vibrator;
 import android.util.Log;
+import android.widget.Toast;
 
 import com.savoirfairelinux.sflphone.interfaces.CallInterface;
 import com.savoirfairelinux.sflphone.model.CallContact;
+import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.service.CallManagerCallBack;
 import com.savoirfairelinux.sflphone.service.ConfigurationManagerCallback;
+import com.savoirfairelinux.sflphone.service.ISipService.Stub;
 import com.savoirfairelinux.sflphone.service.SipService;
 
 public class IncomingReceiver extends BroadcastReceiver{
@@ -19,23 +25,31 @@
     static final String TAG = IncomingReceiver.class.getSimpleName();
 
     SipService callback;
+    Stub mBinder;
     
-    public IncomingReceiver(SipService client){
+    public IncomingReceiver(SipService client, Stub bind){
         callback = client;
+        mBinder = bind;
     }
     
     @Override
     public void onReceive(Context context, Intent intent) {
 
         if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED)) {
+            
             Log.i(TAG, "Received" + intent.getAction());
             callback.sendBroadcast(intent);
+            
         } else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_CHANGED)) {
+            
             Log.i(TAG, "Received" + intent.getAction());
             callback.sendBroadcast(intent);
+            
         } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)) {
+            
             Log.i(TAG, "Received" + intent.getAction());
             callback.sendBroadcast(intent);
+            
         } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
             Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newcall");
 
@@ -79,8 +93,45 @@
             }
 
             callback.sendBroadcast(intent);
+            
         } else if (intent.getAction().contentEquals(CallManagerCallBack.NEW_CALL_CREATED)) {
+            
             Log.i(TAG, "Received" + intent.getAction());
+            
+        } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CREATED)) {
+            
+            Log.i(TAG, "Received" + intent.getAction());
+            Conference created = new Conference(intent.getStringExtra("confID"));
+            ArrayList<String> all_participants;
+            try {
+                all_participants = (ArrayList<String>) mBinder.getParticipantList(intent.getStringExtra("confID"));
+                for(String participant : all_participants){
+                    created.getParticipants().add(callback.getCurrent_calls().get(participant));
+                }
+                Intent toSend = new Intent(CallManagerCallBack.CONF_CREATED);
+                toSend.putExtra("newconf", created);
+                callback.getCurrent_confs().put(intent.getStringExtra("confID"), created);
+                callback.sendBroadcast(toSend);
+            } catch (RemoteException e1) {
+                e1.printStackTrace();
+            }
+            Log.i(TAG, "current_confs size " + callback.getCurrent_confs().size());
+            
+        } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_REMOVED)) {
+            
+            Log.i(TAG, "Received" + intent.getAction());
+            Conference toDestroy = callback.getCurrent_confs().get(intent.getStringExtra("confID"));
+            for(int i = 0; i < toDestroy.getParticipants().size() ; ++i){
+                callback.getCurrent_calls().put(toDestroy.getParticipants().get(i).getCallId(), toDestroy.getParticipants().get(i));
+            }
+            callback.getCurrent_confs().remove(intent.getStringExtra("confID"));
+            Toast.makeText(callback, "Removed conf ", Toast.LENGTH_SHORT).show();
+            
+        } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CHANGED)) {
+            
+            Log.i(TAG, "Received" + intent.getAction());
+            callback.getCurrent_confs().get(intent.getStringExtra("confID")).setState(intent.getStringExtra("State"));
+            Toast.makeText(callback, "Changing conf state: "+ intent.getStringExtra("State"), Toast.LENGTH_SHORT).show();
         }
 
     }
diff --git a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
index b1a7d81..f8a352f 100644
--- a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
+++ b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
@@ -16,6 +16,8 @@
     static public final String INCOMING_CALL = "incoming-call";
     static public final String INCOMING_TEXT = "incoming-text";
     static public final String CONF_CREATED = "conf_created";
+    static public final String CONF_REMOVED = "conf_removed";
+    static public final String CONF_CHANGED = "conf_changed";
 
 
     public CallManagerCallBack(Context context) {
@@ -25,7 +27,7 @@
     @Override
     public void on_new_call_created(String accountID, String callID, String to) {
         Log.d(TAG, "on_new_call_created(" + accountID + ", " + callID + ", " + to + ")");
-        sendNewCallCreatedMessage(accountID, callID, to);
+
     }
 
     @Override
@@ -48,10 +50,8 @@
     @Override
     public void on_conference_created(String confID){
         Log.w(TAG,"CONFERENCE CREATED:"+confID);
-        Bundle bundle = new Bundle();
-        bundle.putString("confID", confID);
-        Intent intent = new Intent(NEW_CALL_CREATED);
-        intent.putExtra("com.savoirfairelinux.sflphone.service.newcall", bundle);
+        Intent intent = new Intent(CONF_CREATED);
+        intent.putExtra("confID", confID);
         LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
     
@@ -64,20 +64,17 @@
     @Override
     public void on_conference_removed(String confID){
         Log.w(TAG,"CONFERENCE REMOVED:"+confID);
+        Intent intent = new Intent(CONF_REMOVED);
+        intent.putExtra("confID", confID);
+        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
     
     @Override
     public void on_conference_state_changed(String confID, String state){
         Log.w(TAG,"CONFERENCE STATE CHANGED:"+confID);
-    }
-
-    private void sendNewCallCreatedMessage(String accountID, String callID, String to) {
-        Bundle bundle = new Bundle();
-        bundle.putString("AccountID", accountID);
-        bundle.putString("CallID", callID);
-        bundle.putString("To", to);
-        Intent intent = new Intent(NEW_CALL_CREATED);
-        intent.putExtra("com.savoirfairelinux.sflphone.service.newcall", bundle);
+        Intent intent = new Intent(CONF_CHANGED);
+        intent.putExtra("confID", confID);
+        intent.putExtra("State", state);
         LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
 
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
index 7d1e842..15569b8 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
@@ -44,7 +44,7 @@
     void removeConference(in String confID);
     void joinParticipant(in String sel_callID, in String drag_callID);
 
-    void addParticipant(in String callID, in String confID);
+    void addParticipant(in SipCall call, in String confID);
     void addMainParticipant(in String confID);
     void detachParticipant(in String callID);
     void joinConference(in String sel_confID, in String drag_confID);
@@ -55,7 +55,7 @@
     Map getCallList();
     List getParticipantList(in String confID);
     String getConferenceId(in String callID);
-    Map getConferenceDetails(in String callID);
+    String getConferenceDetails(in String callID);
     
     
     /*   */
diff --git a/src/com/savoirfairelinux/sflphone/service/SipService.java b/src/com/savoirfairelinux/sflphone/service/SipService.java
index 1fe89c0..9f1c193 100644
--- a/src/com/savoirfairelinux/sflphone/service/SipService.java
+++ b/src/com/savoirfairelinux/sflphone/service/SipService.java
@@ -30,6 +30,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Random;
 
 import android.app.Notification;
@@ -53,10 +54,10 @@
 
 import com.savoirfairelinux.sflphone.R;
 import com.savoirfairelinux.sflphone.account.AccountDetailsHandler;
-import com.savoirfairelinux.sflphone.account.AudioHandler;
 import com.savoirfairelinux.sflphone.account.HistoryHandler;
 import com.savoirfairelinux.sflphone.client.SFLPhoneHomeActivity;
 import com.savoirfairelinux.sflphone.client.SFLphoneApplication;
+import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.receivers.IncomingReceiver;
 
@@ -80,8 +81,12 @@
     public static final String NOTIF_DELETION = "notif_deletion";
 
     private HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
+    private HashMap<String, Conference> current_confs = new HashMap<String, Conference>();
+    private IncomingReceiver receiver;
 
-    private IncomingReceiver receiver = new IncomingReceiver(this);
+    public HashMap<String, Conference> getCurrent_confs() {
+        return current_confs;
+    }
 
     @Override
     public boolean onUnbind(Intent i) {
@@ -106,7 +111,10 @@
         callFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
         callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
         callFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
-
+        callFilter.addAction(CallManagerCallBack.CONF_CREATED);
+        callFilter.addAction(CallManagerCallBack.CONF_REMOVED);
+        callFilter.addAction(CallManagerCallBack.CONF_CHANGED);
+        receiver = new IncomingReceiver(this, mBinder);
         LocalBroadcastManager.getInstance(this).registerReceiver(receiver, callFilter);
 
         getExecutor().execute(new StartRunnable());
@@ -119,6 +127,7 @@
         Log.i(TAG, "onStarted");
         super.onStartCommand(intent, flags, startId);
 
+        receiver = new IncomingReceiver(this, mBinder);
         if (!runFlag) {
             sipServiceThread.start();
             runFlag = true;
@@ -251,10 +260,6 @@
         return current_calls;
     }
 
-    public void setCurrent_calls(HashMap<String, SipCall> current_calls) {
-        this.current_calls = current_calls;
-    }
-
     // Enforce same thread contract to ensure we do not call from somewhere else
     public class SameThreadException extends Exception {
         private static final long serialVersionUID = -905639124232613768L;
@@ -510,7 +515,7 @@
                     VectMap swigmap = new VectMap();
                     StringMap entry = new StringMap();
                     entry.set(ServiceConstants.CONFIG_ACCOUNT_USERNAME, (String) map.get(ServiceConstants.CONFIG_ACCOUNT_USERNAME));
-                    if((String) map.get(ServiceConstants.CONFIG_ACCOUNT_REALM) != null)
+                    if ((String) map.get(ServiceConstants.CONFIG_ACCOUNT_REALM) != null)
                         entry.set(ServiceConstants.CONFIG_ACCOUNT_REALM, (String) map.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
                     else
                         entry.set(ServiceConstants.CONFIG_ACCOUNT_REALM, "*");
@@ -530,7 +535,7 @@
                 Log.i(TAG, "Entry " + i);
                 StringMap tmp = swigmap.get(i);
                 Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_USERNAME));
-//                Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
+                // Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_REALM));
                 Log.i(TAG, tmp.get(ServiceConstants.CONFIG_ACCOUNT_PASSWORD));
             }
 
@@ -663,19 +668,20 @@
                 protected void doRun() throws SameThreadException, RemoteException {
                     Log.i(TAG, "SipService.joinParticipant() thread running...");
                     callManagerJNI.joinParticipant(sel_callID, drag_callID);
+                    // Generate a CONF_CREATED callback
                 }
             });
 
         }
 
-
         @Override
-        public void addParticipant(final String callID, final String confID) throws RemoteException {
+        public void addParticipant(final SipCall call, final String confID) throws RemoteException {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
                     Log.i(TAG, "SipService.addParticipant() thread running...");
-                    callManagerJNI.addParticipant(callID, confID);
+                    callManagerJNI.addParticipant(call.getCallId(), confID);
+                    current_confs.get(confID).getParticipants().add(call);
                 }
             });
 
@@ -699,6 +705,17 @@
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
                     Log.i(TAG, "SipService.detachParticipant() thread running...");
+                    Log.i(TAG, "Detaching " + callID);
+                    Iterator<Entry<String, Conference>> it = current_confs.entrySet().iterator();
+                    Log.i(TAG, "current_confs size " + current_confs.size());
+                    while (it.hasNext()) {
+                        Conference tmp = it.next().getValue();
+                        Log.i(TAG, "conf has " + tmp.getParticipants().size() + " participants");
+                        if (tmp.contains(callID)) {
+                            current_calls.put(callID, tmp.getCall(callID));
+                            Log.i(TAG, "Call found and put in current_calls");
+                        }
+                    }
                     callManagerJNI.detachParticipant(callID);
                 }
             });
@@ -758,7 +775,7 @@
             class ConfList extends SipRunnableWithReturn {
                 @Override
                 protected StringVect doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getAccountList() thread running...");
+                    Log.i(TAG, "SipService.getConferenceList() thread running...");
                     return callManagerJNI.getConferenceList();
                 }
             }
@@ -802,7 +819,7 @@
 
             return nativelist;
         }
-        
+
         @Override
         public String getConferenceId(String callID) throws RemoteException {
             Log.e(TAG, "getConferenceList not implemented");
@@ -810,29 +827,23 @@
         }
 
         @Override
-        public Map getConferenceDetails(final String callID) throws RemoteException {
-//            class ConfDetails extends SipRunnableWithReturn {
-//                @Override
-//                protected StringMap doRun() throws SameThreadException {
-//                    Log.i(TAG, "SipService.getAccountList() thread running...");
-//                    return callManagerJNI.getConferenceDetails(callID);
-//                }
-//            }
-//            ;
-//            ConfDetails runInstance = new ConfDetails();
-//            getExecutor().execute(runInstance);
-//            while (!runInstance.isDone()) {
-//                // Log.w(TAG, "Waiting for getConferenceList");
-//            }
-//            StringMap swigvect = (StringMap) runInstance.getVal();
-//
-//            HashMap<String,String> nativelist = new HashMap<String,String>();
-//
-//            for (int i = 0; i < swigvect.size(); i++)
-//                nativelist.put(swigvect.);
-//
-//            return nativelist;
-            return null;
+        public String getConferenceDetails(final String callID) throws RemoteException {
+            class ConfDetails extends SipRunnableWithReturn {
+                @Override
+                protected StringMap doRun() throws SameThreadException {
+                    Log.i(TAG, "SipService.getAccountList() thread running...");
+                    return callManagerJNI.getConferenceDetails(callID);
+                }
+            }
+            ;
+            ConfDetails runInstance = new ConfDetails();
+            getExecutor().execute(runInstance);
+            while (!runInstance.isDone()) {
+                // Log.w(TAG, "Waiting for getConferenceList");
+            }
+            StringMap swigvect = (StringMap) runInstance.getVal();
+
+            return swigvect.get("CONF_STATE");
         }
 
         @Override
@@ -893,25 +904,25 @@
 
         @Override
         public List getAudioCodecList(String accountID) throws RemoteException {
-//            class AudioCodecList extends SipRunnableWithReturn {
-//
-//                @Override
-//                protected IntVect doRun() throws SameThreadException {
-//                    Log.i(TAG, "SipService.getAudioCodecList() thread running...");
-//                    return configurationManagerJNI.getAudioCodecList();
-//                }
-//            }
-//
-//            AudioCodecList runInstance = new AudioCodecList();
-//            getExecutor().execute(runInstance);
-//            while (!runInstance.isDone()) {
-//                Log.w(TAG, "Waiting for getAudioCodecList");
-//            }
-//            IntVect swigmap = (IntVect) runInstance.getVal();
-//
-//            ArrayList<Integer> codecs = AudioHandler.convertSwigToNative(swigmap);
-//
-//            return codecs;
+            // class AudioCodecList extends SipRunnableWithReturn {
+            //
+            // @Override
+            // protected IntVect doRun() throws SameThreadException {
+            // Log.i(TAG, "SipService.getAudioCodecList() thread running...");
+            // return configurationManagerJNI.getAudioCodecList();
+            // }
+            // }
+            //
+            // AudioCodecList runInstance = new AudioCodecList();
+            // getExecutor().execute(runInstance);
+            // while (!runInstance.isDone()) {
+            // Log.w(TAG, "Waiting for getAudioCodecList");
+            // }
+            // IntVect swigmap = (IntVect) runInstance.getVal();
+            //
+            // ArrayList<Integer> codecs = AudioHandler.convertSwigToNative(swigmap);
+            //
+            // return codecs;
             return null;
         }
 
@@ -994,7 +1005,5 @@
 
         }
 
-        
-
     };
 }