* #25270 Overall improvements of transitions between calls and call actions
* #25117 Refactor and stability
diff --git a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
index 6226021..13cb87e 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
@@ -23,7 +23,7 @@
     ArrayList<Account> accounts;
     Context mContext;
     ISipService service;
-    int selectedAccount = 0;
+    int selectedAccount = -1;
 
     public AccountSelectionAdapter(Context cont, ISipService s, ArrayList<Account> newList) {
         super();
@@ -90,6 +90,9 @@
     }
 
     public Account getSelectedAccount() {
+        if(selectedAccount == -1){
+            return null;
+        }
         return accounts.get(selectedAccount);
     }
 
diff --git a/src/com/savoirfairelinux/sflphone/client/CallActivity.java b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
index 75ce0c3..16c47e1 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
@@ -33,7 +33,6 @@
 
 package com.savoirfairelinux.sflphone.client;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 
 import android.app.Activity;
@@ -44,7 +43,6 @@
 import android.content.ServiceConnection;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.support.v4.widget.SlidingPaneLayout;
@@ -57,6 +55,7 @@
 import com.savoirfairelinux.sflphone.fragments.CallListFragment;
 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.model.SipCall.state;
 import com.savoirfairelinux.sflphone.receivers.CallReceiver;
@@ -75,6 +74,7 @@
 
     CallListFragment mCallsFragment;
     CallFragment mCurrentCallFragment;
+    private boolean fragIsChanging;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -88,9 +88,7 @@
         getFragmentManager().beginTransaction().replace(R.id.calllist_pane, mCallsFragment).commit();
 
         slidingPaneLayout = (CallPaneLayout) findViewById(R.id.slidingpanelayout);
-        // slidingPaneLayout.
-        // slidingPaneLayout.requestDisallowInterceptTouchEvent(disallowIntercept)
-        // Toast.makeText(this, getIntent().getData().toString(), Toast.LENGTH_LONG).show();
+
         slidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
 
             @Override
@@ -115,8 +113,14 @@
 
                 switch (view.getId()) {
                 case R.id.ongoingcall_pane:
-                    Log.i(TAG, "PANEL CLOSED DRAWING SHOULD RESTART");
-                    mCurrentCallFragment.getBubbleView().restartDrawing();
+                    if (fragIsChanging) {
+                        getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment).commit();
+
+                        fragIsChanging = false;
+                    } else {
+                        mCurrentCallFragment.getBubbleView().restartDrawing();
+                    }
+
                     break;
                 default:
                     break;
@@ -126,7 +130,7 @@
 
         Intent intent = new Intent(this, SipService.class);
         bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
-
+        slidingPaneLayout.setCoveredFadeColor(0xFFFF0000);
     }
 
     /* activity gets back to the foreground and user input */
@@ -137,6 +141,10 @@
         intentFilter.addAction(CallManagerCallBack.INCOMING_CALL);
         intentFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
         intentFilter.addAction(CallManagerCallBack.CALL_STATE_CHANGED);
+        intentFilter.addAction(CallManagerCallBack.CONF_CREATED);
+        intentFilter.addAction(CallManagerCallBack.CONF_REMOVED);
+        intentFilter.addAction(CallManagerCallBack.CONF_CHANGED);
+        intentFilter.addAction(CallManagerCallBack.RECORD_STATE_CHANGED);
         registerReceiver(receiver, intentFilter);
         super.onResume();
     }
@@ -175,7 +183,7 @@
         @Override
         public void onServiceConnected(ComponentName className, IBinder binder) {
             service = ISipService.Stub.asInterface(binder);
-            Log.i(TAG, "Placing call");
+
             mCurrentCallFragment = new CallFragment();
             Uri u = getIntent().getData();
             if (u != null) {
@@ -184,20 +192,31 @@
                     service.destroyNotification();
                     SipCall call = SipCall.SipCallBuilder.getInstance().startCallCreation().setContact(c)
                             .setAccountID(service.getAccountList().get(1).toString()).setCallType(SipCall.state.CALL_TYPE_OUTGOING).build();
+                    Conference tmp = new Conference("-1");
+                    tmp.getParticipants().add(call);
                     Bundle b = new Bundle();
-                    b.putParcelable("CallInfo", call);
+                    b.putParcelable("conference", tmp);
                     Log.i(TAG, "Arguments set");
                     mCurrentCallFragment.setArguments(b);
                 } catch (RemoteException e) {
-                    // TODO Auto-generated catch block
                     e.printStackTrace();
                 } catch (Exception e) {
-                    // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
-
             } else {
-                mCurrentCallFragment.setArguments(getIntent().getExtras());
+                if (getIntent().getBooleanExtra("resuming", false)) {
+
+                    Bundle b = new Bundle();
+                    try {
+                        b.putParcelable("conference", (Conference) service.getCurrentCall());
+                        mCurrentCallFragment.setArguments(b);
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
+                    }
+                } else {
+                    mCurrentCallFragment.setArguments(getIntent().getExtras());
+                }
+
             }
 
             slidingPaneLayout.setCurFragment(mCurrentCallFragment);
@@ -239,10 +258,9 @@
 
         mCurrentCallFragment.changeCallState(callID, newState);
 
-        HashMap<String, SipCall> callMap;
         try {
-            callMap = (HashMap<String, SipCall>) service.getCallList();
-            ArrayList<String> confMap = (ArrayList<String>) service.getConferenceList();
+            HashMap<String, SipCall> callMap = (HashMap<String, SipCall>) service.getCallList();
+            HashMap<String, Conference> confMap = (HashMap<String, Conference>) service.getConferenceList();
             if (callMap.size() == 0 && confMap.size() == 0) {
 
                 finish();
@@ -269,22 +287,25 @@
     }
 
     @Override
-    public void onCallSelected(ArrayList<SipCall> calls) {
+    public void onCallSelected(Conference conf) {
 
-        mCurrentCallFragment.getBubbleView().restartDrawing();
+        if(mCurrentCallFragment.getBubbleView() == null){
+            return;
+        }
+        mCurrentCallFragment.getBubbleView().stopThread();
         mCurrentCallFragment = new CallFragment();
         Bundle b = new Bundle();
 
-        b.putParcelableArrayList("CallsInfo", calls);
+        b.putParcelable("conference", conf);
         mCurrentCallFragment.setArguments(b);
-        getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment).commit();
 
-        if(calls.size() == 1){
-            onCallResumed(calls.get(0));
-        }
-        
+        // if (calls.size() == 1) {
+        // onCallResumed(calls.get(0));
+        // }
+
         slidingPaneLayout.setCurFragment(mCurrentCallFragment);
         slidingPaneLayout.closePane();
+        fragIsChanging = true;
 
     }
 
@@ -387,11 +408,11 @@
     @Override
     public void onRecordCall(SipCall call) {
         try {
-            if (call.getCallStateInt() == state.CALL_STATE_CURRENT) {
-//                service.setRecordPath(Environment.getExternalStorageDirectory().getAbsolutePath());
+
+                // service.setRecordPath(Environment.getExternalStorageDirectory().getAbsolutePath());
                 Log.w(TAG, "Recording path" + service.getRecordPath());
                 service.setRecordingCall(call.getCallId());
-            }
+            
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot call service method", e);
         }
@@ -436,7 +457,18 @@
 
     @Override
     public void onCallsTerminated() {
-        Toast.makeText(this, "No Calls ", Toast.LENGTH_SHORT).show();
+
+    }
+
+    @Override
+    public void recordingChanged(Intent intent) {
+        mCallsFragment.update();
+    }
+
+    @Override
+    public void replaceCurrentCallDisplayed() {
+        mCurrentCallFragment.getBubbleView().stopThread();
+        getFragmentManager().beginTransaction().remove(mCurrentCallFragment).commit();
 
     }
 
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index 64abea2..2f1041d 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -31,7 +31,6 @@
  */
 package com.savoirfairelinux.sflphone.client;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -71,6 +70,7 @@
 import com.savoirfairelinux.sflphone.interfaces.CallInterface;
 import com.savoirfairelinux.sflphone.loaders.LoaderConstants;
 import com.savoirfairelinux.sflphone.model.CallContact;
+import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.receivers.CallReceiver;
 import com.savoirfairelinux.sflphone.service.CallManagerCallBack;
@@ -345,11 +345,11 @@
     public void launchCallActivity(SipCall infos) {
         Log.i(TAG, "Launch Call Activity");
         Bundle bundle = new Bundle();
-        ArrayList<SipCall> tmp = new ArrayList<SipCall>();
-        tmp.add(infos);
-        bundle.putParcelableArrayList("CallsInfo", tmp);
+        Conference tmp = new Conference("-1");
+        tmp.getParticipants().add(infos);
+        bundle.putParcelable("conference", tmp);
         Intent intent = new Intent().setClass(this, CallActivity.class);
-
+        intent.putExtra("resuming", false);
         intent.putExtras(bundle);
         startActivityForResult(intent, REQUEST_CODE_CALL);
     }
@@ -367,6 +367,7 @@
                 getFragmentManager().beginTransaction().replace(R.id.left_drawer, fMenu).commit();
                 mSectionsPagerAdapter = new SectionsPagerAdapter(SFLPhoneHomeActivity.this, getFragmentManager());
                 initialiseTabHost(null);
+                mViewPager.setOffscreenPageLimit(2);
                 mViewPager.setAdapter(mSectionsPagerAdapter);
                 mTabHost.setCurrentTab(1);
                 service.destroyNotification();
@@ -410,19 +411,13 @@
             break;
         case REQUEST_CODE_CALL:
             Log.w(TAG, "Result out of CallActivity");
-
+            getLoaderManager().restartLoader(LoaderConstants.HISTORY_LOADER, null, (HistoryFragment) mSectionsPagerAdapter.getItem(2));
             break;
         }
 
     }
 
     @Override
-    public void onCallSelected(SipCall c) {
-        launchCallActivity(c);
-
-    }
-
-    @Override
     public ISipService getService() {
         return service;
     }
@@ -507,6 +502,11 @@
     @Override
     public void onCallDialed(String to) {
 
+        if (fMenu.getSelectedAccount() == null) {
+            Toast.makeText(this, "No Account Selected", Toast.LENGTH_SHORT).show();
+            return;
+        }
+
         SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
         callBuilder.startCallCreation().setAccountID(fMenu.getSelectedAccount().getAccountID()).setCallType(SipCall.state.CALL_TYPE_OUTGOING);
         callBuilder.setContact(CallContact.ContactBuilder.buildUnknownContact(to));
@@ -586,19 +586,32 @@
     @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
-        
+
+    }
+
+    @Override
+    public void recordingChanged(Intent intent) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void resumeCallActivity() {
+        Intent intent = new Intent().setClass(this, CallActivity.class);
+        intent.putExtra("resuming", true);
+        startActivityForResult(intent, REQUEST_CODE_CALL);
     }
 
 }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
