* #26787 Replaced buttons by DnD
diff --git a/src/com/savoirfairelinux/sflphone/client/CallActivity.java b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
index 16c47e1..2da13ec 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
@@ -256,6 +256,7 @@
 
         mCallsFragment.update();
 
+        if(mCurrentCallFragment != null)
         mCurrentCallFragment.changeCallState(callID, newState);
 
         try {
@@ -469,6 +470,7 @@
     public void replaceCurrentCallDisplayed() {
         mCurrentCallFragment.getBubbleView().stopThread();
         getFragmentManager().beginTransaction().remove(mCurrentCallFragment).commit();
+        mCurrentCallFragment = null;
 
     }
 
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index 098b723..cac9296 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -246,14 +246,14 @@
             }
         });
     }
-    
+
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
         // Sync the toggle state after onRestoreInstanceState has occurred.
         mDrawerToggle.syncState();
     }
-    
+
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
@@ -360,12 +360,15 @@
         Log.i(TAG, "Launch Call Activity");
         Bundle bundle = new Bundle();
         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);
+        overridePendingTransition(R.anim.slide_down, R.anim.slide_up);
     }
 
     /** Defines callbacks for service binding, passed to bindService() */
@@ -425,7 +428,8 @@
             break;
         case REQUEST_CODE_CALL:
             Log.w(TAG, "Result out of CallActivity");
-            getLoaderManager().restartLoader(LoaderConstants.HISTORY_LOADER, null, (HistoryFragment) mSectionsPagerAdapter.getItem(2));
+            if (mSectionsPagerAdapter.getItem(2) != null)
+                getLoaderManager().restartLoader(LoaderConstants.HISTORY_LOADER, null, (HistoryFragment) mSectionsPagerAdapter.getItem(2));
             break;
         }
 
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
index 95d01e9..9276db0 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
@@ -221,7 +221,7 @@
         int angle_part = 360 / conf.getParticipants().size();
         double dX = 0;
         double dY = 0;
