* #25115 First Implementation of new CallActivity with dual-pane
* #25116 SipCall redesigned, holding list of contacts (android or unknown)
diff --git a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
index 9f22110..9b9bad3 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
@@ -20,7 +20,6 @@
 
     ArrayList<Account> accounts;
     Context mContext;
-    // AccountManager accManager;
     ISipService service;
     int selectedAccount = 0;
 
@@ -29,7 +28,6 @@
         accounts = newList;
         mContext = cont;
         service = s;
-        // accManager = new AccountManager(mContext);
     }
 
     @Override
@@ -84,144 +82,7 @@
         public RadioButton select;
     }
 
-    // /**
-    // * Asynchronous account details retriever
-    // */
-    // public class AccountManager {
-    //
-    // // private static final String TAG = ImageManager.class.getSimpleName();
-    //
-    // private HashMap<String, HashMap<String, String>> accountMap = new HashMap<String, HashMap<String, String>>();
-    // private AccountQueue accountQueue = new AccountQueue();
-    // private Thread accountLoaderThread = new Thread(new AccountQueueManager());
-    //
-    //
-    // public AccountManager(Context context) {
-    // accountLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);
-    //
-    // }
-    //
-    // public void displayAccountDetails(String id, AccountView account) {
-    //
-    // if (accountMap.containsKey(id)) {
-    //
-    // HashMap<String, String> details = accountMap.get(id);
-    // account.alias.setText(details.get(AccountDetailBasic.CONFIG_ACCOUNT_ALIAS));
-    // account.host.setText(details.get(AccountDetailBasic.CONFIG_ACCOUNT_HOSTNAME));
-    //
-    // } else {
-    // queueAccount(id, account);
-    // }
-    // }
-    //
-    // private void queueAccount(String id, AccountView row) {
-    // // This ImageView might have been used for other images, so we clear
-    // // the queue of old tasks before starting.
-    // // accountQueue.Clean(row);
-    // AccountRef p = new AccountRef(id, row);
-    //
-    // synchronized (accountQueue.accountRefsStack) {
-    // accountQueue.accountRefsStack.push(p);
-    // accountQueue.accountRefsStack.notifyAll();
-    // }
-    //
-    // // Start thread if it's not started yet
-    // if (accountLoaderThread.getState() == Thread.State.NEW) {
-    // accountLoaderThread.start();
-    // }
-    // }
-    //
-    // /** Classes **/
-    //
-    // private class AccountRef {
-    // public String accountID;
-    // public AccountView row;
-    //
-    // public AccountRef(String u, AccountView i) {
-    // accountID = u;
-    // row = i;
-    // }
-    // }
-    //
-    // private class AccountQueue {
-    // private Stack<AccountRef> accountRefsStack = new Stack<AccountRef>();
-    //
-    // // removes all instances of this account
-    // // public void Clean(AccountView view) {
-    // //
-    // // for (int i = 0; i < accountRefsStack.size();) {
-    // // if (accountRefsStack.get(i).row == view)
-    // // accountRefsStack.remove(i);
-    // // else
-    // // ++i;
-    // // }
-    // // }
-    // }
-    //
-    // private class AccountQueueManager implements Runnable {
-    // @Override
-    // public void run() {
-    // try {
-    // while (true) {
-    // // Thread waits until there are accountsID in the queue to be retrieved
-    // if (accountQueue.accountRefsStack.size() == 0) {
-    // synchronized (accountQueue.accountRefsStack) {
-    // accountQueue.accountRefsStack.wait();
-    // }
-    // }
-    //
-    // // When we have accounts to load
-    // if (accountQueue.accountRefsStack.size() != 0) {
-    // AccountRef accountToLoad;
-    //
-    // synchronized (accountQueue.accountRefsStack) {
-    // accountToLoad = accountQueue.accountRefsStack.pop();
-    // }
-    //
-    // HashMap<String, String> details = (HashMap<String, String>) service.getAccountDetails(accountToLoad.accountID);
-    //
-    // accountMap.put(accountToLoad.accountID, details);
-    // AccountDisplayer accDisplayer = new AccountDisplayer(details, accountToLoad.row);
-    // Activity a = (Activity) mContext;
-    //
-    // a.runOnUiThread(accDisplayer);
-    //
-    // }
-    //
-    // if (Thread.interrupted())
-    // break;
-    // }
-    // } catch (InterruptedException e) {
-    // Log.e(TAG, e.toString());
-    // } catch (RemoteException e) {
-    // Log.e(TAG, e.toString());
-    // }
-    // }
-    // }
-    //
-    // // Used to display details in the UI thread
-    // private class AccountDisplayer implements Runnable {
-    // HashMap<String, String> displayDetails;
-    // AccountView displayRow;
-    //
-    // public AccountDisplayer(HashMap<String, String> details, AccountView row) {
-    // displayRow = row;
-    // displayDetails = details;
-    // }
-    //
-    // public void run() {
-    // displayRow.alias.setText(displayDetails.get(AccountDetailBasic.CONFIG_ACCOUNT_ALIAS));
-    // displayRow.host.setText(displayDetails.get(AccountDetailBasic.CONFIG_ACCOUNT_HOSTNAME));
-    // }
-    // }
-    //
-    // public void removeFromCache(Uri uri) {
-    // if (accountMap.containsKey(uri)) {
-    // accountMap.remove(uri);
-    // }
-    // }
-    // }
-    //
+   
     public void setSelectedAccount(int pos) {
         selectedAccount = pos;
     }
diff --git a/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java
index 05d9226..3214a32 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java
@@ -66,8 +66,8 @@
         // to the view objects
 
         SipCall call = (SipCall) mCallList.values().toArray()[position];
-        entryView.displayName.setText(call.getDisplayName());
-        entryView.phones.setText(call.getPhone());
+        entryView.displayName.setText(call.getContacts().get(0).getmDisplayName());
+        entryView.phones.setText(call.getContacts().get(0).getPhones().get(0).getNumber());
         entryView.state.setText(CURRENT_STATE_LABEL + call.getCallStateString());
 
         return rowView;
@@ -110,26 +110,26 @@
             return;
         }
         if (newState.equals("INCOMING")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_INCOMING);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_INCOMING);
         } else if (newState.equals("RINGING")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_RINGING);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_RINGING);
         } else if (newState.equals("CURRENT")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_CURRENT);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_CURRENT);
         } else if (newState.equals("HUNGUP")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_HUNGUP);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_HUNGUP);
             mCallList.remove(id);
         } else if (newState.equals("BUSY")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_BUSY);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_BUSY);
             mCallList.remove(id);
         } else if (newState.equals("FAILURE")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_FAILURE);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_FAILURE);
             mCallList.remove(id);
         } else if (newState.equals("HOLD")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_HOLD);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_HOLD);
         } else if (newState.equals("UNHOLD")) {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_CURRENT);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_CURRENT);
         } else {
-            mCallList.get(id).setCallState(SipCall.CALL_STATE_NONE);
+            mCallList.get(id).setCallState(SipCall.state.CALL_STATE_NONE);
         }
         notifyDataSetChanged();
 