index b79d2a3..6917f02 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
@@ -31,9 +31,6 @@
 
 package com.savoirfairelinux.sflphone.fragments;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-
 import android.app.Activity;
 import android.app.Fragment;
 import android.graphics.Bitmap;
@@ -47,14 +44,13 @@
 import android.view.SurfaceHolder.Callback;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.TextView;
 
 import com.savoirfairelinux.sflphone.R;
 import com.savoirfairelinux.sflphone.model.Attractor;
 import com.savoirfairelinux.sflphone.model.Bubble;
 import com.savoirfairelinux.sflphone.model.BubbleModel;
 import com.savoirfairelinux.sflphone.model.BubblesView;
-import com.savoirfairelinux.sflphone.model.CallContact;
+import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.service.ISipService;
 import com.savoirfairelinux.sflphone.views.CounterTextView;
@@ -66,7 +62,7 @@
     static final float BUBBLE_SIZE = 75;
     static final float ATTRACTOR_SIZE = 40;
 
-    private ArrayList<SipCall> mCalls;
+    private Conference conf;
 
     private CounterTextView callStatusTxt;
     private BubblesView view;
@@ -74,20 +70,17 @@
 
     private Callbacks mCallbacks = sDummyCallbacks;
 
-    private HashMap<CallContact, Bubble> contacts = new HashMap<CallContact, Bubble>();
-
     private SipCall myself;
 
-    private Bitmap hangup_icon;
+    private Bitmap hangup_icon, separate_icon;
     private Bitmap call_icon;
 
     @Override
     public void onCreate(Bundle savedBundle) {
         super.onCreate(savedBundle);
-        model = new BubbleModel(getResources().getDisplayMetrics().density);
         Bundle b = getArguments();
-
-        mCalls = b.getParcelableArrayList("CallsInfo");
+        conf = b.getParcelable("conference");
+        model = new BubbleModel(getResources().getDisplayMetrics().density);
 
     }
 
@@ -135,6 +128,10 @@
         public ISipService getService() {
             return null;
         }