-        int radiusCalls = model.width / 2 - 150;
+        int radiusCalls = (int) (model.width / 2 - BUBBLE_SIZE);
         for (int i = 0; i < conf.getParticipants().size(); ++i) {
 
             if (conf.getParticipants().get(i) == null) {
@@ -311,13 +311,13 @@
 
         callStatusTxt.setText("Calling...");
 
-        getBubbleFor(myself, model.width / 2, model.height / 2);
+        getBubbleFor(myself, model.width / 2, (float) (model.height / 1.2));
 
         // TODO off-thread image loading
         int angle_part = 360 / conf.getParticipants().size();
         double dX = 0;
         double dY = 0;
-        int radiusCalls = model.width / 2 - 150;
+        int radiusCalls = (int) ((model.width / 2 - BUBBLE_SIZE));
         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;
@@ -415,9 +415,7 @@
 
     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-        // Log.i(TAG, "Init fragment " + mCall.getCallId());
 
-        // mCall.printCallInfo();
         if (conf.getParticipants().size() == 1) {
 
             if (conf.getParticipants().get(0).isIncoming() && conf.getParticipants().get(0).isRinging()) {
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
index 9abaad3..126eb85 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
@@ -35,24 +35,34 @@
 import java.util.HashMap;
 
 import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
 import android.app.Fragment;
 import android.app.FragmentManager;
+import android.content.ClipData;
+import android.content.ClipData.Item;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.graphics.Color;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.os.Vibrator;
 import android.util.Log;
+import android.view.DragEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
+import android.view.View.DragShadowBuilder;
+import android.view.View.OnDragListener;
 import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.BaseExpandableListAdapter;
-import android.widget.Button;
-import android.widget.ExpandableListView;
-import android.widget.ImageButton;
-import android.widget.RelativeLayout;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.ListAdapter;
+import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -60,6 +70,7 @@
 import com.savoirfairelinux.sflphone.model.Conference;
 import com.savoirfairelinux.sflphone.model.SipCall;
 import com.savoirfairelinux.sflphone.service.ISipService;
+import com.savoirfairelinux.sflphone.views.SwipeListViewTouchListener;
 
 public class CallListFragment extends Fragment {
     static final String TAG = CallListFragment.class.getSimpleName();
@@ -128,22 +139,125 @@
         mCallbacks = sDummyCallbacks;
     }
 
-    ExpandableListView list;
+    ListView list;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.frag_call_list, container, false);
 
-        list = (ExpandableListView) rootView.findViewById(R.id.call_list);
-        list.setDividerHeight(2);
-        list.setGroupIndicator(null);
-        list.setAdapter(mAdapter);
+        list = (ListView) rootView.findViewById(R.id.call_list);
 
-        list.setClickable(true);
-        list.setItemsCanFocus(true);
+        list.setDivider(getResources().getDrawable(android.R.drawable.divider_horizontal_dark));
+        list.setDividerHeight(10);
+        list.setAdapter(mAdapter);
+        list.setOnItemClickListener(mItemClickListener);
+        list.setOnTouchListener(new SwipeListViewTouchListener(list, new SwipeListViewTouchListener.OnSwipeCallback() {
+            @Override
+            public void onSwipeLeft(ListView listView, int[] reverseSortedPositions) {
+                // Log.i(this.getClass().getName(), "swipe left : pos="+reverseSortedPositions[0]);
+                // TODO : YOUR CODE HERE FOR LEFT ACTION
+            }
+
+            @Override
+            public void onSwipeRight(ListView listView, int[] reverseSortedPositions) {
+                // Log.i(ProfileMenuActivity.class.getClass().getName(), "swipe right : pos="+reverseSortedPositions[0]);
+                // TODO : YOUR CODE HERE FOR RIGHT ACTION
+            }
+        }, true, // example : left action = dismiss
+                false)); // example : right action without dismiss animation);
+        list.setOnItemLongClickListener(mItemLongClickListener);
+
         return rootView;
     }
 
+    OnDragListener dragListener = new OnDragListener() {
+
+        @Override
+        public boolean onDrag(View v, DragEvent event) {
+            switch (event.getAction()) {
+            case DragEvent.ACTION_DRAG_STARTED:
+                // Do nothing
+                Log.w(TAG, "ACTION_DRAG_STARTED");
+                break;
+            case DragEvent.ACTION_DRAG_ENTERED:
+                Log.w(TAG, "ACTION_DRAG_ENTERED");
+                v.setBackgroundColor(Color.GREEN);
+                break;
+            case DragEvent.ACTION_DRAG_EXITED:
+                Log.w(TAG, "ACTION_DRAG_EXITED");
+                v.setBackgroundDrawable(getResources().getDrawable(R.drawable.item_call_selector));
+                break;
+            case DragEvent.ACTION_DROP:
+                Log.w(TAG, "ACTION_DROP");
+                View view = (View) event.getLocalState();
+
+                Item i = event.getClipData().getItemAt(0);
+                Intent intent = i.getIntent();
+                intent.setExtrasClassLoader(Conference.class.getClassLoader());
+
+                Conference initial = (Conference) view.getTag();
+                Conference target = (Conference) v.getTag();
+                
+                if(initial == target){
+                    return true;
+                }
+
+                DropActionsChoice dialog = DropActionsChoice.newInstance();
+                Bundle b = new Bundle();
+                b.putParcelable("call_initial", initial);
+                b.putParcelable("call_targeted", target);
+                dialog.setArguments(b);
+                dialog.setTargetFragment(CallListFragment.this, 0);
+                dialog.show(getFragmentManager(), "dialog");
+
+                Toast.makeText(
+                        getActivity(),
+                        "Dropped " + initial.getParticipants().get(0).getContact().getmDisplayName() + " on "
+                                + target.getParticipants().get(0).getContact().getmDisplayName(), Toast.LENGTH_SHORT).show();
+                // view.setBackgroundColor(Color.WHITE);
+                // v.setBackgroundColor(Color.BLACK);
+                break;
+            case DragEvent.ACTION_DRAG_ENDED:
+                Log.w(TAG, "ACTION_DRAG_ENDED");
+                View view1 = (View) event.getLocalState();
+                view1.setVisibility(View.VISIBLE);
+                v.setBackgroundDrawable(getResources().getDrawable(R.drawable.item_call_selector));
+            default:
+                break;
+            }
+            return true;
+        }
+
+    };
+
+    private OnItemLongClickListener mItemLongClickListener = new OnItemLongClickListener() {
+
+        @Override
+        public boolean onItemLongClick(AdapterView<?> arg0, View view, int pos, long arg3) {
+            final Vibrator vibe = (Vibrator) view.getContext().getSystemService(Context.VIBRATOR_SERVICE);
+            vibe.vibrate(80);
+            Intent i = new Intent();
+            Bundle b = new Bundle();
+            b.putParcelable("conference", mAdapter.getItem(pos));
+            i.putExtra("bconference", b);
+            
+            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view.findViewById(R.id.num_participants));
+            ClipData data = ClipData.newIntent("conference", i);
+            view.startDrag(data, shadowBuilder, view, 0);
+            return false;
+        }
+
+    };
+
+    private OnItemClickListener mItemClickListener = new OnItemClickListener() {
+
+        @Override
+        public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
+            mCallbacks.onCallSelected(mAdapter.getItem(pos));
+
+        }
+    };
+
     public void update() {
         try {
             Log.w(TAG, "Updating");
@@ -153,20 +267,6 @@
             ArrayList<Conference> conferences = new ArrayList<Conference>();
             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) {
@@ -191,10 +291,10 @@
         FragmentManager fm = getFragmentManager();
         TransferDFragment editNameDialog = new TransferDFragment();
 
-        if (mAdapter.getGroup(groupPosition).getParticipants().size() == 1) {
+        if (!mAdapter.getItem(groupPosition).hasMultipleParticipants()) {
             Bundle b = new Bundle();
             b.putParcelableArrayList("calls", mAdapter.getConcurrentCalls(groupPosition));
-            b.putParcelable("call_selected", mAdapter.getGroup(groupPosition));
+            b.putParcelable("call_selected", mAdapter.getItem(groupPosition));
             editNameDialog.setArguments(b);
             editNameDialog.setTargetFragment(this, REQUEST_TRANSFER);
             editNameDialog.show(fm, "dialog");
@@ -210,7 +310,7 @@
 
         Bundle b = new Bundle();
         b.putParcelableArrayList("calls", mAdapter.getConcurrentCalls(groupPosition));
-        b.putParcelable("call_selected", mAdapter.getGroup(groupPosition));
+        b.putParcelable("call_selected", mAdapter.getItem(groupPosition));
         confDialog.setArguments(b);
         confDialog.setTargetFragment(this, REQUEST_CONF);
         confDialog.show(fm, "dialog");
@@ -230,7 +330,7 @@
 
                     mCallbacks.getService().attendedTransfer(transfer.getParticipants().get(0).getCallId(), c.getParticipants().get(0).getCallId());
                     mAdapter.remove(transfer);
-
+                    mAdapter.remove(c);
                     mAdapter.notifyDataSetChanged();
                 } catch (RemoteException e) {
                     // TODO Auto-generated catch block
@@ -259,38 +359,10 @@
         } else if (requestCode == REQUEST_CONF) {
             switch (resultCode) {
             case 0:
-                Conference call_to_add = data.getParcelableExtra("call_to_add");
-                Conference call_target = data.getParcelableExtra("call_target");
-                try {
+                Conference call_to_add = data.getParcelableExtra("transfer");
+                Conference call_target = data.getParcelableExtra("target");
 
-                    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());
-                    // mCallbacks.getService().createConfFromParticipantList(tmp);
-
-                } catch (RemoteException e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
-                }
-                Toast.makeText(getActivity(), "Conference created", Toast.LENGTH_LONG).show();
+                bindCalls(call_to_add, call_target);
                 break;
 
             default:
@@ -299,36 +371,47 @@
         }
     }
 
-    /**
-     * A simple adapter which maintains an ArrayList of photo resource Ids. Each photo is displayed as an image. This adapter supports clearing the
-     * list of photos and adding a new photo.
-     * 
-     */
-    public class CallListAdapter extends BaseExpandableListAdapter {
+    private void bindCalls(Conference call_to_add, Conference call_target) {
+        try {
+
+            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());
+            }
+
+        } catch (RemoteException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    public class CallListAdapter extends BaseAdapter {
 
         private ArrayList<Conference> calls;
 
         private Context mContext;
-        private int lastExpandedGroupPosition;
 
-        public CallListAdapter(Context activity) {
+        public CallListAdapter(Context act) {
+            super();
+            mContext = act;
             calls = new ArrayList<Conference>();
-            mContext = activity;
-        }
-
-        public void remove(Conference transfer) {
-            calls.remove(transfer);
 
         }
 
-        // public String getCurrentCall() {
-        // for (int i = 0; i < calls.size(); ++i) {
-        // if (calls.get(i).getCallStateInt() == SipCall.state.CALL_STATE_CURRENT)
-        // return calls.get(i).getCallId();
-        // }
-        // return "";
-        // }
-
         public ArrayList<Conference> getConcurrentCalls(int position) {
             ArrayList<Conference> toReturn = new ArrayList<Conference>();
             for (int i = 0; i < calls.size(); ++i) {
@@ -338,197 +421,119 @@
             return toReturn;
         }
 
-        public ArrayList<Conference> getCalls() {
-            return calls;
-        }
+        public void remove(Conference transfer) {
 
-        @Override
-        public Object getChild(int groupPosition, int childPosition) {
-            return null;
-        }
-
-        public long getChildId(int groupPosition, int childPosition) {
-            return childPosition;
-        }
-
-        public int getChildrenCount(int groupPosition) {
-            return 1;
-        }
-
-        public View getChildView(final int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
-
-            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() {
-
-                @Override
-                public void onClick(View v) {
-                    try {
-                        if (getGroup(groupPosition).getParticipants().size() == 1) {
-                            mCallbacks.getService().hangUp(getGroup(groupPosition).getParticipants().get(0).getCallId());
-                        } else {
-                            mCallbacks.getService().hangUpConference(getGroup(groupPosition).getId());
-                        }
-                    } catch (RemoteException e) {
-                        e.printStackTrace();
-                    }
-
-                }
-            });
-
-            if(getGroup(groupPosition).isOnHold()){
-                ((Button) convertView.findViewById(R.id.action_hold)).setText("Unhold");
-            }
-            ((Button) convertView.findViewById(R.id.action_hold)).setOnClickListener(new OnClickListener() {
-
-                @Override
-                public void onClick(View v) {
-
-                    try {
-                        if (((Button) v).getText().toString().contentEquals("Hold")) {
-                            if (getGroup(groupPosition).getParticipants().size() == 1) {
-                                mCallbacks.getService().hold(getGroup(groupPosition).getParticipants().get(0).getCallId());
-                            } else {
-                                mCallbacks.getService().holdConference(getGroup(groupPosition).getId());
-                            }
-
-                            ((Button) v).setText("Unhold");
-                        } else {
-                            if (getGroup(groupPosition).getParticipants().size() == 1) {
-                                mCallbacks.getService().unhold(getGroup(groupPosition).getParticipants().get(0).getCallId());
-                            } else {
-                                mCallbacks.getService().unholdConference(getGroup(groupPosition).getId());
-                            }
-                            ((Button) v).setText("Hold");
-                        }
-                    } catch (RemoteException e) {
-                        e.printStackTrace();
-                    }
-
-                }
-            });
-
-            ((Button) convertView.findViewById(R.id.action_conf)).setOnClickListener(new OnClickListener() {
-
-                @Override
-                public void onClick(View v) {
-                    makeConferenceDialog(groupPosition);
-                }
-
-            });
-
-            ((Button) convertView.findViewById(R.id.action_transfer)).setOnClickListener(new OnClickListener() {
-
-                @Override
-                public void onClick(View v) {
-                    makeTransferDialog(groupPosition);
-                }
-
-            });
-
-            return convertView;
-        }
-
-        @Override
-        public Conference getGroup(int groupPosition) {
-            return calls.get(groupPosition);
-        }
-
-        @Override
-        public int getGroupCount() {
-            return calls.size();
-        }
-
-        @Override
-        public void onGroupCollapsed(int groupPosition) {
-            super.onGroupCollapsed(groupPosition);
-        }
-
-        @Override
-        public void onGroupExpanded(int groupPosition) {
-
-            // collapse the old expanded group, if not the same
-            // as new group to expand
-            if (groupPosition != lastExpandedGroupPosition) {
-                list.collapseGroup(lastExpandedGroupPosition);
-
-            }
-
-            super.onGroupExpanded(groupPosition);
-            lastExpandedGroupPosition = groupPosition;
-        }
-
-        @Override
-        public long getGroupId(int groupPosition) {
-            return 0;
-        }
-
-        public View getGroupView(final int groupPosition, final boolean isExpanded, View convertView, ViewGroup parent) {
-
-            if (convertView == null)
-                convertView = LayoutInflater.from(mContext).inflate(R.layout.item_calllist, null);
-
-            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.getState());
-            } else {
-                ((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));
-
-                }
-            });
-
-            ((ImageButton) convertView.findViewById(R.id.expand_button)).setOnClickListener(new OnClickListener() {
-
-                @Override
-                public void onClick(View v) {
-
-                    if (isExpanded) {
-                        list.collapseGroup(groupPosition);
-
-                        final Animation animRotate = AnimationUtils.loadAnimation(getActivity(), R.animator.reverse);
-                        ((ImageButton) v).startAnimation(animRotate);
-                        ((ImageButton) v).setRotation(0);
-                    } else {
-                        list.expandGroup(groupPosition);
-                        final Animation animRotate = AnimationUtils.loadAnimation(getActivity(), R.animator.reverse);
-                        ((ImageButton) v).startAnimation(animRotate);
-                        ((ImageButton) v).setRotation(180);
-
-                    }
-                }
-            });
-
-            return convertView;
-        }
-
-        @Override
-        public boolean hasStableIds() {
-            return false;
-        }
-
-        @Override
-        public boolean isChildSelectable(int groupPosition, int childPosition) {
-            return false;
         }
 
         public void update(ArrayList<Conference> list) {
             calls.clear();
             calls.addAll(list);
             notifyDataSetChanged();
-
         }
 
+        @Override
+        public int getCount() {
+            return calls.size();
+        }
+
+        @Override
+        public Conference getItem(int position) {
+            return calls.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return 0;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null)
+                convertView = LayoutInflater.from(mContext).inflate(R.layout.item_calllist, null);
+
+            Conference call = calls.get(position);
+            if (call.getParticipants().size() == 1) {
+                ((TextView) convertView.findViewById(R.id.call_title)).setText(call.getParticipants().get(0).getContact().getmDisplayName());
+            } else {
+                String tmp = "Conference with ";
+                for(SipCall c: call.getParticipants()){
+                    tmp += c.getContact().getmDisplayName() + " ";
+                }
+                ((TextView) convertView.findViewById(R.id.call_title)).setText(tmp);
+            }
+            ((TextView) convertView.findViewById(R.id.num_participants)).setText("" + call.getParticipants().size());
+            ((TextView) convertView.findViewById(R.id.call_status)).setText(call.getState());
+            convertView.setOnDragListener(dragListener);
+
+            convertView.setTag(call);
+            return convertView;
+        }
+
+    }
+
+    public static class DropActionsChoice extends DialogFragment {
+
+        ListAdapter mAdapter;
+        private Bundle args;
+
+        /**
+         * Create a new instance of CallActionsDFragment
+         */
+        public static DropActionsChoice newInstance() {
+            DropActionsChoice f = new DropActionsChoice();
+            return f;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            // Pick a style based on the num.
+            int style = DialogFragment.STYLE_NORMAL, theme = 0;
+            setStyle(style, theme);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            ListView rootView = new ListView(getActivity());
+
+            args = getArguments();
+            mAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, getResources().getStringArray(
+                    R.array.drop_actions));
+
+            // ListView list = (ListView) rootView.findViewById(R.id.concurrent_calls);
+            rootView.setAdapter(mAdapter);
+            rootView.setOnItemClickListener(new OnItemClickListener() {
+
+                @Override
+                public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
+                    Intent in = new Intent();
+
+                    in.putExtra("transfer", args.getParcelable("call_initial"));
+                    in.putExtra("target", args.getParcelable("call_targeted"));
+
+                    switch (pos) {
+                    case 0: // Transfer
+                        getTargetFragment().onActivityResult(REQUEST_TRANSFER, 0, in);
+                        break;
+                    case 1: // Conference
+                        getTargetFragment().onActivityResult(REQUEST_CONF, 0, in);
+                        break;
+                    }
+                    dismiss();
+
+                }
+            });
+
+            final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView).setTitle("Choose Action")
+                    .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int whichButton) {
+                            dismiss();
+                        }
+                    }).create();
+
+            return a;
+        }
     }
 
 }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java b/src/com/savoirfairelinux/sflphone/fragments/ConferenceDFragment.java