diff --git a/src/com/savoirfairelinux/sflphone/adapters/CallListAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/CallListAdapter.java
new file mode 100644
index 0000000..9cc769b
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/adapters/CallListAdapter.java
@@ -0,0 +1,124 @@
+package com.savoirfairelinux.sflphone.adapters;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.CheckedTextView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.model.SipCall;
+
+public class CallListAdapter extends BaseExpandableListAdapter {
+
+    private HashMap<String, SipCall> calls;
+    private Context mContext;
+    
+    public ArrayList<String> groupItem, tempChild;
+    public ArrayList<Object> Childtem = new ArrayList<Object>();
+
+    public CallListAdapter(Context c, HashMap<String, SipCall> hashMap, ArrayList<String> grList, ArrayList<Object> childItem) {
+        mContext = c;
+        calls = hashMap;
+        groupItem = grList;
+        this.Childtem = childItem;
+    }
+
+
+
+//    @Override
+//    public SipCall getItem(int position) {
+//        for(int j = 0 ; j <= position ; ++j){
+//            calls.entrySet().iterator().next();
+//        }
+//
+//        return calls.entrySet().iterator().next().getValue();
+//    }
+
+
+    @Override
+    public Object getChild(int groupPosition, int childPosition) {
+        return null;
+    }
+
+    @Override
+    public long getChildId(int groupPosition, int childPosition) {
+        return 0;
+    }
+
+    @Override
+    public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
+        tempChild = (ArrayList<String>) Childtem.get(groupPosition);
+        TextView text = null;
+        if (convertView == null) {
+            convertView = LayoutInflater.from(mContext).inflate(R.layout.childrow, null);
+        }
+        text = (TextView) convertView.findViewById(R.id.textView1);
+        text.setText(tempChild.get(childPosition));
+        convertView.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Toast.makeText(mContext, tempChild.get(childPosition), Toast.LENGTH_SHORT).show();
+            }
+        });
+        return convertView;
+    }
+
+    @Override
+    public int getChildrenCount(int groupPosition) {
+        return ((ArrayList<String>) Childtem.get(groupPosition)).size();
+    }
+
+    @Override
+    public Object getGroup(int groupPosition) {
+        return null;
+    }
+
+    @Override
+    public int getGroupCount() {
+        return groupItem.size();
+    }
+
+    @Override
+    public void onGroupCollapsed(int groupPosition) {
+        super.onGroupCollapsed(groupPosition);
+    }
+
+    @Override
+    public void onGroupExpanded(int groupPosition) {
+        super.onGroupExpanded(groupPosition);
+    }
+
+    @Override
+    public long getGroupId(int groupPosition) {
+        return 0;
+    }
+
+    @Override
+    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = LayoutInflater.from(mContext).inflate(R.layout.grouprow, null);
+        }
+        ((CheckedTextView) convertView).setText(groupItem.get(groupPosition));
+        ((CheckedTextView) convertView).setChecked(isExpanded);
+        return convertView;
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return false;
+    }
+
+    @Override
+    public boolean isChildSelectable(int groupPosition, int childPosition) {
+        return false;
+    }
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/adapters/CallPagerAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/CallPagerAdapter.java
index b6d7f49..d0e4d75 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/CallPagerAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/CallPagerAdapter.java
@@ -1,12 +1,12 @@
 package com.savoirfairelinux.sflphone.adapters;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.content.Context;
 import android.support.v13.app.FragmentStatePagerAdapter;
+import android.support.v4.view.PagerAdapter;
 import android.util.Log;
 
 import com.savoirfairelinux.sflphone.R;
@@ -36,8 +36,7 @@
         for(int j = 0 ; j <= i ; ++j){
             calls.entrySet().iterator().next();
         }
-        
-        
+
         return calls.entrySet().iterator().next().getValue();
     }
 
@@ -106,6 +105,11 @@
         }
         return null;
     }