+
+        @Override
+        public void replaceCurrentCallDisplayed() {
+        }
     };
 
     /**
@@ -162,6 +159,8 @@
         public void onRecordCall(SipCall call);
 
         public void onSendMessage(SipCall call, String msg);
+
+        public void replaceCurrentCallDisplayed();
     }
 
     @Override
@@ -204,6 +203,7 @@
 
         hangup_icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_hangup);
         call_icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_call);
+        separate_icon = BitmapFactory.decodeResource(getResources(), R.drawable.icon_separate);
 
         // Do nothing here, the view is not initialized yet.
         return rootView;
@@ -216,58 +216,76 @@
 
         getBubbleFor(myself, model.width / 2, model.height / 2);
 
-        int angle_part = 360 / mCalls.size();
+        int angle_part = 360 / conf.getParticipants().size();
         double dX = 0;
         double dY = 0;
         int radiusCalls = model.width / 2 - 150;
-        for (int i = 0; i < mCalls.size(); ++i) {
+        for (int i = 0; i < conf.getParticipants().size(); ++i) {
+
+            if (conf.getParticipants().get(i) == null) {
+                Log.i(TAG, i + " null ");
+                continue;
+            }
             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));
+            getBubbleFor(conf.getParticipants().get(i), (int) (model.width / 2 + dX), (int) (model.height / 2 + dY));
         }
 
         model.clearAttractors();
-//        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 ! ");
-//                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;
-//            }
-//        }, hangup_icon));
+        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(b.associated_call);
+
+                bubbleRemoved(b);
+                return true;
+            }
+        }, hangup_icon));
+
+        // if (conf.hasMultipleParticipants()) {
+        // model.addAttractor(new Attractor(new PointF(model.width / 1.1f, model.height * .9f), ATTRACTOR_SIZE, new Attractor.Callback() {
+        // @Override
+        // public boolean onBubbleSucked(Bubble b) {
+        //
+        // try {
+        // mCallbacks.getService().detachParticipant(b.associated_call.getCallId());
+        // } catch (RemoteException e) {
+        // e.printStackTrace();
+        // }
+        //
+        // bubbleRemoved(b);
+        // return true;
+        // }
+        // }, separate_icon));
+        // }
+
+        // if(mCalls.size() == 1 && mCalls.get(0).isOnHold()){
+        // mCallbacks.onCallResumed(mCalls.get(0));
+        // }
 
     }
 
     private void initIncomingCallDisplay() {
         Log.i(TAG, "Start incoming display");
 
-        callStatusTxt.setText("Incomming call");
+        callStatusTxt.setText("Incoming call");
 
-        Bubble contact_bubble = getBubbleFor(mCalls.get(0), model.width / 2, model.height / 2);
-        contacts.put(mCalls.get(0).getContact(), contact_bubble);
+        getBubbleFor(conf.getParticipants().get(0), model.width / 2, model.height / 2);
 
         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(mCalls.get(0));
+                mCallbacks.onCallAccepted(conf.getParticipants().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(mCalls.get(0));
+                mCallbacks.onCallRejected(conf.getParticipants().get(0));
                 bubbleRemoved(b);
                 return true;
             }
@@ -279,17 +297,25 @@
 
         callStatusTxt.setText("Calling...");
 
-        // TODO off-thread image loading
         getBubbleFor(myself, model.width / 2, model.height / 2);
 
-        getBubbleFor(mCalls.get(0), (int) (model.width / 2), (int) (model.height / 3));
+        // TODO off-thread image loading
+        int angle_part = 360 / conf.getParticipants().size();
+        double dX = 0;
+        double dY = 0;
+        int radiusCalls = model.width / 2 - 150;
+        for (int i = 0; i < conf.getParticipants().size(); ++i) {
+            dX = Math.cos(Math.toRadians(angle_part * i - 90)) * radiusCalls;
+            dY = Math.sin(Math.toRadians(angle_part * i - 90)) * radiusCalls;
+            getBubbleFor(conf.getParticipants().get(i), (int) (model.width / 2 + dX), (int) (model.height / 2 + dY));
+        }
 
         model.clearAttractors();
         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(mCalls.get(0));
+                mCallbacks.onCallEnded(conf.getParticipants().get(0));
                 bubbleRemoved(b);
                 return true;
             }
@@ -308,7 +334,7 @@
      * @return Bubble corresponding to the contact.
      */
     private Bubble getBubbleFor(SipCall call, float x, float y) {
-        Bubble contact_bubble = contacts.get(call.getContact());
+        Bubble contact_bubble = model.getBubble(call);
         if (contact_bubble != null) {
             contact_bubble.attractor.set(x, y);
             return contact_bubble;
@@ -317,8 +343,6 @@
         contact_bubble = new Bubble(getActivity(), call, x, y, BUBBLE_SIZE);
 
         model.addBubble(contact_bubble);
-        contacts.put(call.getContact(), contact_bubble);
-
         return contact_bubble;
     }
 
@@ -329,28 +353,42 @@
         if (b.associated_call == null) {
             return;
         }
-        contacts.remove(b.associated_call.getContact());
     }
 
     public void changeCallState(String callID, String newState) {
 
-        Log.w(TAG, "Changing call state of " + callID);
-        if (mCalls.size() == 1) {
-            if (callID.equals(mCalls.get(0).getCallId()))
-                mCalls.get(0).setCallState(newState);
-
-            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);
-
+        if (newState.contentEquals("FAILURE")) {
+            try {
+                mCallbacks.getService().hangUp(callID);
+            } catch (RemoteException e) {
+                e.printStackTrace();
             }
         }
+        if (conf.getParticipants() == null) {
+            return;
+        }
+
+        for (int i = 0; i < conf.getParticipants().size(); ++i) {
+            // conf.getParticipants().get(i).printCallInfo();
+
+            if (callID.equals(conf.getParticipants().get(i).getCallId())) {
+                if (newState.contentEquals("HUNGUP")) {
+
+                    model.removeBubble(conf.getParticipants().get(i));
+                    conf.getParticipants().remove(i);
+                } else {
+                    conf.getParticipants().get(i).setCallState(newState);
+                }
+            }
+        }
+
+        if (conf.isOnGoing())
+            initNormalStateDisplay();
+
+        if (conf.getParticipants().size() == 0) {
+            mCallbacks.replaceCurrentCallDisplayed();
+        }
+
     }
 
     public boolean draggingBubble() {
@@ -362,19 +400,20 @@
         // Log.i(TAG, "Init fragment " + mCall.getCallId());
 
         // mCall.printCallInfo();
-        if (mCalls.size() == 1) {
+        if (conf.getParticipants().size() == 1) {
 
-            if (mCalls.get(0).isIncoming() && mCalls.get(0).isRinging()) {
+            if (conf.getParticipants().get(0).isIncoming() && conf.getParticipants().get(0).isRinging()) {
                 initIncomingCallDisplay();
             } else {
-                if (mCalls.get(0).isRinging()) {
+                if (conf.getParticipants().get(0).isRinging()) {
                     initOutGoingCallDisplay();
                 }
                 try {
-                    if (mCalls.get(0).isOutGoing() && mCallbacks.getService().getCall(mCalls.get(0).getCallId()) == null) {
-                        mCallbacks.getService().placeCall(mCalls.get(0));
+                    if (conf.getParticipants().get(0).isOutGoing()
+                            && mCallbacks.getService().getCall(conf.getParticipants().get(0).getCallId()) == null) {
+                        mCallbacks.getService().placeCall(conf.getParticipants().get(0));
                         initOutGoingCallDisplay();
-                    } else if (mCalls.get(0).isOutGoing() && mCalls.get(0).isRinging()) {
+                    } else if (conf.getParticipants().get(0).isOutGoing() && conf.getParticipants().get(0).isRinging()) {
                         initOutGoingCallDisplay();
                     }
                 } catch (RemoteException e) {
@@ -382,10 +421,10 @@
                 }
             }
 
-            if (mCalls.get(0).isOngoing()) {
+            if (conf.getParticipants().get(0).isOngoing()) {
                 initNormalStateDisplay();
             }
-        } else {
+        } else if (conf.getParticipants().size() > 1) {
             initNormalStateDisplay();
         }
 
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
index b8eba9f..9abaad3 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
@@ -90,7 +90,7 @@
         }
 
         @Override
-        public void onCallSelected(ArrayList<SipCall> call) {
+        public void onCallSelected(Conference conf) {
         }
 
         @Override
@@ -105,7 +105,7 @@
     public interface Callbacks {
         public ISipService getService();
 
-        public void onCallSelected(ArrayList<SipCall> call);
+        public void onCallSelected(Conference conf);
 
         public void onCallsTerminated();
 
@@ -149,33 +149,34 @@
             Log.w(TAG, "Updating");
             HashMap<String, SipCall> list = (HashMap<String, SipCall>) mCallbacks.getService().getCallList();
 
-            Toast.makeText(getActivity(), "Calls: "+list.size(), Toast.LENGTH_SHORT).show();
+            // 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);
-            }
+            HashMap<String, Conference> tmp = (HashMap<String, Conference>) mCallbacks.getService().getConferenceList();
+            conferences.addAll(tmp.values());
+//            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());
+                Log.w(TAG, "SimpleCall:" + call.getCallId());
                 Conference confOne = new Conference("-1");
                 confOne.getParticipants().add(call);
                 conferences.add(confOne);
             }
-            
-            if(conferences.isEmpty()){
+
+            if (conferences.isEmpty()) {
                 mCallbacks.onCallsTerminated();
             }
 
@@ -193,7 +194,7 @@
         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));
+            b.putParcelable("call_selected", mAdapter.getGroup(groupPosition));
             editNameDialog.setArguments(b);
             editNameDialog.setTargetFragment(this, REQUEST_TRANSFER);
             editNameDialog.show(fm, "dialog");
@@ -207,31 +208,27 @@
         FragmentManager fm = getFragmentManager();
         ConferenceDFragment confDialog = ConferenceDFragment.newInstance();
 
-        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();
-        }
+        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");
 
     }
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
-        SipCall transfer = null;
+        Conference transfer = null;
         if (requestCode == REQUEST_TRANSFER) {
             switch (resultCode) {
             case 0:
-                SipCall c = data.getParcelableExtra("target");
+                Conference c = data.getParcelableExtra("target");
                 transfer = data.getParcelableExtra("transfer");
                 try {
 
-                    mCallbacks.getService().attendedTransfer(transfer.getCallId(), c.getCallId());
+                    mCallbacks.getService().attendedTransfer(transfer.getParticipants().get(0).getCallId(), c.getParticipants().get(0).getCallId());
                     mAdapter.remove(transfer);
 
                     mAdapter.notifyDataSetChanged();
@@ -246,9 +243,10 @@
                 String to = data.getStringExtra("to_number");
                 transfer = data.getParcelableExtra("transfer");
                 try {
-                    Toast.makeText(getActivity(), "Transferring " + transfer.getContact().getmDisplayName() + " to " + to, Toast.LENGTH_SHORT).show();
-                    mCallbacks.getService().transfer(transfer.getCallId(), to);
-
+                    Toast.makeText(getActivity(), "Transferring " + transfer.getParticipants().get(0).getContact().getmDisplayName() + " to " + to,
+                            Toast.LENGTH_SHORT).show();
+                    mCallbacks.getService().transfer(transfer.getParticipants().get(0).getCallId(), to);
+                    mCallbacks.getService().hangUp(transfer.getParticipants().get(0).getCallId());
                 } catch (RemoteException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
@@ -261,12 +259,28 @@
         } else if (requestCode == REQUEST_CONF) {
             switch (resultCode) {
             case 0:
-                Conference call1 = data.getParcelableExtra("call1");
-                Conference call2 = data.getParcelableExtra("call2");
+                Conference call_to_add = data.getParcelableExtra("call_to_add");
+                Conference call_target = data.getParcelableExtra("call_target");
                 try {
 
-                    mCallbacks.getService().joinParticipant(call1.getParticipants().get(0).getCallId(), call2.getParticipants().get(0).getCallId());
+                    if (call_target.hasMultipleParticipants() && !call_to_add.hasMultipleParticipants()) {
 
+                        mCallbacks.getService().addParticipant(call_to_add.getParticipants().get(0), call_target.getId());
+
+                    } else if (call_target.hasMultipleParticipants() && call_to_add.hasMultipleParticipants()) {
+
+                        // We join two conferences
+                        mCallbacks.getService().joinConference(call_to_add.getId(), call_target.getId());
+
+                    } else if (!call_target.hasMultipleParticipants() && call_to_add.hasMultipleParticipants()) {
+
+                        mCallbacks.getService().addParticipant(call_target.getParticipants().get(0), call_to_add.getId());
+
+                    } else {
+                        // We join two single calls to create a conf
+                        mCallbacks.getService().joinParticipant(call_to_add.getParticipants().get(0).getCallId(),
+                                call_target.getParticipants().get(0).getCallId());
+                    }
                     // ArrayList<String> tmp = new ArrayList<String>();
                     // tmp.add(call1.getCallId());
                     // tmp.add(call2.getCallId());
@@ -302,7 +316,7 @@
             mContext = activity;
         }
 
-        public void remove(SipCall transfer) {
+        public void remove(Conference transfer) {
             calls.remove(transfer);
 
         }
@@ -343,12 +357,9 @@
 
         public View getChildView(final int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
 
-            if (convertView == null)
-                convertView = LayoutInflater.from(mContext).inflate(R.layout.expandable_child, null);
-            
+            convertView = LayoutInflater.from(mContext).inflate(R.layout.expandable_child, null);
+
             convertView.setAnimation(AnimationUtils.loadAnimation(getActivity(), R.animator.slide_down));
-            
-            
 
             ((ImageButton) convertView.findViewById(R.id.action_hangup)).setOnClickListener(new OnClickListener() {
 
@@ -367,6 +378,9 @@
                 }
             });
 
+            if(getGroup(groupPosition).isOnHold()){
+                ((Button) convertView.findViewById(R.id.action_hold)).setText("Unhold");
+            }
             ((Button) convertView.findViewById(R.id.action_hold)).setOnClickListener(new OnClickListener() {
 
                 @Override
@@ -439,7 +453,7 @@
             // as new group to expand
             if (groupPosition != lastExpandedGroupPosition) {
                 list.collapseGroup(lastExpandedGroupPosition);
-                
+
             }
 
             super.onGroupExpanded(groupPosition);
@@ -459,16 +473,17 @@
             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());
+                ((TextView) convertView.findViewById(R.id.call_status)).setText(call.getState());
             } else {
-                ((TextView) convertView.findViewById(R.id.call_title)).setText("Conference with "+call.getParticipants().size()+" participants");
+                ((TextView) convertView.findViewById(R.id.call_title)).setText("Conference with " + call.getParticipants().size() + " participants");
+                ((TextView) convertView.findViewById(R.id.call_status)).setText(call.getState());
             }
 
             ((RelativeLayout) convertView.findViewById(R.id.call_entry)).setOnClickListener(new OnClickListener() {
 
                 @Override
                 public void onClick(View v) {
-                    mCallbacks.onCallSelected(getGroup(groupPosition).getParticipants());
+                    mCallbacks.onCallSelected(getGroup(groupPosition));
 
                 }
             });
diff --git a/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java b/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java
index 3c5ae73..7fb6c9a 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java
@@ -67,8 +67,8 @@
 
                 Intent in = new Intent();
                 
-                in.putExtra("call1", call_selected);
-                in.putExtra("call2", mAdapter.getItem(pos));
+                in.putExtra("call_to_add", call_selected);
+                in.putExtra("call_target", mAdapter.getItem(pos));
                 getTargetFragment().onActivityResult(getTargetRequestCode(), 0, in);
                 dismiss();
             }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java b/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
index ded9c96..a5cc407 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
@@ -47,15 +47,13 @@
 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 HomeFragment extends Fragment {
     private static final String TAG = HomeFragment.class.getSimpleName();
 
-
-
     private Callbacks mCallbacks = sDummyCallbacks;
     Button access_calls;
 
@@ -63,15 +61,16 @@
      * A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
      */
     private static Callbacks sDummyCallbacks = new Callbacks() {
-        @Override
-        public void onCallSelected(SipCall c) {
-        }
 
         @Override
         public ISipService getService() {
             Log.i(TAG, "I'm a dummy");
             return null;
         }
+
+        @Override
+        public void resumeCallActivity() {            
+        }
     };
 
     /**
@@ -79,10 +78,11 @@
      * 
      */
     public interface Callbacks {
-        public void onCallSelected(SipCall c);
 
         public ISipService getService();
 
+        public void resumeCallActivity();
+
     }
 
     @Override
@@ -94,25 +94,24 @@
         }
 
         mCallbacks = (Callbacks) activity;
-        
-        
+
     }
-    
+
     @Override
-    public void onResume(){
+    public void onResume() {
         super.onResume();
         if (mCallbacks.getService() != null) {
             try {
                 HashMap<String, SipCall> calls = (HashMap<String, SipCall>) mCallbacks.getService().getCallList();
-                Log.i(TAG, "Call size "+calls.size());
-                access_calls.setText(calls.size()+" on going calls");
+                HashMap<String, Conference> confs = (HashMap<String, Conference>) mCallbacks.getService().getConferenceList();
+                Log.i(TAG, "Call size " + calls.size());
+                access_calls.setText(calls.size() + " on going calls and "+confs.size()+" conferences");
 
-                
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
         }
-        
+
     }
 
     @Override
@@ -124,8 +123,8 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-//        mAdapter = new CallElementAdapter(getActivity(), new ArrayList<SipCall>());
-        
+        // mAdapter = new CallElementAdapter(getActivity(), new ArrayList<SipCall>());
+
     }
 
     @Override
@@ -139,8 +138,6 @@
         // We have a menu item to show in action bar.
         setHasOptionsMenu(true);
 
-        
-
     }
 
     @Override
@@ -149,7 +146,6 @@
 
     }
 
-
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         Log.i(TAG, "onCreateView");
@@ -161,13 +157,16 @@
 
             @Override
             public void onClick(View v) {
-                HashMap<String, SipCall> calls;
+
                 try {
-                    calls = (HashMap<String, SipCall>) mCallbacks.getService().getCallList();
-                    if (calls.size() == 0) {
+                    HashMap<String, SipCall> calls = (HashMap<String, SipCall>) mCallbacks.getService().getCallList();
+                    HashMap<String, Conference> confs = (HashMap<String, Conference>) mCallbacks.getService().getConferenceList();
+                    if (calls.isEmpty() && confs.isEmpty()) {
                         Toast.makeText(getActivity(), "No calls", Toast.LENGTH_SHORT).show();
                     } else {
-                        mCallbacks.onCallSelected((SipCall) calls.values().toArray()[0]);
+                        
+                       mCallbacks.resumeCallActivity();
+                        
                     }
                 } catch (RemoteException e) {
                     Log.e(TAG, e.toString());
@@ -179,5 +178,4 @@
         return inflatedView;
     }
 
-
 }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/TransferDFragment.java b/src/com/savoirfairelinux/sflphone/fragments/TransferDFragment.java
index 7e5a080..c410211 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/TransferDFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/TransferDFragment.java
@@ -36,6 +36,7 @@
 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 TransferDFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Bundle> {
@@ -65,8 +66,8 @@
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_transfer, 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);
@@ -89,7 +90,7 @@
         mEditText.setAdapter(autoCompleteAdapter);
 
         final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView)
-                .setTitle("Transfer " + call_selected.getContact())
+                .setTitle("Transfer " + call_selected.getParticipants().get(0).getContact().getmDisplayName())
                 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int whichButton) {
                         
@@ -227,9 +228,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;
@@ -244,7 +245,7 @@
                 tv = (TextView) mInflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
             }
 
-            tv.setText(calls.get(position).getContact().getmDisplayName());
+            tv.setText(calls.get(position).getParticipants().get(0).getContact().getmDisplayName());
             return tv;
         }
 
@@ -254,7 +255,7 @@
         }
 
         @Override
-        public SipCall getItem(int pos) {
+        public Conference getItem(int pos) {
             return calls.get(pos);
         }
 
diff --git a/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java b/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java
index ce89fda..4c70821 100644
--- a/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java
+++ b/src/com/savoirfairelinux/sflphone/interfaces/CallInterface.java
@@ -16,4 +16,6 @@
 
     public void confChanged(Intent intent);
     
+    public void recordingChanged(Intent intent);
+    
 }
diff --git a/src/com/savoirfairelinux/sflphone/loaders/AccountsLoader.java b/src/com/savoirfairelinux/sflphone/loaders/AccountsLoader.java
index 7194096..be14488 100644
--- a/src/com/savoirfairelinux/sflphone/loaders/AccountsLoader.java
+++ b/src/com/savoirfairelinux/sflphone/loaders/AccountsLoader.java
@@ -55,6 +55,8 @@
             }
         } catch (RemoteException e) {
             Log.e(TAG, e.toString());
+        } catch (NullPointerException e1){
+            Log.e(TAG, e1.toString());
         }
 
         return result;