index 7fb6c9a..0316d33 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("call_to_add", call_selected);
-                in.putExtra("call_target", mAdapter.getItem(pos));
+                in.putExtra("transfer", call_selected);
+                in.putExtra("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 a5cc407..96cb3f8 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/HomeFragment.java
@@ -149,7 +149,7 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         Log.i(TAG, "onCreateView");
-        View inflatedView = inflater.inflate(R.layout.frag_call_element, container, false);
+        View inflatedView = inflater.inflate(R.layout.frag_home, container, false);
 
         access_calls = (Button) inflatedView.findViewById(R.id.access_callactivity);
 
diff --git a/src/com/savoirfairelinux/sflphone/model/Bubble.java b/src/com/savoirfairelinux/sflphone/model/Bubble.java
index f416169..b22e0bf 100644
--- a/src/com/savoirfairelinux/sflphone/model/Bubble.java
+++ b/src/com/savoirfairelinux/sflphone/model/Bubble.java
@@ -168,19 +168,6 @@
         canvas.drawBitmap(circle, 0, 0, circlePaint);
         circle_drawer.drawOval(new RectF(0, 0, internalBMP.getWidth(), internalBMP.getHeight()), circlePaint);
 
-        int[] allpixels = new int[internalBMP.getHeight() * internalBMP.getWidth()];
-
-        internalBMP.getPixels(allpixels, 0, internalBMP.getWidth(), 0, 0, internalBMP.getWidth(), internalBMP.getHeight());
-
-        for (int i = 0; i < internalBMP.getHeight() * internalBMP.getWidth(); i++) {
-//            Log.i("Bubble", "allpixels[i]:"+allpixels[i]);
-            if (allpixels[i] == Color.BLACK) {
-                Log.i("Bubble", "replacing color");
-                allpixels[i] = 0xAA000000;
-            }
-        }
-        
-        internalBMP.setPixels(allpixels, 0, internalBMP.getWidth(), 0, 0, internalBMP.getWidth(), internalBMP.getHeight());
         externalBMP = Bitmap.createBitmap((int) (getRadius() * 2), (int) (getRadius() * 2), Bitmap.Config.ARGB_8888);
         Canvas canvasf = new Canvas(externalBMP);
 
@@ -194,6 +181,19 @@
         fatality.setStyle(Paint.Style.FILL);
 
         canvasf.drawOval(new RectF(0, 0, getRadius() * 2, getRadius() * 2), mPaintPath); // background with buttons
+        
+        int[] allpixels = new int[internalBMP.getHeight() * internalBMP.getWidth()];
+
+        internalBMP.getPixels(allpixels, 0, internalBMP.getWidth(), 0, 0, internalBMP.getWidth(), internalBMP.getHeight());
+        for (int i = 0; i < internalBMP.getHeight() * internalBMP.getWidth(); i++) {
+            // Log.i("Bubble", "allpixels[i]:"+allpixels[i]);
+            if (allpixels[i] == Color.BLACK) {
+                Log.i("Bubble", "replacing color");
+                allpixels[i] = 0xAA000000;
+            }
+        }
+        internalBMP.setPixels(allpixels, 0, internalBMP.getWidth(), 0, 0, internalBMP.getWidth(), internalBMP.getHeight());
+        
         canvasf.drawBitmap(internalBMP, (float) (getRadius() - radius), (float) (getRadius() - radius), fatality);
 
     }