+    
+    @Override
+    public int getItemPosition(Object object){
+        return PagerAdapter.POSITION_NONE;
+    }
 
     public void addCall(String mCallID, CallFragment newCall) {
         Log.w(TAG, "Put "+mCallID);
diff --git a/src/com/savoirfairelinux/sflphone/client/CallActivity.java b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
index 3c3ac6a..025709c 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
@@ -3,6 +3,7 @@
  *
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
  *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -43,22 +44,23 @@
 import android.content.ServiceConnection;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.support.v4.view.ViewPager;
+import android.support.v4.widget.SlidingPaneLayout;
 import android.util.Log;
+import android.view.View;
 import android.widget.Toast;
 
 import com.savoirfairelinux.sflphone.R;
-import com.savoirfairelinux.sflphone.adapters.CallPagerAdapter;
 import com.savoirfairelinux.sflphone.client.receiver.CallReceiver;
 import com.savoirfairelinux.sflphone.fragments.CallFragment;
+import com.savoirfairelinux.sflphone.fragments.CallListFragment;
 import com.savoirfairelinux.sflphone.interfaces.CallInterface;
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.service.CallManagerCallBack;
 import com.savoirfairelinux.sflphone.service.ISipService;
 import com.savoirfairelinux.sflphone.service.SipService;
 
-public class CallActivity extends Activity implements CallInterface, CallFragment.Callbacks {
+public class CallActivity extends Activity implements CallInterface, CallFragment.Callbacks, CallListFragment.Callbacks {
     static final String TAG = "CallActivity";
     private ISipService service;
 
@@ -66,10 +68,13 @@
 
     private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
     CallReceiver receiver;
+    
+    CallListFragment mCallsFragment;
+    CallFragment mCurrentCallFragment;
 
-    ViewPager vp;
-    private CallPagerAdapter mCallPagerAdapter;
-    private ViewPager mViewPager;
+
+    // private CallPagerAdapter mCallPagerAdapter;
+    // private ViewPager mViewPager;
 
     /*
      * private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@@ -88,13 +93,47 @@
 
         receiver = new CallReceiver(this);
 
-        if (mCallPagerAdapter == null) {
-            mCallPagerAdapter = new CallPagerAdapter(this, getFragmentManager());
-        }
 
-        mViewPager = (ViewPager) findViewById(R.id.pager);
+        mCallsFragment = new CallListFragment();
+       
+        
+        
+        getFragmentManager().beginTransaction().replace(R.id.calllist_pane, mCallsFragment).commit();
+        
 
-        mViewPager.setAdapter(mCallPagerAdapter);
+        final SlidingPaneLayout slidingPaneLayout = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout);
+        slidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
+
+            @Override
+            public void onPanelSlide(View view, float offSet) {
+            }
+
+            @Override
+            public void onPanelOpened(View view) {
+
+                switch (view.getId()) {
+                case R.id.calllist_pane:
+//                    getFragmentManager().findFragmentById(R.id.calllist_pane).setHasOptionsMenu(true);
+//                    getFragmentManager().findFragmentById(R.id.ongoingcall_pane).setHasOptionsMenu(false);
+                    break;
+                default:
+                    break;
+                }
+            }
+
+            @Override
+            public void onPanelClosed(View view) {
+
+                switch (view.getId()) {
+                case R.id.ongoingcall_pane:
+//                    getFragmentManager().findFragmentById(R.id.calllist_pane).setHasOptionsMenu(false);
+//                    getFragmentManager().findFragmentById(R.id.ongoingcall_pane).setHasOptionsMenu(true);
+                    break;
+                default:
+                    break;
+                }
+            }
+        });
 
         Bundle b = getIntent().getExtras();
 
@@ -102,7 +141,6 @@
 
         // setCallStateDisplay(mCall.getCallStateString());
 
-
         bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
 
     }
@@ -140,12 +178,13 @@
         @Override
         public void onServiceConnected(ComponentName className, IBinder binder) {
             service = ISipService.Stub.asInterface(binder);
-                Log.i(TAG, "Placing call");
-                CallFragment newCall = new CallFragment();
-                newCall.setArguments(getIntent().getExtras());
-                getIntent().getExtras();
-                SipCall.CallInfo info = getIntent().getExtras().getParcelable("CallInfo");
-                mCallPagerAdapter.addCall(info.mCallID, newCall);
+            Log.i(TAG, "Placing call");
+            mCurrentCallFragment = new CallFragment();
+            mCurrentCallFragment.setArguments(getIntent().getExtras());
+            getIntent().getExtras();
+            SipCall info = getIntent().getExtras().getParcelable("CallInfo");
+            // mCallPagerAdapter.addCall(info.mCallID, newCall);
+            getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment).commit();
 
         }
 
@@ -158,7 +197,7 @@
     public void incomingCall(Intent call) {
         Toast.makeText(this, "New Call incoming", Toast.LENGTH_LONG).show();
 
-        // TODO Handle multicall here
+        mCallsFragment.update();
 
     }
 
@@ -175,34 +214,43 @@
          * Bundle bundle = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate"); String callID = bundle.getString("CallID"); String
          * newState = bundle.getString("State");
          */
-        CallFragment fr = (CallFragment) mCallPagerAdapter.getCall(callID);
+        CallFragment fr = mCurrentCallFragment;
 
         if (newState.equals("INCOMING")) {
-            fr.changeCallState(SipCall.CALL_STATE_INCOMING);
+            fr.changeCallState(SipCall.state.CALL_STATE_INCOMING);
 
         } else if (newState.equals("RINGING")) {
-            fr.changeCallState(SipCall.CALL_STATE_RINGING);
+            fr.changeCallState(SipCall.state.CALL_STATE_RINGING);
 
         } else if (newState.equals("CURRENT")) {
-            fr.changeCallState(SipCall.CALL_STATE_CURRENT);
+            fr.changeCallState(SipCall.state.CALL_STATE_CURRENT);
 
         } else if (newState.equals("HUNGUP")) {
-            mCallPagerAdapter.remove(callID);
+//            mCallPagerAdapter.remove(callID);
+//            if (mCallPagerAdapter.getCount() == 0) {
+//                finish();
+//            }
 
         } else if (newState.equals("BUSY")) {
-            mCallPagerAdapter.remove(callID);
+//            mCallPagerAdapter.remove(callID);
+//            if (mCallPagerAdapter.getCount() == 0) {
+//                finish();
+//            }
 
         } else if (newState.equals("FAILURE")) {
-            mCallPagerAdapter.remove(callID);
+//            mCallPagerAdapter.remove(callID);
+//            if (mCallPagerAdapter.getCount() == 0) {
+//                finish();
+//            }
 
         } else if (newState.equals("HOLD")) {
-            fr.changeCallState(SipCall.CALL_STATE_HOLD);
+            fr.changeCallState(SipCall.state.CALL_STATE_HOLD);
 
         } else if (newState.equals("UNHOLD")) {
-            fr.changeCallState(SipCall.CALL_STATE_CURRENT);
+            fr.changeCallState(SipCall.state.CALL_STATE_CURRENT);
 
         } else {
-            fr.changeCallState(SipCall.CALL_STATE_NONE);
+            fr.changeCallState(SipCall.state.CALL_STATE_NONE);
 
         }
 
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index d47a653..5b3b187 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -52,7 +52,6 @@
 import android.util.Log;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.ImageButton;
 import android.widget.RelativeLayout;
 import android.widget.Toast;
 
@@ -75,10 +74,10 @@
 
 public class SFLPhoneHomeActivity extends Activity implements ActionBar.TabListener, DialingFragment.Callbacks, ContactListFragment.Callbacks,
         CallElementListFragment.Callbacks, HistoryFragment.Callbacks, CallInterface {
+
     SectionsPagerAdapter mSectionsPagerAdapter = null;
     static final String TAG = "SFLPhoneHomeActivity";
 
-    ImageButton buttonCall, buttonHangup;
     private ContactListFragment mContactsFragment = null;
     private DialingFragment mDialingFragment = null;
     private CallElementListFragment mCallElementList = null;
@@ -297,11 +296,10 @@
         super.onDestroy();
     }
 
-    public void launchCallActivity(SipCall.CallInfo infos, String action) {
+    public void launchCallActivity(SipCall infos, String action) {
         Log.i(TAG, "Launch Call Activity");
         Bundle bundle = new Bundle();
         bundle.putString("action", action);
-        // bundle.putParcelable("CallContact", mListAdapter.getItem(pos));
         bundle.putParcelable("CallInfo", infos);
         Intent intent = new Intent().setClass(this, CallActivity.class);
         intent.putExtras(bundle);
@@ -378,12 +376,6 @@
         // Log.d(TAG, "onTabReselected");
     }
 
-    public void processingHangUpAction() {
-        SipCall call = (SipCall) buttonHangup.getTag();
-        if (call != null)
-            call.notifyServiceHangup(service);
-    }
-
     @Override
     public void onCallSelected(SipCall c) {
         // launchCallActivity(c.mCallInfo);
@@ -401,13 +393,10 @@
     @Override
     public void incomingCall(Intent call) {
         Toast.makeText(this, "New Call incoming", Toast.LENGTH_LONG).show();
-        SipCall.CallInfo infos = new SipCall.CallInfo(call);
-        SipCall c = new SipCall(infos);
-        mCallElementList.addCall(c);
+        SipCall infos = call.getParcelableExtra("newcall");
 
-        CallContact.ContactBuilder builder = new ContactBuilder();
-        infos.contacts.add(builder.buildUnknownContact(infos.mPhone));
-        
+        mCallElementList.addCall(infos);
+
         launchCallActivity(infos, CallManagerCallBack.INCOMING_CALL);
 
     }
@@ -433,42 +422,35 @@
 
     @Override
     public void onContactSelected(CallContact c) {
-        String callID = Integer.toString(new Random().nextInt());
-        SipCall.CallInfo info = new SipCall.CallInfo();
-        info.mCallID = callID;
+
+        SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
         try {
-            info.mAccountID = service.getAccountList().get(1).toString();
-        } catch (RemoteException e) {
+            callBuilder.startCallCreation().setAccountID(service.getAccountList().get(1).toString()).setCallType(SipCall.state.CALL_TYPE_OUTGOING);
+        } catch (RemoteException e1) {
+            Log.e(TAG,e1.toString());
+        }
+        callBuilder.addContact(c);
+
+        try {
+            launchCallActivity(callBuilder.build(), "call");
+        } catch (Exception e) {
             Log.e(TAG, e.toString());
         }
-        info.mDisplayName = c.getmDisplayName();
-        info.mPhone = c.getSipPhone().getNumber();
-        info.mEmail = c.getmEmail();
-        info.mCallType = SipCall.CALL_TYPE_OUTGOING;
-        info.contacts.add(c);
-
-        launchCallActivity(info, "call");
 
     }
 
     @Override
     public void onCallDialed(String accountID, String to) {
-        Random random = new Random();
-        String callID = Integer.toString(random.nextInt());
-        SipCall.CallInfo info = new SipCall.CallInfo();
 
-        info.mCallID = callID;
-        info.mAccountID = accountID;
-        info.mDisplayName = "Username";
-        info.mPhone = to;
-        info.mEmail = "username@xxxx.com";
-        info.mCallType = SipCall.CALL_TYPE_OUTGOING;
+        SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
+        callBuilder.startCallCreation().setAccountID(accountID).setCallType(SipCall.state.CALL_TYPE_OUTGOING);
+        callBuilder.addContact(CallContact.ContactBuilder.buildUnknownContact(to));
 
-        CallContact.ContactBuilder builder = new ContactBuilder();
-
-        info.contacts.add(builder.buildUnknownContact(info.mPhone));
-
-        launchCallActivity(info, "call");
+        try {
+            launchCallActivity(callBuilder.build(), "call");
+        } catch (Exception e) {
+            Log.e(TAG, e.toString());
+        }
 
     }
 
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java
index 3bdc706..2e2b38c 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java
@@ -147,7 +147,7 @@
      */
 
     public void addCall(SipCall c) {
-        Log.i(TAG, "Adding call " + c.mCallInfo.mDisplayName);
+//        Log.i(TAG, "Adding call " + c.mCallInfo.mDisplayName);
         if (mAdapter == null) {
             Log.w(TAG, "mAdapter is null");
             return;
@@ -189,7 +189,7 @@
                 // // FIXME
                 // service = sflphoneApplication.getSipService();
                 AlertDialog.Builder builder = new AlertDialog.Builder(context);
-                builder.setTitle("Action to perform with " + call.mCallInfo.mDisplayName).setCancelable(true)
+                builder.setTitle("Action to perform with " + call.getContacts().get(0).getmDisplayName()).setCancelable(true)
                         .setItems(items, new DialogInterface.OnClickListener() {
                             @Override
                             public void onClick(DialogInterface dialog, int item) {
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
index b4f5913..903c673 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
@@ -1,3 +1,34 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *
+ *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
 package com.savoirfairelinux.sflphone.fragments;
 
 import java.util.HashMap;
@@ -81,6 +112,12 @@
 
         mCallbacks = (Callbacks) activity;
     }
+    
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        mCallbacks = sDummyCallbacks;
+    }
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -91,13 +128,12 @@
 
         Bundle b = getArguments();
 
-        SipCall.CallInfo info = b.getParcelable("CallInfo");
-        Log.i(TAG, "Starting fragment for call " + info.mCallID);
-        mCall = new SipCall(info);
+        mCall = b.getParcelable("CallInfo");
+        Log.i(TAG, "Starting fragment for call " + mCall.getCallId());
 
         String pendingAction = b.getString("action");
         if (pendingAction != null && pendingAction.contentEquals("call")) {
-            callContact(info);
+            callContact(mCall);
         } else if (pendingAction.equals(CallManagerCallBack.INCOMING_CALL)) {
             callIncoming();
         }
@@ -105,11 +141,11 @@
         return rootView;
     }
 
-    private void callContact(SipCall.CallInfo infos) {
+    private void callContact(SipCall infos) {
         // TODO off-thread image loading
         Bubble contact_bubble;
-        if (infos.contacts.get(0).getPhoto_id() > 0) {
-            Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), infos.contacts.get(0).getId());
+        if (infos.getContacts().get(0).getPhoto_id() > 0) {
+            Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), infos.getContacts().get(0).getId());
             contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, photo);
         } else {
             contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, R.drawable.ic_contact_picture);
@@ -124,12 +160,12 @@
             }
         }));
 
-        contact_bubble.contact = infos.contacts.get(0);
+        contact_bubble.contact = infos.getContacts().get(0);
         model.listBubbles.add(contact_bubble);
-        contacts.put(infos.contacts.get(0), contact_bubble);
-        
+        contacts.put(infos.getContacts().get(0), contact_bubble);
+
         try {
-            mCallbacks.getService().placeCall(infos.mAccountID, infos.mCallID, infos.mPhone);
+            mCallbacks.getService().placeCall(infos);
         } catch (RemoteException e) {
             Log.e(TAG, e.toString());
         }
@@ -152,8 +188,6 @@
 
     }
 