diff --git a/src/com/savoirfairelinux/sflphone/model/Bubble.java b/src/com/savoirfairelinux/sflphone/model/Bubble.java
index 420fb6a..7d9bf2c 100644
--- a/src/com/savoirfairelinux/sflphone/model/Bubble.java
+++ b/src/com/savoirfairelinux/sflphone/model/Bubble.java
@@ -210,6 +210,19 @@
         canvas.drawBitmap(circle, 0, 0, circlePaint);
 
     }
+    
+
+    /**
+     * Compare bubbles based on call ID
+     */
+    @Override
+    public boolean equals(Object c) {
+        if (c instanceof Bubble && ((Bubble) c).associated_call.getCallId().contentEquals(associated_call.getCallId())) {
+            return true;
+        }
+        return false;
+
+    }
 
     /**
      * When bubble is expanded we need to check on wich action button the user tap
diff --git a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
index 8650230..c1a87cb 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
@@ -4,6 +4,7 @@
 import java.util.List;
 
 import android.graphics.PointF;
+import android.util.Log;
 
 public class BubbleModel
 {
@@ -182,5 +183,25 @@
 		}
 	}
 
+    public Bubble getBubble(SipCall call) {
+        for(Bubble b : bubbles){
+            if(call == null){
+                Log.e(TAG, "call null");
+            } 
+            if(b.associated_call.getCallId() == null){
+                Log.e(TAG, "id null");
+            }
+            if(b.associated_call.getCallId().contentEquals(call.getCallId()))
+                return b;
+        }
+        return null;
+    }
+
+    public void removeBubble(SipCall sipCall) {
+        
+        bubbles.remove(getBubble(sipCall));
+        
+    }
+
 
 }
diff --git a/src/com/savoirfairelinux/sflphone/model/BubblesView.java b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
index f365ec2..0e3864a 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubblesView.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
@@ -34,13 +34,11 @@
 

 import java.util.List;

 

-import android.app.FragmentManager;

 import android.content.Context;

 import android.graphics.Canvas;

 import android.graphics.Color;

 import android.graphics.Paint;

 import android.graphics.Paint.Align;

-import android.os.Bundle;

 import android.os.Handler;

 import android.os.Message;

 import android.util.AttributeSet;

@@ -56,7 +54,6 @@
 

 import com.savoirfairelinux.sflphone.client.CallActivity;

 import com.savoirfairelinux.sflphone.fragments.CallFragment;

-import com.savoirfairelinux.sflphone.fragments.TransferDFragment;

 

 public class BubblesView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener {

     private static final String TAG = BubblesView.class.getSimpleName();

@@ -279,8 +276,18 @@
                         canvas.drawText(first_plan.associated_call.getContact().getmDisplayName(), first_plan.getPosX(), first_plan.getPosY() - 50

                                 * density, getNamePaint(first_plan));

                         canvas.drawText("Transfer", first_plan.getPosX(), first_plan.getPosY() + 70 * density, getNamePaint(first_plan));

-                        canvas.drawText("Hold", first_plan.getPosX() - 70 * density, first_plan.getPosY(), getNamePaint(first_plan));

-                        canvas.drawText("Record", first_plan.getPosX() + 70 * density, first_plan.getPosY(), getNamePaint(first_plan));

+                        if (first_plan.associated_call.isOnHold()) {

+                            canvas.drawText("Unhold", first_plan.getPosX() - 70 * density, first_plan.getPosY(), getNamePaint(first_plan));

+                        } else {

+                            canvas.drawText("Hold", first_plan.getPosX() - 70 * density, first_plan.getPosY(), getNamePaint(first_plan));

+                        }

+                        if (first_plan.associated_call.isRecording()) {

+                            canvas.drawText("Stop\nRecording", first_plan.getPosX() + 70 * density, first_plan.getPosY(), getNamePaint(first_plan));

+                        } else {

+                            canvas.drawText("Record", first_plan.getPosX() + 70 * density, first_plan.getPosY(), getNamePaint(first_plan));

+

+                        }

+

                     }

 

                 } catch (IndexOutOfBoundsException e) {

@@ -344,6 +351,27 @@
         return null;

     }

 

+    public void restartDrawing() {

+        if (thread != null && thread.suspendFlag) {

+            Log.i(TAG, "Relaunch drawing thread");

+            thread.setPaused(false);

+        }

+    }

+

+    public void setFragment(CallFragment callFragment) {

+        callback = callFragment;

+

+    }

+

+    public void stopThread() {

+        if (thread != null && thread.suspendFlag) {

+            Log.i(TAG, "Stop drawing thread");

+            thread.setRunning(false);

+            thread.setPaused(false);

+        }

+

+    }

+

     class MyOnGestureListener implements OnGestureListener {

         @Override

         public boolean onDown(MotionEvent event) {

@@ -360,8 +388,12 @@
                         expand.retract();

                         break;

                     case 1:

-                        Log.d("Main", "onCallSuspended");

-                        ((CallActivity) callback.getActivity()).onCallSuspended(expand.associated_call);

+                        if (expand.associated_call.isOnHold()) {

+                            ((CallActivity) callback.getActivity()).onCallResumed(expand.associated_call);

+                        } else {

+                            ((CallActivity) callback.getActivity()).onCallSuspended(expand.associated_call);

+                        }

+

                         break;

                     case 2:

                         Log.d("Main", "onRecordCall");

@@ -450,17 +482,4 @@
             return true;

         }

     }

-

-    public void restartDrawing() {

-        if (thread != null && thread.suspendFlag) {

-            Log.i(TAG, "Relaunch drawing thread");

-            thread.setPaused(false);

-        }

-    }

-

-    public void setFragment(CallFragment callFragment) {

-        callback = callFragment;

-

-    }

-

 }

diff --git a/src/com/savoirfairelinux/sflphone/model/CallContact.java b/src/com/savoirfairelinux/sflphone/model/CallContact.java
index 75c8b6b..4e3ae1a 100644
--- a/src/com/savoirfairelinux/sflphone/model/CallContact.java
+++ b/src/com/savoirfairelinux/sflphone/model/CallContact.java
@@ -37,7 +37,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.ContactsContract.Profile;
-import android.util.Log;
 
 public class CallContact implements Parcelable {
 
@@ -49,7 +48,7 @@
 
     private CallContact(long cID, String displayName, long photoID, ArrayList<Phone> p, ArrayList<Phone> sip, String mail) {
         id = cID;
-        mDisplayName = displayName;
+        mDisplayName = displayName.substring(0, displayName.length() > 10 ? 10 : displayName.length());;
         phones = p;
         sip_phones = sip;
         mEmail = mail;
@@ -68,10 +67,6 @@
         return mDisplayName;
     }
 
-    public void setmDisplayName(String mDisplayName) {
-        this.mDisplayName = mDisplayName;
-    }
-
     public long getPhoto_id() {
         return photo_id;
     }
@@ -131,6 +126,7 @@
 
         public ContactBuilder startNewContact(long id, String displayName, long photo_id) {
             contactID = id;
+            
             contactName = displayName;
             contactPhoto = photo_id;
             phones = new ArrayList<Phone>();
@@ -169,7 +165,6 @@
             CallContact result = null;
             if (mProfileCursor.getCount() > 0) {
                 mProfileCursor.moveToFirst();
-                Log.i("CallContact", "THERE IS AN ENTRY");
                 result = new CallContact(mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile._ID)), displayName,
                         mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile.PHOTO_ID)), new ArrayList<Phone>(),
                         new ArrayList<CallContact.Phone>(), "");
diff --git a/src/com/savoirfairelinux/sflphone/model/Conference.aidl b/src/com/savoirfairelinux/sflphone/model/Conference.aidl
new file mode 100644
index 0000000..a959fe3
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/model/Conference.aidl
@@ -0,0 +1,4 @@
+package com.savoirfairelinux.sflphone.model;
+
+
+parcelable Conference;
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/model/Conference.java b/src/com/savoirfairelinux/sflphone/model/Conference.java
index 26ddf63..02d06c7 100644
--- a/src/com/savoirfairelinux/sflphone/model/Conference.java
+++ b/src/com/savoirfairelinux/sflphone/model/Conference.java
@@ -9,8 +9,9 @@
 public class Conference implements Parcelable {
 
     private String id;
-    private String state;
+    private String state = "";
     private ArrayList<SipCall> participants;
+    private boolean recording;
 
     public interface state {
         int ACTIVE_ATTACHED = 0;
@@ -68,6 +69,9 @@
     }
 
     public String getState() {
+        if(participants.size() == 1){
+            return participants.get(0).getCallStateString();
+        }
         return state;
     }
 
@@ -95,4 +99,32 @@
         return null;
     }
 
+    public boolean hasMultipleParticipants() {
+        return participants.size() > 1;
+    }
+
+    public boolean isOnHold() {
+        if(participants.size() == 1 && participants.get(0).isOnHold())
+            return true;
+        return state.contentEquals("HOLD");
+    }
+
+    public void setRecording(boolean b) {
+        recording = b;
+    }
+
+    public boolean isRecording() {
+        return recording;
+    }
+
+    public boolean isOnGoing() {
+        if(participants.size() == 1 && participants.get(0).isOngoing())
+            return true;
+        
+        if (participants.size() > 1)
+            return true;
+        
+        return false;
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.java b/src/com/savoirfairelinux/sflphone/model/SipCall.java
index 2e7018d..3f38733 100644
--- a/src/com/savoirfairelinux/sflphone/model/SipCall.java
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.java
@@ -45,7 +45,8 @@
     private String mCallID = "";
     private String mAccountID = "";
     private CallContact contact = null;
-    
+    private boolean isRecording = false;
+
     public static final String USER_ID = "user_id";
 
     private int mCallType = state.CALL_TYPE_UNDETERMINED;
@@ -59,24 +60,15 @@
     private SipCall(Parcel in) {
         ArrayList<String> list = in.createStringArrayList();
 
-        // Don't mess with this order!!!
         mCallID = list.get(0);
         mAccountID = list.get(1);
-        // mDisplayName = list.get(2);
-        // mPhone = list.get(3);
-        // mEmail = list.get(4);
-        // mRemoteContact = list.get(5);
-
         contact = in.readParcelable(CallContact.class.getClassLoader());
-
+        isRecording = in.readByte() == 1;
         mCallType = in.readInt();
         mCallState = in.readInt();
         mMediaState = in.readInt();
     }
 
-    // public SipCall(Intent call) {
-
-    // }
 
     public SipCall(String id, String account, int call_type, int call_state, int media_state, CallContact c) {
         mCallID = id;
@@ -87,8 +79,6 @@
         contact = c;
     }
 
-    // public SipCall() {
-    // }
 
     public interface state {
         public static final int CALL_TYPE_UNDETERMINED = 0;
@@ -127,6 +117,7 @@
 
         out.writeStringList(list);
         out.writeParcelable(contact, 0);
+        out.writeByte((byte) (isRecording ? 1 : 0));
         out.writeInt(mCallType);
         out.writeInt(mCallState);
         out.writeInt(mMediaState);
@@ -269,6 +260,14 @@
         return mMediaState;
     }
 
+    public boolean isRecording() {
+        return isRecording;
+    }
+
+    public void setRecording(boolean isRecording) {
+        this.isRecording = isRecording;
+    }
+
     public static class SipCallBuilder {
 
         private String bCallID = "";
@@ -332,7 +331,7 @@
 
         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, ""));
+                    CallContact.ContactBuilder.buildUserContact(cr, displayName));
 
         }
 
@@ -401,6 +400,7 @@
 
     }
 
+
     public boolean isOngoing() {
         if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE || mCallState == state.CALL_STATE_FAILURE
                 || mCallState == state.CALL_STATE_BUSY || mCallState == state.CALL_STATE_HUNGUP)
@@ -409,4 +409,8 @@
         return true;
     }
 
+    public boolean isOnHold() {
+        return mCallState == state.CALL_STATE_HOLD;
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java b/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java
index 4642b54..f025212 100644
--- a/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java
+++ b/src/com/savoirfairelinux/sflphone/receivers/CallReceiver.java
@@ -38,37 +38,36 @@
 import com.savoirfairelinux.sflphone.interfaces.CallInterface;
 import com.savoirfairelinux.sflphone.service.CallManagerCallBack;
 
-public class CallReceiver extends BroadcastReceiver{
-    
+public class CallReceiver extends BroadcastReceiver {
+
     static final String TAG = CallReceiver.class.getSimpleName();
 
     CallInterface callback;
-    
-    public CallReceiver(CallInterface client){
+
+    public CallReceiver(CallInterface client) {
         callback = client;
     }
-    
-	@Override
-	public void onReceive(Context context, Intent intent)
-	{
-	    if( intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)){
-	        callback.incomingCall(intent);
-	    } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)){
-	        callback.incomingText(intent);
-	    } else if(intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)){
-	        callback.callStateChanged(intent);
-	    } 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());
-	    }
 
-	}
-	
-	
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
+            callback.incomingCall(intent);
+        } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)) {
+            callback.incomingText(intent);
+        } else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {
+            callback.callStateChanged(intent);
+        } 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 if (intent.getAction().contentEquals(CallManagerCallBack.RECORD_STATE_CHANGED)) {
+            callback.recordingChanged(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 69cbed9..4fab834 100644
--- a/src/com/savoirfairelinux/sflphone/receivers/IncomingReceiver.java
+++ b/src/com/savoirfairelinux/sflphone/receivers/IncomingReceiver.java
@@ -10,7 +10,6 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.util.Log;
-import android.widget.Toast;
 
 import com.savoirfairelinux.sflphone.model.CallContact;
 import com.savoirfairelinux.sflphone.model.Conference;
@@ -90,26 +89,28 @@
                 } else {
                     // Check if call is in a conference
                     Iterator<Entry<String, Conference>> it = callback.getCurrent_confs().entrySet().iterator();
-                    while(it.hasNext()){
+                    while (it.hasNext()) {
                         Conference tmp = it.next().getValue();
-                        for(SipCall c : tmp.getParticipants()){
-                            if(c.getCallId().contentEquals(b.getString("CallID")));
-                                c.setCallState(SipCall.state.CALL_STATE_HOLD);
+                        for (SipCall c : tmp.getParticipants()) {
+                            if (c.getCallId().contentEquals(b.getString("CallID")))
+                                ;
+                            c.setCallState(SipCall.state.CALL_STATE_HOLD);
                         }
                     }
                 }
             } else if (newState.equals("UNHOLD")) {
-                
+
                 if (callback.getCurrent_calls().get(b.getString("CallID")) != null) {
                     callback.getCurrent_calls().get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_CURRENT);
                 } else {
                     // Check if call is in a conference
                     Iterator<Entry<String, Conference>> it = callback.getCurrent_confs().entrySet().iterator();
-                    while(it.hasNext()){
+                    while (it.hasNext()) {
                         Conference tmp = it.next().getValue();
-                        for(SipCall c : tmp.getParticipants()){
-                            if(c.getCallId().contentEquals(b.getString("CallID")));
-                                c.setCallState(SipCall.state.CALL_STATE_CURRENT);
+                        for (SipCall c : tmp.getParticipants()) {
+                            if (c.getCallId().contentEquals(b.getString("CallID")))
+                                ;
+                            c.setCallState(SipCall.state.CALL_STATE_CURRENT);
                         }
                     }
                 }
@@ -127,11 +128,12 @@
 
             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"));
+                ArrayList<String> all_participants = (ArrayList<String>) mBinder.getParticipantList(intent.getStringExtra("confID"));
                 for (String participant : all_participants) {
                     created.getParticipants().add(callback.getCurrent_calls().get(participant));
+                    callback.getCurrent_calls().remove(participant);
                 }
                 Intent toSend = new Intent(CallManagerCallBack.CONF_CREATED);
                 toSend.putExtra("newconf", created);
@@ -150,13 +152,58 @@
                 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();
+            callback.sendBroadcast(intent);
 
         } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CHANGED)) {
 
+            ArrayList<String> all_participants;
+            try {
+                all_participants = (ArrayList<String>) mBinder.getParticipantList(intent.getStringExtra("confID"));
+                for (String participant : all_participants) {
+                    if (callback.getCurrent_confs().get(intent.getStringExtra("confID")).getParticipants().size() < all_participants.size()
+                            && callback.getCurrent_calls().get(participant) != null) { // We need to add the new participant to the conf
+                        callback.getCurrent_confs().get(intent.getStringExtra("confID")).getParticipants()
+                                .add(callback.getCurrent_calls().get(participant));
+                        callback.getCurrent_calls().remove(participant);
+                        callback.getCurrent_confs().get(intent.getStringExtra("confID")).setState(intent.getStringExtra("State"));
+                        callback.sendBroadcast(intent);
+                        return;
+                    }
+                }
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+
             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();
+            callback.sendBroadcast(intent);
+
+        } else if (intent.getAction().contentEquals(CallManagerCallBack.RECORD_STATE_CHANGED)) {
+
+            Log.i(TAG, "Received" + intent.getAction());
+
+            try {
+                if (callback.getCurrent_confs().get(intent.getStringExtra("id")) != null) {
+                    callback.getCurrent_confs().get(intent.getStringExtra("id")).setRecording(mBinder.isRecording(intent.getStringExtra("id")));
+                } else if (callback.getCurrent_calls().get(intent.getStringExtra("id")) != null){
+                    callback.getCurrent_calls().get(intent.getStringExtra("id")).setRecording(mBinder.isRecording(intent.getStringExtra("id")));
+                } else {
+                    // A call in a conference has been put on hold
+                    Iterator<Conference> it = callback.getCurrent_confs().values().iterator();
+                    while(it.hasNext()){
+                        Conference c = it.next();
+                        if(c.getCall(intent.getStringExtra("id")) != null)
+                            c.getCall(intent.getStringExtra("id")).setRecording(mBinder.isRecording(intent.getStringExtra("id")));
+                    }
+                }
+                // Re sending the same intent to the app
+                callback.sendBroadcast(intent);
+                ;
+            } catch (RemoteException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
         }
 
     }
diff --git a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
index f8a352f..965d2b8 100644
--- a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
+++ b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
@@ -18,6 +18,7 @@
     static public final String CONF_CREATED = "conf_created";
     static public final String CONF_REMOVED = "conf_removed";
     static public final String CONF_CHANGED = "conf_changed";
+    static public final String RECORD_STATE_CHANGED = "record_state";
 
 
     public CallManagerCallBack(Context context) {
@@ -33,13 +34,24 @@
     @Override
     public void on_call_state_changed(String callID, String state) {
         Log.d(TAG, "on_call_state_changed(" + callID + ", " + state + ")");
-        sendCallStateChangedMessage(callID, state);
+        Bundle bundle = new Bundle();
+        bundle.putString("CallID", callID);
+        bundle.putString("State", state);
+        Intent intent = new Intent(CALL_STATE_CHANGED);
+        intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
+        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
 
     @Override
     public void on_incoming_call(String accountID, String callID, String from) {
         Log.d(TAG, "on_incoming_call(" + accountID + ", " + callID + ", " + from + ")");
-        sendIncomingCallMessage(accountID, callID, from);
+        Bundle bundle = new Bundle();
+        bundle.putString("AccountID", accountID);
+        bundle.putString("CallID", callID);
+        bundle.putString("From", from);
+        Intent intent = new Intent(INCOMING_CALL);
+        intent.putExtra("com.savoirfairelinux.sflphone.service.newcall", bundle);
+        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
     
     @Override
@@ -58,12 +70,18 @@
     @Override
     public void on_incoming_message(String ID, String from, String msg){
         Log.w(TAG,"on_incoming_message:"+msg);
-        sendIncomingTextMessage(ID, from, msg);
+        Bundle bundle = new Bundle();
+
+        bundle.putString("CallID", ID);
+        bundle.putString("From", from);
+        bundle.putString("Msg", msg);
+        Intent intent = new Intent(INCOMING_TEXT); 
+        intent.putExtra("com.savoirfairelinux.sflphone.service.newtext", bundle);
+        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
     
     @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);
@@ -71,41 +89,18 @@
     
     @Override
     public void on_conference_state_changed(String confID, String state){
-        Log.w(TAG,"CONFERENCE STATE CHANGED:"+confID);
         Intent intent = new Intent(CONF_CHANGED);
         intent.putExtra("confID", confID);
         intent.putExtra("State", state);
         LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
-
-    private void sendCallStateChangedMessage(String callID, String state) {
-        Bundle bundle = new Bundle();
-        bundle.putString("CallID", callID);
-        bundle.putString("State", state);
-        Intent intent = new Intent(CALL_STATE_CHANGED);
-        intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
-        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
-    }
-
-    private void sendIncomingCallMessage(String accountID, String callID, String from) {
-        Bundle bundle = new Bundle();
-        bundle.putString("AccountID", accountID);
-        bundle.putString("CallID", callID);
-        bundle.putString("From", from);
-        Intent intent = new Intent(INCOMING_CALL);
-        intent.putExtra("com.savoirfairelinux.sflphone.service.newcall", bundle);
-        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
-    }
     
-    private void sendIncomingTextMessage(String id, String from, String msg) {
-        Bundle bundle = new Bundle();
-
-        bundle.putString("CallID", id);
-        bundle.putString("From", from);
-        bundle.putString("Msg", msg);
-        Intent intent = new Intent(INCOMING_TEXT); 
-        intent.putExtra("com.savoirfairelinux.sflphone.service.newtext", bundle);
+    @Override
+    public void on_record_playback_filepath(String id, String filename){
+        Intent intent = new Intent(RECORD_STATE_CHANGED);
+        intent.putExtra("id", id);
+        intent.putExtra("file", filename);
         LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
-        
     }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
index 3a6cb3c..3a79892 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
@@ -1,6 +1,7 @@
 package com.savoirfairelinux.sflphone.service;
 
 import com.savoirfairelinux.sflphone.model.SipCall;
+import com.savoirfairelinux.sflphone.model.Conference;
 
 interface ISipService {
     /*void placeCall(String accountID, in String callID, in String to);*/