diff --git a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
index 1a69796..2032e6e 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
@@ -185,12 +185,6 @@
 
     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;
         }
diff --git a/src/com/savoirfairelinux/sflphone/model/BubblesView.java b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
index 077f1bf..a29d8ab 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubblesView.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
@@ -267,16 +267,19 @@
 

                     for (int i = 0, n = bubbles.size(); i < n; i++) {

                         Bubble b = bubbles.get(i);

+                        if(b.expanded){

+                            continue;

+                        }

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

                         canvas.drawText(b.associated_call.getContact().getmDisplayName(), b.getPosX(),

-                                (float) (b.getPosY() - b.getRetractedRadius() * 1.5 * density), getNamePaint(b));

+                                (float) (b.getPosY() - b.getRetractedRadius() * 1.2 * density), getNamePaint(b));

                     }

                     Bubble first_plan = getExpandedBubble();

                     if (first_plan != null) {

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

                         

                         canvas.drawText(first_plan.associated_call.getContact().getmDisplayName(), first_plan.getPosX(),

-                                (float) (first_plan.getPosY() - first_plan.getRetractedRadius() * 1.5 * density), getNamePaint(first_plan));

+                                (float) (first_plan.getPosY() - first_plan.getRetractedRadius() * 1.2 * density), getNamePaint(first_plan));

                         

                         canvas.drawText("Transfer", first_plan.getPosX(), (float) (first_plan.getPosY() + first_plan.getRetractedRadius() * 1.5

                                 * density), getNamePaint(first_plan));