-    
-
     public void onCallAccepted() {
 
         mCall.notifyServiceAnswer(mCallbacks.getService());
@@ -189,15 +223,14 @@
 
     }
 
-    public void onSendMessage(String msg) {
-        mCall.notifyServiceSendMsg(mCallbacks.getService(), msg);
-
-    }
+    // public void onSendMessage(String msg) {
+    // mCall.notifyServiceSendMsg(mCallbacks.getService(), msg);
+    //
+    // }
 
     public void changeCallState(int callState) {
+
         mCall.setCallState(callState);
     }
 
-
-
 }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
new file mode 100644
index 0000000..3ae4fc8
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *
+ *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+package com.savoirfairelinux.sflphone.fragments;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ExpandableListView;
+
+import com.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.adapters.CallListAdapter;
+import com.savoirfairelinux.sflphone.model.SipCall;
+import com.savoirfairelinux.sflphone.service.ISipService;
+
+public class CallListFragment extends Fragment {
+    static final String TAG = "CallFragment";
+
+    private Callbacks mCallbacks = sDummyCallbacks;
+
+    CallListAdapter mAdapter;
+
+    ArrayList<String> groupItem = new ArrayList<String>();
+    ArrayList<Object> childItem = new ArrayList<Object>();
+
+    @Override
+    public void onCreate(Bundle savedBundle) {
+        super.onCreate(savedBundle);
+
+        groupItem.add("TechNology");
+        groupItem.add("Mobile");
+        groupItem.add("Manufacturer");
+        groupItem.add("Extras");
+
+        /**
+         * Add Data For TecthNology
+         */
+        ArrayList<String> child = new ArrayList<String>();
+        child.add("Java");
+        child.add("Drupal");
+        child.add(".Net Framework");
+        child.add("PHP");
+        childItem.add(child);
+
+        /**
+         * Add Data For Mobile
+         */
+        child = new ArrayList<String>();
+        child.add("Android");
+        child.add("Window Mobile");
+        child.add("iPHone");
+        child.add("Blackberry");
+        childItem.add(child);
+        /**
+         * Add Data For Manufacture
+         */
+        child = new ArrayList<String>();
+        child.add("HTC");
+        child.add("Apple");
+        child.add("Samsung");
+        child.add("Nokia");
+        childItem.add(child);
+        /**
+         * Add Data For Extras
+         */
+        child = new ArrayList<String>();
+        child.add("Contact Us");
+        child.add("About Us");
+        child.add("Location");
+        child.add("Root Cause");
+        childItem.add(child);
+
+        mAdapter = new CallListAdapter(getActivity(), new HashMap<String, SipCall>(), groupItem, childItem);
+
+    }
+
+    /**
+     * 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 ISipService getService() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+    };
+
+    /**
+     * The Activity calling this fragment has to implement this interface
+     * 
+     */
+    public interface Callbacks {
+        public ISipService getService();
+
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+
+        if (!(activity instanceof Callbacks)) {
+            throw new IllegalStateException("Activity must implement fragment's callbacks.");
+        }
+
+        mCallbacks = (Callbacks) activity;
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        mCallbacks = sDummyCallbacks;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.frag_call_list, container, false);
+
+        ExpandableListView expandbleLis = (ExpandableListView) rootView.findViewById(R.id.call_list);
+        expandbleLis.setDividerHeight(2);
+        expandbleLis.setGroupIndicator(null);
+        expandbleLis.setClickable(true);
+
+        expandbleLis.setAdapter(mAdapter);
+        return rootView;
+    }
+
+    public void update() {
+        try {
+            HashMap<String, SipCall> list = (HashMap<String, SipCall>) mCallbacks.getService().getCallList();
+        } catch (RemoteException e) {
+            Log.e(TAG, e.toString());
+        }
+
+    }
+
+}
diff --git a/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
index a330843..819abb0 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
@@ -123,6 +123,12 @@
 
         mCallbacks = (Callbacks) activity;
     }