@@ -34,6 +35,7 @@
     void setRecordingCall(in String id);
     boolean startRecordedFilePlayback(in String filepath);
 	void stopRecordedFilePlayback(in String filepath);
+	boolean isRecording(in String id);
     
     /* IM */
     void sendTextMessage(in String callID, in String message, in String from);
@@ -53,12 +55,14 @@
     void hangUpConference(in String confID);
     void holdConference(in String confID);
     void unholdConference(in String confID);
-    List getConferenceList();
+    Map getConferenceList();
     Map getCallList();
     List getParticipantList(in String confID);
     String getConferenceId(in String callID);
     String getConferenceDetails(in String callID);
     
+    Conference getCurrentCall();
+    
     
     /*   */
     
diff --git a/src/com/savoirfairelinux/sflphone/service/SipService.java b/src/com/savoirfairelinux/sflphone/service/SipService.java
index 94afa54..3ab830e 100644
--- a/src/com/savoirfairelinux/sflphone/service/SipService.java
+++ b/src/com/savoirfairelinux/sflphone/service/SipService.java
@@ -114,6 +114,7 @@
         callFilter.addAction(CallManagerCallBack.CONF_CREATED);
         callFilter.addAction(CallManagerCallBack.CONF_REMOVED);
         callFilter.addAction(CallManagerCallBack.CONF_CHANGED);