diff --git a/src/com/savoirfairelinux/sflphone/model/CallContact.java b/src/com/savoirfairelinux/sflphone/model/CallContact.java
index adfd61d..bc720a0 100644
--- a/src/com/savoirfairelinux/sflphone/model/CallContact.java
+++ b/src/com/savoirfairelinux/sflphone/model/CallContact.java
@@ -49,7 +49,7 @@
 
     private CallContact(long cID, String displayName, long photoID, ArrayList<Phone> p, ArrayList<Phone> sip, String mail, boolean user) {
         id = cID;
-        mDisplayName = displayName.substring(0, displayName.length() > 10 ? 10 : displayName.length());
+        mDisplayName = displayName;
         phones = p;
         sip_phones = sip;
         mEmail = mail;
diff --git a/src/com/savoirfairelinux/sflphone/model/Conference.java b/src/com/savoirfairelinux/sflphone/model/Conference.java
index 4418210..c242b4d 100644
--- a/src/com/savoirfairelinux/sflphone/model/Conference.java
+++ b/src/com/savoirfairelinux/sflphone/model/Conference.java
@@ -107,6 +107,28 @@
         }
         return null;
     }
+    
+    /**
+     * Compare conferences based on confID/participants
+     */
+    @Override
+    public boolean equals(Object c) {
+        if (c instanceof Conference) {
+            if(((Conference) c).id.contentEquals(id) && !id.contentEquals("-1")){
+                return true;
+            } else {
+                if(((Conference) c).id.contentEquals(id)){
+                    for (int i = 0; i < participants.size(); ++i) {
+                        if (!((Conference) c).contains(participants.get(i).getCallId()))
+                            return false;
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+
+    }
 
     public boolean hasMultipleParticipants() {
         return participants.size() > 1;
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.java b/src/com/savoirfairelinux/sflphone/model/SipCall.java
index 3f38733..2d83e99 100644
--- a/src/com/savoirfairelinux/sflphone/model/SipCall.java
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.java
@@ -349,7 +349,7 @@
      */
     @Override
     public boolean equals(Object c) {
-        if (c instanceof SipCall && ((SipCall) c).mCallID == mCallID) {
+        if (c instanceof SipCall && ((SipCall) c).mCallID.contentEquals((mCallID))) {
             return true;
         }
         return false;
diff --git a/src/com/savoirfairelinux/sflphone/views/SwipeListViewTouchListener.java b/src/com/savoirfairelinux/sflphone/views/SwipeListViewTouchListener.java
new file mode 100644
index 0000000..96e65b7
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/views/SwipeListViewTouchListener.java
@@ -0,0 +1,331 @@
+package com.savoirfairelinux.sflphone.views;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.graphics.Rect;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.ListView;
+
+public class SwipeListViewTouchListener implements View.OnTouchListener {
+    // Cached ViewConfiguration and system-wide constant values
+    private int mSlop;
+    private int mMinFlingVelocity;
+    private int mMaxFlingVelocity;
+    private long mAnimationTime;
+
+    // Fixed properties
+    private ListView mListView;
+    private OnSwipeCallback mCallback;
+    private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
+    private boolean dismissLeft = true;
+    private boolean dismissRight = true;
+
+    // Transient properties
+    private List < PendingSwipeData > mPendingSwipes = new ArrayList < PendingSwipeData > ();
+    private int mDismissAnimationRefCount = 0;
+    private float mDownX;
+    private boolean mSwiping;
+    private VelocityTracker mVelocityTracker;
+    private int mDownPosition;
+    private View mDownView;
+    private boolean mPaused;
+
+    /**
+     * The callback interface used by {@link SwipeListViewTouchListener} to inform its client
+     * about a successful swipe of one or more list item positions.
+     */
+    public interface OnSwipeCallback {
+        /**
+         * Called when the user has swiped the list item to the left.
+         *
+         * @param listView               The originating {@link ListView}.
+         * @param reverseSortedPositions An array of positions to dismiss, sorted in descending
+         *                               order for convenience.
+         */
+        void onSwipeLeft(ListView listView, int[] reverseSortedPositions);
+
+        void onSwipeRight(ListView listView, int[] reverseSortedPositions);
+    }
+
+    /**
+     * Constructs a new swipe-to-action touch listener for the given list view.
+     *
+     * @param listView The list view whose items should be dismissable.
+     * @param callback The callback to trigger when the user has indicated that she would like to
+     *                 dismiss one or more list items.
+     */
+    public SwipeListViewTouchListener(ListView listView, OnSwipeCallback callback) {
+        ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
+        mSlop = vc.getScaledTouchSlop();
+        mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
+        mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
+        mAnimationTime = listView.getContext().getResources().getInteger(
+            android.R.integer.config_shortAnimTime);
+        mListView = listView;
+        mCallback = callback;
+    }
+
+    /**
+     * Constructs a new swipe-to-action touch listener for the given list view.
+     * 
+     * @param listView The list view whose items should be dismissable.
+     * @param callback The callback to trigger when the user has indicated that she would like to
+     *                 dismiss one or more list items.
+     * @param dismissLeft set if the dismiss animation is up when the user swipe to the left
+     * @param dismissRight set if the dismiss animation is up when the user swipe to the right
+     * @see #SwipeListViewTouchListener(ListView, OnSwipeCallback, boolean, boolean)
+     */
+    public SwipeListViewTouchListener(ListView listView, OnSwipeCallback callback, boolean dismissLeft, boolean dismissRight) {
+        this(listView, callback);
+        this.dismissLeft = dismissLeft;
+        this.dismissRight = dismissRight;
+    }
+
+    /**
+     * Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures.
+     *
+     * @param enabled Whether or not to watch for gestures.
+     */
+    public void setEnabled(boolean enabled) {
+        mPaused = !enabled;
+    }
+
+    /**
+     * Returns an {@link android.widget.AbsListView.OnScrollListener} to be added to the
+     * {@link ListView} using
+     * {@link ListView#setOnScrollListener(android.widget.AbsListView.OnScrollListener)}.
+     * If a scroll listener is already assigned, the caller should still pass scroll changes
+     * through to this listener. This will ensure that this
+     * {@link SwipeListViewTouchListener} is paused during list view scrolling.</p>
+     *
+     * @see {@link SwipeListViewTouchListener}
+     */
+    public AbsListView.OnScrollListener makeScrollListener() {
+        return new AbsListView.OnScrollListener() {@
+            Override
+            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
+                setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+            }
+
+            @
+            Override
+            public void onScroll(AbsListView absListView, int i, int i1, int i2) {}
+        };
+    }
+
+    @
+    Override
+    public boolean onTouch(View view, MotionEvent motionEvent) {
+        if (mViewWidth < 2) {
+            mViewWidth = mListView.getWidth();
+        }
+
+        switch (motionEvent.getActionMasked()) {
+        case MotionEvent.ACTION_DOWN:
+            {
+                if (mPaused) {
+                    return false;
+                }
+
+                // TODO: ensure this is a finger, and set a flag
+
+                // Find the child view that was touched (perform a hit test)
+                Rect rect = new Rect();
+                int childCount = mListView.getChildCount();
+                int[] listViewCoords = new int[2];
+                mListView.getLocationOnScreen(listViewCoords);
+                int x = (int) motionEvent.getRawX() - listViewCoords[0];
+                int y = (int) motionEvent.getRawY() - listViewCoords[1];
+                View child;
+                for (int i = 0; i < childCount; i++) {
+                    child = mListView.getChildAt(i);
+                    child.getHitRect(rect);
+                    if (rect.contains(x, y)) {
+                        mDownView = child;
+                        break;
+                    }
+                }
+
+                if (mDownView != null) {
+                    mDownX = motionEvent.getRawX();
+                    mDownPosition = mListView.getPositionForView(mDownView);
+
+                    mVelocityTracker = VelocityTracker.obtain();
+                    mVelocityTracker.addMovement(motionEvent);
+                }
+                view.onTouchEvent(motionEvent);
+                return true;
+            }
+
+        case MotionEvent.ACTION_UP:
+            {
+                if (mVelocityTracker == null) {
+                    break;
+                }
+
+                float deltaX = motionEvent.getRawX() - mDownX;
+                mVelocityTracker.addMovement(motionEvent);
+                mVelocityTracker.computeCurrentVelocity(500); // 1000 by defaut but it was too much
+                float velocityX = Math.abs(mVelocityTracker.getXVelocity());
+                float velocityY = Math.abs(mVelocityTracker.getYVelocity());
+                boolean swipe = false;
+                boolean swipeRight = false;
+
+                if (Math.abs(deltaX) > mViewWidth / 2) {
+                    swipe = true;
+                    swipeRight = deltaX > 0;
+                } else if (mMinFlingVelocity <= velocityX && velocityX <= mMaxFlingVelocity && velocityY < velocityX) {
+                    swipe = true;
+                    swipeRight = mVelocityTracker.getXVelocity() > 0;
+                }
+                if (swipe) {
+                    // sufficent swipe value
+                    final View downView = mDownView; // mDownView gets null'd before animation ends
+                    final int downPosition = mDownPosition;
+                    final boolean toTheRight = swipeRight;
+                    ++mDismissAnimationRefCount;
+                    mDownView.animate()
+                        .translationX(swipeRight ? mViewWidth : -mViewWidth)
+                        .alpha(0)
+                        .setDuration(mAnimationTime)
+                        .setListener(new AnimatorListenerAdapter() {@
+                        Override
+                        public void onAnimationEnd(Animator animation) {
+                            performSwipeAction(downView, downPosition, toTheRight, toTheRight ? dismissRight : dismissLeft);
+                        }
+                    });
+                } else {
+                    // cancel
+                    mDownView.animate()
+                        .translationX(0)
+                        .alpha(1)
+                        .setDuration(mAnimationTime)
+                        .setListener(null);
+                }
+                mVelocityTracker = null;
+                mDownX = 0;
+                mDownView = null;
+                mDownPosition = ListView.INVALID_POSITION;
+                mSwiping = false;
+                break;
+            }
+
+        case MotionEvent.ACTION_MOVE:
+            {
+                if (mVelocityTracker == null || mPaused) {
+                    break;
+                }
+
+                mVelocityTracker.addMovement(motionEvent);
+                float deltaX = motionEvent.getRawX() - mDownX;
+                if (Math.abs(deltaX) > mSlop) {
+                    mSwiping = true;
+                    mListView.requestDisallowInterceptTouchEvent(true);
+
+                    // Cancel ListView's touch (un-highlighting the item)
+                    MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
+                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
+                        (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
+                    mListView.onTouchEvent(cancelEvent);
+                }
+
+                if (mSwiping) {
+                    mDownView.setTranslationX(deltaX);
+                    mDownView.setAlpha(Math.max(0f, Math.min(1f,
+                        1f - 2f * Math.abs(deltaX) / mViewWidth)));
+                    return true;
+                }
+                break;
+            }
+        }
+        return false;
+    }
+
+    class PendingSwipeData implements Comparable < PendingSwipeData > {
+        public int position;
+        public View view;
+
+        public PendingSwipeData(int position, View view) {
+            this.position = position;
+            this.view = view;
+        }
+
+        @
+        Override
+        public int compareTo(PendingSwipeData other) {
+            // Sort by descending position
+            return other.position - position;
+        }
+    }
+
+    private void performSwipeAction(final View swipeView, final int swipePosition, boolean toTheRight, boolean dismiss) {
+        // Animate the dismissed list item to zero-height and fire the dismiss callback when
+        // all dismissed list item animations have completed. This triggers layout on each animation
+        // frame; in the future we may want to do something smarter and more performant.
+
+        final ViewGroup.LayoutParams lp = swipeView.getLayoutParams();
+        final int originalHeight = swipeView.getHeight();
+        final boolean swipeRight = toTheRight;
+
+        ValueAnimator animator;
+        if (dismiss)
+            animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
+        else
+            animator = ValueAnimator.ofInt(originalHeight, originalHeight - 1).setDuration(mAnimationTime);
+
+
+        animator.addListener(new AnimatorListenerAdapter() {@
+            Override
+            public void onAnimationEnd(Animator animation) {
+                --mDismissAnimationRefCount;
+                if (mDismissAnimationRefCount == 0) {
+                    // No active animations, process all pending dismisses.
+                    // Sort by descending position
+                    Collections.sort(mPendingSwipes);
+
+                    int[] swipePositions = new int[mPendingSwipes.size()];
+                    for (int i = mPendingSwipes.size() - 1; i >= 0; i--) {
+                        swipePositions[i] = mPendingSwipes.get(i).position;
+                    }
+                    if (swipeRight)
+                        mCallback.onSwipeRight(mListView, swipePositions);
+                    else
+                        mCallback.onSwipeLeft(mListView, swipePositions);
+
+                    ViewGroup.LayoutParams lp;
+                    for (PendingSwipeData pendingDismiss: mPendingSwipes) {
+                        // Reset view presentation
+                        pendingDismiss.view.setAlpha(1f);
+                        pendingDismiss.view.setTranslationX(0);
+                        lp = pendingDismiss.view.getLayoutParams();
+                        lp.height = originalHeight;
+                        pendingDismiss.view.setLayoutParams(lp);
+                    }
+
+                    mPendingSwipes.clear();
+                }
+            }
+        });
+
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@
+            Override
+            public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                lp.height = (Integer) valueAnimator.getAnimatedValue();
+                swipeView.setLayoutParams(lp);
+            }
+        });
+
+        mPendingSwipes.add(new PendingSwipeData(swipePosition, swipeView));
+        animator.start();
+    }
+}