+    
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        mCallbacks = sDummyCallbacks;
+    }
 
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
diff --git a/src/com/savoirfairelinux/sflphone/model/CallContact.java b/src/com/savoirfairelinux/sflphone/model/CallContact.java
index 77d9f2b..b69c794 100644
--- a/src/com/savoirfairelinux/sflphone/model/CallContact.java
+++ b/src/com/savoirfairelinux/sflphone/model/CallContact.java
@@ -152,8 +152,8 @@
             return new ContactBuilder();
         }
 
-        public CallContact buildUnknownContact(String to) {
-            phones = new ArrayList<Phone>();
+        public static CallContact buildUnknownContact(String to) {
+            ArrayList<Phone> phones = new ArrayList<Phone>();
             phones.add(new Phone(to, 0));
             
             return new CallContact(-1, to, 0, phones, new ArrayList<CallContact.Phone>(), "");
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.aidl b/src/com/savoirfairelinux/sflphone/model/SipCall.aidl
new file mode 100644
index 0000000..e1e7264
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.aidl
@@ -0,0 +1,4 @@
+package com.savoirfairelinux.sflphone.model;
+
+
+parcelable SipCall;
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.java b/src/com/savoirfairelinux/sflphone/model/SipCall.java
index 6d14257..bf81adf 100644
--- a/src/com/savoirfairelinux/sflphone/model/SipCall.java
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.java
@@ -31,6 +31,7 @@
 package com.savoirfairelinux.sflphone.model;
 
 import java.util.ArrayList;
+import java.util.Random;
 
 import android.content.Intent;
 import android.os.Bundle;
@@ -40,230 +41,246 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.savoirfairelinux.sflphone.model.Account.AccountBuilder;
+import com.savoirfairelinux.sflphone.model.CallContact.ContactBuilder;
 import com.savoirfairelinux.sflphone.service.ISipService;
 
-public class SipCall {
-    final static String TAG = "SipCall";
-    public CallInfo mCallInfo;
+public class SipCall implements Parcelable {
 
-    public static final int CALL_TYPE_UNDETERMINED = 0;
-    public static final int CALL_TYPE_INCOMING = 1;
-    public static final int CALL_TYPE_OUTGOING = 2;
+    private static final String TAG = SipCall.class.getSimpleName();
 
-    public static final int CALL_STATE_NONE = 0;
-    public static final int CALL_STATE_INCOMING = 1;
-    public static final int CALL_STATE_RINGING = 2;
-    public static final int CALL_STATE_CURRENT = 3;
-    public static final int CALL_STATE_HUNGUP = 4;
-    public static final int CALL_STATE_BUSY = 5;
-    public static final int CALL_STATE_FAILURE = 6;
-    public static final int CALL_STATE_HOLD = 7;
-    public static final int CALL_STATE_UNHOLD = 8;
+    private String mCallID = "";
+    private String mAccountID = "";
+    private ArrayList<CallContact> contacts = new ArrayList<CallContact>();
 
-    public static final int MEDIA_STATE_NONE = 0; // No media currently
-    public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
-    public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
-    public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
-    public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
+    private int mCallType = state.CALL_TYPE_UNDETERMINED;
+    private int mCallState = state.CALL_STATE_NONE;
+    private int mMediaState = state.MEDIA_STATE_NONE;
 
-    public static class CallInfo implements Parcelable {
-        public String mCallID = "";
-        public String mAccountID = "";
-        public String mDisplayName = "";
-        public String mPhone = "";
-        public String mEmail = "";
-        public String mRemoteContact = "";
-        public ArrayList<CallContact> contacts = new ArrayList<CallContact>();
-        public int mCallType = CALL_TYPE_UNDETERMINED;
-        public int mCallState = CALL_STATE_NONE;
-        public int mMediaState = MEDIA_STATE_NONE;
+    /************************
+     * Construtors
+     * 
+     ***********************/
 
-        @Override
-        public int describeContents() {
-            return 0;
-        }
+    private SipCall(Parcel in) {
+        ArrayList<String> list = in.createStringArrayList();
 
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            ArrayList<String> list = new ArrayList<String>();
+        // 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);
 
-            // Don't mess with this order!!!
-            list.add(mCallID);
-            list.add(mAccountID);
-            list.add(mDisplayName);
-            list.add(mPhone);
-            list.add(mEmail);
-            list.add(mRemoteContact);
+        contacts = in.createTypedArrayList(CallContact.CREATOR);
 
-            out.writeStringList(list);
-            out.writeTypedList(contacts);
-            out.writeInt(mCallType);
-            out.writeInt(mCallState);
-            out.writeInt(mMediaState);
-        }
-
-        public static final Parcelable.Creator<CallInfo> CREATOR = new Parcelable.Creator<CallInfo>() {
-            public CallInfo createFromParcel(Parcel in) {
-                return new CallInfo(in);
-            }
-
-            public CallInfo[] newArray(int size) {
-                return new CallInfo[size];
-            }
-        };
-
-        public CallInfo() {
-        }
-
-        private CallInfo(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);
-
-            contacts = in.createTypedArrayList(CallContact.CREATOR);
-            
-            mCallType = in.readInt();
-            mCallState = in.readInt();
-            mMediaState = in.readInt();
-        }
-
-        public CallInfo(Intent call) {
-            Bundle b = call.getBundleExtra("com.savoirfairelinux.sflphone.service.newcall");
-            mAccountID = b.getString("AccountID");
-            mCallID = b.getString("CallID");
-            mDisplayName = b.getString("From");
-        }
+        mCallType = in.readInt();
+        mCallState = in.readInt();
+        mMediaState = in.readInt();
     }
 
-    public SipCall() {
-        mCallInfo = new CallInfo();
+    // public SipCall(Intent call) {
+
+    // }
+
+    public SipCall(String id, String account, int call_type, int call_state, int media_state, ArrayList<CallContact> c) {
+        mCallID = id;
+        mAccountID = account;
+        mCallType = call_type;
+        mCallState = call_state;
+        mMediaState = media_state;
+        this.contacts = new ArrayList<CallContact>(c);
     }
 
-    public SipCall(CallInfo info) {
-        mCallInfo = info;
+
+    // public SipCall() {
+    // }
+
+    public interface state {
+        public static final int CALL_TYPE_UNDETERMINED = 0;
+        public static final int CALL_TYPE_INCOMING = 1;
+        public static final int CALL_TYPE_OUTGOING = 2;
+
+        public static final int CALL_STATE_NONE = 0;
+        public static final int CALL_STATE_INCOMING = 1;
+        public static final int CALL_STATE_RINGING = 2;
+        public static final int CALL_STATE_CURRENT = 3;
+        public static final int CALL_STATE_HUNGUP = 4;
+        public static final int CALL_STATE_BUSY = 5;
+        public static final int CALL_STATE_FAILURE = 6;
+        public static final int CALL_STATE_HOLD = 7;
+        public static final int CALL_STATE_UNHOLD = 8;
+
+        public static final int MEDIA_STATE_NONE = 0; // No media currently
+        public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
+        public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
+        public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
+        public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
     }
 
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        ArrayList<String> list = new ArrayList<String>();
+
+        // Don't mess with this order!!!
+        list.add(mCallID);
+        list.add(mAccountID);
+
+        out.writeStringList(list);
+        out.writeTypedList(contacts);
+        out.writeInt(mCallType);
+        out.writeInt(mCallState);
+        out.writeInt(mMediaState);
+    }
+
+    public static final Parcelable.Creator<SipCall> CREATOR = new Parcelable.Creator<SipCall>() {
+        public SipCall createFromParcel(Parcel in) {
+            return new SipCall(in);
+        }
+
+        public SipCall[] newArray(int size) {
+            return new SipCall[size];
+        }
+    };
+
     public void setCallID(String callID) {
-        mCallInfo.mCallID = callID;
+        mCallID = callID;
     }
 
     public String getCallId() {
-        return mCallInfo.mCallID;
+        return mCallID;
     }
 
     public void setAccountID(String accountID) {
-        mCallInfo.mAccountID = accountID;
+        mAccountID = accountID;
     }
 
     public String getAccountID() {
-        return mCallInfo.mAccountID;
-    }
-
-    public void setDisplayName(String displayName) {
-        mCallInfo.mDisplayName = displayName;
-    }
-
-    public String getDisplayName() {
-        return mCallInfo.mDisplayName;
-    }
-
-    public void setPhone(String phone) {
-        mCallInfo.mPhone = phone;
-    }
-
-    public String getPhone() {
-        return mCallInfo.mPhone;
-    }
-
-    public void setEmail(String email) {
-        mCallInfo.mEmail = email;
-    }
-
-    public String getEmail() {
-        return mCallInfo.mEmail;
-    }
-
-    public void setRemoteContact(String remoteContact) {
-        mCallInfo.mRemoteContact = remoteContact;
-    }
-
-    public String getRemoteContact() {
-        return mCallInfo.mRemoteContact;
+        return mAccountID;
     }
 
     public void setCallType(int callType) {
-        mCallInfo.mCallType = callType;
+        mCallType = callType;
     }
 
     public int getCallType() {
-        return mCallInfo.mCallType;
+        return mCallType;
     }
 
     public void setCallState(int callState) {
-        mCallInfo.mCallState = callState;
+        mCallState = callState;
     }
 
     public int getCallStateInt() {
-        return mCallInfo.mCallState;
+        return mCallState;
+    }
+
+    public String getmCallID() {
+        return mCallID;
+    }
+
+    public void setmCallID(String mCallID) {
+        this.mCallID = mCallID;
+    }
+
+    public String getmAccountID() {
+        return mAccountID;
+    }
+
+    public void setmAccountID(String mAccountID) {
+        this.mAccountID = mAccountID;
+    }
+
+    public ArrayList<CallContact> getContacts() {
+        return contacts;
+    }
+
+    public void setContacts(ArrayList<CallContact> contacts) {
+        this.contacts = contacts;
+    }
+
+    public int getmCallType() {
+        return mCallType;
+    }
+
+    public void setmCallType(int mCallType) {
+        this.mCallType = mCallType;
+    }
+
+    public int getmCallState() {
+        return mCallState;
+    }
+
+    public void setmCallState(int mCallState) {
+        this.mCallState = mCallState;
+    }
+
+    public int getmMediaState() {
+        return mMediaState;
+    }
+
+    public void setmMediaState(int mMediaState) {
+        this.mMediaState = mMediaState;
     }
 
     public String getCallStateString() {
-        String state;
 
-        switch (mCallInfo.mCallState) {
-        case CALL_STATE_INCOMING:
-            state = "INCOMING";
+        String text_state;
+
+        switch (mCallState) {
+        case state.CALL_STATE_INCOMING:
+            text_state = "INCOMING";
             break;
-        case CALL_STATE_RINGING:
-            state = "RINGING";
+        case state.CALL_STATE_RINGING:
+            text_state = "RINGING";
             break;
-        case CALL_STATE_CURRENT:
-            state = "CURRENT";
+        case state.CALL_STATE_CURRENT:
+            text_state = "CURRENT";
             break;
-        case CALL_STATE_HUNGUP:
-            state = "HUNGUP";
+        case state.CALL_STATE_HUNGUP:
+            text_state = "HUNGUP";
             break;
-        case CALL_STATE_BUSY:
-            state = "BUSY";
+        case state.CALL_STATE_BUSY:
+            text_state = "BUSY";
             break;
-        case CALL_STATE_FAILURE:
-            state = "FAILURE";
+        case state.CALL_STATE_FAILURE:
+            text_state = "FAILURE";
             break;
-        case CALL_STATE_HOLD:
-            state = "HOLD";
+        case state.CALL_STATE_HOLD:
+            text_state = "HOLD";
             break;
-        case CALL_STATE_UNHOLD:
-            state = "UNHOLD";
+        case state.CALL_STATE_UNHOLD:
+            text_state = "UNHOLD";
             break;
         default:
-            state = "NULL";
+            text_state = "NULL";
         }
 
-        return state;
+        return text_state;
     }
 
     public void setMediaState(int mediaState) {
-        mCallInfo.mMediaState = mediaState;
+        mMediaState = mediaState;
     }
 
     public int getMediaState() {
-        return mCallInfo.mMediaState;
+        return mMediaState;
     }
 
     public boolean notifyServiceAnswer(ISipService service) {
         int callState = getCallStateInt();
-        if ((callState != CALL_STATE_RINGING) && (callState != CALL_STATE_NONE)) {
+        if ((callState != state.CALL_STATE_RINGING) && (callState != state.CALL_STATE_NONE)) {
             return false;
         }
 
         try {
-            service.accept(mCallInfo.mCallID);
+            service.accept(mCallID);
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot call service method", e);
         }
@@ -275,7 +292,7 @@
      * Perform hangup action without sending request to the service Used when SipService haved been notified that this call hung up
      */
     // public void hangupUpdateUi() {
-    // Log.i(TAG, "Hangup call " + mCallInfo.mCallID);
+    // Log.i(TAG, "Hangup call " + mCallID);
     //
     // if(mCallElementList != null)
     // mCallElementList.removeCall(this);
@@ -284,21 +301,90 @@
     // mHome.onUnselectedCallAction();
     // }
 
+    public static class SipCallBuilder {
+
+        private String bCallID = "";
+        private String bAccountID = "";
+        private ArrayList<CallContact> bContacts = new ArrayList<CallContact>();
+
+        private int bCallType = state.CALL_TYPE_UNDETERMINED;
+        private int bCallState = state.CALL_STATE_NONE;
+        private int bMediaState = state.MEDIA_STATE_NONE;
+
+
+
+        public SipCallBuilder setCallType(int bCallType) {
+            this.bCallType = bCallType;
+            return this;
+        }
+
+        public SipCallBuilder setMediaState(int state) {
+            this.bMediaState = state;
+            return this;
+        }
+
+        public SipCallBuilder setCallState(int state) {
+            this.bCallState = state;
+            return this;
+        }
+        
+        private static final String TAG = SipCallBuilder.class.getSimpleName();
+        
+        public SipCallBuilder startCallCreation(String id) {
+            bCallID = id;
+            bContacts = new ArrayList<CallContact>();
+            bCallType = SipCall.state.CALL_TYPE_INCOMING;
+            return this;
+        }
+
+        public SipCallBuilder startCallCreation() {
+            Random random = new Random();
+            bCallID = Integer.toString(random.nextInt());
+            bContacts = new ArrayList<CallContact>();
+            return this;
+        }
+
+        public SipCallBuilder setAccountID(String h) {
+            Log.i(TAG, "setAccountID" + h);
+            bAccountID = h;
+            return this;
+        }
+
+        public SipCallBuilder addContact(CallContact c) {
+            bContacts.add(c);
+            return this;
+        }
+
+        public SipCall build() throws Exception {
+            if (bCallID.contentEquals("") || bAccountID.contentEquals("") || bContacts.size() == 0) {
+                throw new Exception("SipCallBuilder's parameters missing");
+            }
+            return new SipCall(bCallID, bAccountID, bCallType, bCallState, bMediaState, bContacts);
+        }
+
+        public static SipCallBuilder getInstance() {
+            return new SipCallBuilder();
+        }
+
+
+    }
+
     /**
      * Perform hangup action and send request to the service
      */
     public boolean notifyServiceHangup(ISipService service) {
         try {
-            if ((getCallStateInt() == CALL_STATE_NONE) || (getCallStateInt() == CALL_STATE_CURRENT) || (getCallStateInt() == CALL_STATE_HOLD)) {
-                service.hangUp(mCallInfo.mCallID);
+            if ((getCallStateInt() == state.CALL_STATE_NONE) || (getCallStateInt() == state.CALL_STATE_CURRENT)
+                    || (getCallStateInt() == state.CALL_STATE_HOLD)) {
+                service.hangUp(mCallID);
                 return true;
 
-            } else if (getCallStateInt() == CALL_STATE_RINGING) {
-                if (getCallType() == CALL_TYPE_INCOMING) {
-                    service.refuse(mCallInfo.mCallID);
+            } else if (getCallStateInt() == state.CALL_STATE_RINGING) {
+                if (getCallType() == state.CALL_TYPE_INCOMING) {
+                    service.refuse(mCallID);
                     return true;
-                } else if (getCallType() == CALL_TYPE_OUTGOING) {
-                    service.hangUp(mCallInfo.mCallID);
+                } else if (getCallType() == state.CALL_TYPE_OUTGOING) {
+                    service.hangUp(mCallID);
                     return true;
                 }
             }
@@ -311,8 +397,8 @@
 
     public boolean notifyServiceRefuse(ISipService service) {
         try {
-            if (getCallStateInt() == CALL_STATE_RINGING) {
-                service.refuse(mCallInfo.mCallID);
+            if (getCallStateInt() == state.CALL_STATE_RINGING) {
+                service.refuse(mCallID);
                 return true;
             }
         } catch (RemoteException e) {
@@ -324,8 +410,8 @@
 
     public boolean notifyServiceHold(ISipService service) {
         try {
-            if (getCallStateInt() == CALL_STATE_CURRENT) {
-                service.hold(mCallInfo.mCallID);
+            if (getCallStateInt() == state.CALL_STATE_CURRENT) {
+                service.hold(mCallID);
                 return true;
             }
         } catch (RemoteException e) {
@@ -337,8 +423,8 @@
 
     public boolean notifyServiceUnhold(ISipService service) {
         try {
-            if (getCallStateInt() == CALL_STATE_HOLD) {
-                service.unhold(mCallInfo.mCallID);
+            if (getCallStateInt() == state.CALL_STATE_HOLD) {
+                service.unhold(mCallID);
                 return true;
             }
         } catch (RemoteException e) {
@@ -356,21 +442,21 @@
         Log.i(TAG, "Send text message");
     }
 
-    public void printCallInfo() {
-        Log.i(TAG, "CallInfo: CallID: " + mCallInfo.mCallID);
-        Log.i(TAG, "          AccountID: " + mCallInfo.mAccountID);
-        Log.i(TAG, "          Display Name: " + mCallInfo.mDisplayName);
-        Log.i(TAG, "          Phone: " + mCallInfo.mPhone);
-        Log.i(TAG, "          Email: " + mCallInfo.mEmail);
-        Log.i(TAG, "          Contact: " + mCallInfo.mRemoteContact);
-    }
+    // public void printCallInfo() {
+    // Log.i(TAG, "CallInfo: CallID: " + mCallID);
+    // Log.i(TAG, "          AccountID: " + mAccountID);
+    // Log.i(TAG, "          Display Name: " + mDisplayName);
+    // Log.i(TAG, "          Phone: " + mPhone);
+    // Log.i(TAG, "          Email: " + mEmail);
+    // Log.i(TAG, "          Contact: " + mRemoteContact);
+    // }
 
     /**
      * Compare sip calls based on call ID
      */
     @Override
     public boolean equals(Object c) {
-        if (c instanceof SipCall && ((SipCall) c).mCallInfo.mCallID == mCallInfo.mCallID) {
+        if (c instanceof SipCall && ((SipCall) c).mCallID == mCallID) {
             return true;
         }
         return false;
@@ -379,8 +465,8 @@
 
     public void notifyServiceTransfer(ISipService service, String to) {
         try {
-            if (getCallStateInt() == CALL_STATE_CURRENT) {
-                service.transfer(mCallInfo.mCallID, to);
+            if (getCallStateInt() == state.CALL_STATE_CURRENT) {
+                service.transfer(mCallID, to);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot call service method", e);
@@ -389,10 +475,10 @@
 
     public void notifyServiceRecord(ISipService service) {
         try {
-            if (getCallStateInt() == CALL_STATE_CURRENT) {
+            if (getCallStateInt() == state.CALL_STATE_CURRENT) {
                 service.setRecordPath(Environment.getExternalStorageDirectory().getAbsolutePath());
                 Log.w(TAG, "Recording path" + service.getRecordPath());
-                service.setRecordingCall(mCallInfo.mCallID);
+                service.setRecordingCall(mCallID);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot call service method", e);
@@ -400,14 +486,14 @@
 
     }
 
-    public void notifyServiceSendMsg(ISipService service, String msg) {
-        try {
-            if (getCallStateInt() == CALL_STATE_CURRENT) {
-                service.sendTextMessage(mCallInfo.mCallID, msg, mCallInfo.mDisplayName);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Cannot call service method", e);
-        }
-
-    }
+    // public void notifyServiceSendMsg(ISipService service, String msg) {
+    // try {
+    // if (getCallStateInt() == state.CALL_STATE_CURRENT) {
+    // service.sendTextMessage(mCallID, msg, mDisplayName);
+    // }
+    // } catch (RemoteException e) {
+    // Log.e(TAG, "Cannot call service method", e);
+    // }
+    //
+    // }
 }
diff --git a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
index c0390e3..fd8caa9 100644
--- a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
+++ b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
@@ -81,7 +81,6 @@
         bundle.putString("CallID", callID);
         bundle.putString("State", state);
         Intent intent = new Intent(CALL_STATE_CHANGED);
-        intent.putExtra(SIGNAL_NAME, CALL_STATE_CHANGED); 
         intent.putExtra("com.savoirfairelinux.sflphone.service.newstate", bundle);
         LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
index b57b81d..71692ea 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
@@ -1,8 +1,10 @@
 package com.savoirfairelinux.sflphone.service;
 
+import com.savoirfairelinux.sflphone.model.SipCall;
 
 interface ISipService {
-    void placeCall(String accountID, in String callID, in String to);
+    /*void placeCall(String accountID, in String callID, in String to);*/
+    void placeCall(in SipCall call);
     void refuse(in String callID);
     void accept(in String callID);
     void hangUp(in String callID);
@@ -44,7 +46,7 @@
     void holdConference(in String confID);
     void unholdConference(in String confID);
     List getConferenceList();
-    List getCallList();
+    Map getCallList();
     List getParticipantList(in String confID);
     String getConferenceId(in String callID);
     Map getConferenceDetails(in String callID);
diff --git a/src/com/savoirfairelinux/sflphone/service/SipService.java b/src/com/savoirfairelinux/sflphone/service/SipService.java
index dc4c854..88bd458 100644
--- a/src/com/savoirfairelinux/sflphone/service/SipService.java
+++ b/src/com/savoirfairelinux/sflphone/service/SipService.java
@@ -41,6 +41,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.Vibrator;
 import android.support.v4.content.LocalBroadcastManager;
@@ -51,6 +52,8 @@
 import com.savoirfairelinux.sflphone.account.AudioHandler;
 import com.savoirfairelinux.sflphone.account.HistoryHandler;
 import com.savoirfairelinux.sflphone.client.SFLphoneApplication;
+import com.savoirfairelinux.sflphone.model.CallContact;
+import com.savoirfairelinux.sflphone.model.SipCall;
 
 public class SipService extends Service {
 
@@ -67,8 +70,9 @@
     private ConfigurationManagerCallback configurationManagerCallback;
     private ManagerImpl managerImpl;
     private boolean isPjSipStackStarted = false;
+    
+    HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
 
-    int clients = 0;
 
     private BroadcastReceiver IncomingReceiver = new BroadcastReceiver() {
 
@@ -86,8 +90,47 @@
                 Log.i(TAG, "Received" + intent.getAction());
                 sendBroadcast(intent);
             } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
-                sendBroadcast(intent);
+                Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newcall");
+                
+                SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
+                callBuilder.startCallCreation(b.getString("CallID")).setAccountID(b.getString("AccountID")).setCallType(SipCall.state.CALL_TYPE_OUTGOING);
+                callBuilder.addContact(CallContact.ContactBuilder.buildUnknownContact(b.getString("From")));
+    
+                Intent toSend = new Intent();
+                try {
+                    SipCall newCall = callBuilder.build();
+                    toSend.putExtra("newcall",newCall);
+                    current_calls.put(newCall.getCallId(), newCall);
+                    sendBroadcast(toSend);
+                } catch (Exception e) {
+                    Log.e(TAG, e.toString());
+                }
+                
+                
             } else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {
+                
+                Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate");
+                String newState = b.getString("State");
+                if (newState.equals("INCOMING")) {
+                    current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_INCOMING);
+                } else if (newState.equals("RINGING")) {
+                    current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_RINGING);
+                } else if (newState.equals("CURRENT")) {
+                    current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_CURRENT);
+                } else if (newState.equals("HUNGUP")) {
+                    current_calls.remove(b.getString("CallID"));
+                } else if (newState.equals("BUSY")) {
+                    current_calls.remove(b.getString("CallID"));
+                } else if (newState.equals("FAILURE")) {
+                    current_calls.remove(b.getString("CallID"));
+                } else if (newState.equals("HOLD")) {
+                    current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_HOLD);
+                } else if (newState.equals("UNHOLD")) {
+                    current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_CURRENT);
+                } else {
+                    current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_NONE);
+                }
+                
                 sendBroadcast(intent);
             } else if (intent.getAction().contentEquals(CallManagerCallBack.NEW_CALL_CREATED)) {
                 Log.i(TAG, "Received" + intent.getAction());
@@ -344,12 +387,13 @@
     private final ISipService.Stub mBinder = new ISipService.Stub() {
 
         @Override
-        public void placeCall(final String accountID, final String callID, final String to) {
+        public void placeCall(final SipCall call) {
             getExecutor().execute(new SipRunnable() {
                 @Override
                 protected void doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.placeCall() thread running...");
-                    callManagerJNI.placeCall(accountID, callID, to);
+                    callManagerJNI.placeCall(call.getAccountID(), call.getCallId(), call.getContacts().get(0).getPhones().get(0).getNumber());
+                    current_calls.put(call.getCallId(), call);
                 }
             });
         }
@@ -482,11 +526,9 @@
 
             AccountDetails runInstance = new AccountDetails(accountID);
             getExecutor().execute(runInstance);
-            clients++;
+
             while (!runInstance.isDone()) {
-                Log.w(TAG, "Waiting for Details " + clients);
             }
-            clients--;
             StringMap swigmap = (StringMap) runInstance.getVal();
 
             HashMap<String, String> nativemap = AccountDetailsHandler.convertSwigToNative(swigmap);
@@ -860,31 +902,31 @@
         }
 
         @Override
-        public List getCallList() throws RemoteException {
-            class CallList extends SipRunnableWithReturn {
+        public HashMap<String, SipCall> getCallList() throws RemoteException {
+//            class CallList extends SipRunnableWithReturn {
+//
+//                @Override
+//                protected StringVect doRun() throws SameThreadException {
+//                    Log.i(TAG, "SipService.getCallList() thread running...");
+//                    return callManagerJNI.getCallList();
+//                }
+//            }
+//
+//            CallList runInstance = new CallList();
+//            getExecutor().execute(runInstance);
+//            while (!runInstance.isDone()) {
+//                Log.w(TAG, "Waiting for getAudioCodecList");
+//            }
+//            StringVect swigmap = (StringVect) runInstance.getVal();
+//
+//            ArrayList<String> nativemap = new ArrayList<String>();
+//            for (int i = 0; i < swigmap.size(); ++i) {
+//
+//                String t = swigmap.get(i);
+//                nativemap.add(t);
+//            }
 
-                @Override
-                protected StringVect doRun() throws SameThreadException {
-                    Log.i(TAG, "SipService.getCallList() thread running...");
-                    return callManagerJNI.getCallList();
-                }
-            }
-
-            CallList runInstance = new CallList();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-                Log.w(TAG, "Waiting for getAudioCodecList");
-            }
-            StringVect swigmap = (StringVect) runInstance.getVal();
-
-            ArrayList<String> nativemap = new ArrayList<String>();
-            for (int i = 0; i < swigmap.size(); ++i) {
-
-                String t = swigmap.get(i);
-                nativemap.add(t);
-            }
-
-            return nativemap;
+            return current_calls;
         }
 
     };