+        callFilter.addAction(CallManagerCallBack.RECORD_STATE_CHANGED);
         receiver = new IncomingReceiver(this, mBinder);
         LocalBroadcastManager.getInstance(this).registerReceiver(receiver, callFilter);
 
@@ -771,28 +772,29 @@
         }
 
         @Override
-        public List getConferenceList() throws RemoteException {
-            class ConfList extends SipRunnableWithReturn {
-                @Override
-                protected StringVect doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getConferenceList() thread running...");
-                    return callManagerJNI.getConferenceList();
-                }
-            }
-            ;
-            ConfList runInstance = new ConfList();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-                // Log.w(TAG, "Waiting for getConferenceList");
-            }
-            StringVect swigvect = (StringVect) runInstance.getVal();
-
-            ArrayList<String> nativelist = new ArrayList<String>();
-
-            for (int i = 0; i < swigvect.size(); i++)
-                nativelist.add(swigvect.get(i));
-
-            return nativelist;
+        public HashMap<String, Conference> getConferenceList() throws RemoteException {
+//            class ConfList extends SipRunnableWithReturn {
+//                @Override
+//                protected StringVect doRun() throws SameThreadException {
+//                    Log.i(TAG, "SipService.getConferenceList() thread running...");
+//                    return callManagerJNI.getConferenceList();
+//                }
+//            }
+//            ;
+//            ConfList runInstance = new ConfList();
+//            getExecutor().execute(runInstance);
+//            while (!runInstance.isDone()) {
+//                // Log.w(TAG, "Waiting for getConferenceList");
+//            }
+//            StringVect swigvect = (StringVect) runInstance.getVal();
+//
+//            ArrayList<String> nativelist = new ArrayList<String>();
+//
+//            for (int i = 0; i < swigvect.size(); i++)
+//                nativelist.add(swigvect.get(i));
+//
+//            return nativelist;
+            return current_confs;
         }
 
         @Override
@@ -880,6 +882,26 @@
         }
         
         @Override
+        public boolean isRecording(final String id) throws RemoteException {
+            class IsRecording extends SipRunnableWithReturn {
+
+                @Override
+                protected Boolean doRun() throws SameThreadException {
+                    Log.i(TAG, "SipService.isRecording() thread running...");
+                    return callManagerJNI.getIsRecording(id);
+                }
+            }
+
+            IsRecording runInstance = new IsRecording();
+            getExecutor().execute(runInstance);
+            while (!runInstance.isDone()) {
+            }
+
+            return (Boolean) runInstance.getVal();
+            
+        }
+        
+        @Override
         public boolean startRecordedFilePlayback(final String filepath) throws RemoteException {
             getExecutor().execute(new SipRunnable() {
                 @Override
@@ -1027,6 +1049,24 @@
             nm.cancel(NOTIFICATION_ID);
         }
 
+        @Override
+        public Conference getCurrentCall() throws RemoteException {
+            for(SipCall i : current_calls.values()){
+                if(i.isOngoing()){
+                    Conference tmp = new Conference("-1");
+                    tmp.getParticipants().add(i);
+                    return tmp;
+                }
+            }
+            
+            if(!current_confs.isEmpty()){
+                return (Conference) current_confs.values().toArray()[0];
+            }
+            return null;
+        }
+
+        
+
 
 
     };