* #26145 Thread was locking UI
* #26115 Unattended transfer working
diff --git a/src/com/savoirfairelinux/sflphone/fragments/TransferDFragment.java b/src/com/savoirfairelinux/sflphone/fragments/TransferDFragment.java
new file mode 100644
index 0000000..18bc424
--- /dev/null
+++ b/src/com/savoirfairelinux/sflphone/fragments/TransferDFragment.java
@@ -0,0 +1,266 @@
+package com.savoirfairelinux.sflphone.fragments;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.LoaderManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnShowListener;
+import android.content.Intent;
+import android.content.Loader;
+import android.location.Address;
+import android.location.Geocoder;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.savoirfairelinux.sflphone.R;
+import com.savoirfairelinux.sflphone.loaders.ContactsLoader;
+import com.savoirfairelinux.sflphone.model.CallContact;
+import com.savoirfairelinux.sflphone.model.SipCall;
+
+public class TransferDFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Bundle> {
+
+    private AutoCompleteTextView mEditText;
+    private AutoCompleteAdapter autoCompleteAdapter;
+    SimpleCallListAdapter mAdapter;
+
+    /**
+     * Create a new instance of CallActionsDFragment
+     */
+    static TransferDFragment newInstance(int num) {
+        TransferDFragment f = new TransferDFragment();
+        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) {
+        View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_transfer, null);
+
+        ArrayList<SipCall> calls = getArguments().getParcelableArrayList("calls");
+        final SipCall call_selected = getArguments().getParcelable("call_selected");
+
+        mAdapter = new SimpleCallListAdapter(getActivity(), calls);
+        ListView list = (ListView) rootView.findViewById(R.id.concurrent_calls);
+        list.setAdapter(mAdapter);
+        list.setOnItemClickListener(new OnItemClickListener() {
+
+            @Override
+            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
+
+                Intent in = new Intent();
+                in.putExtra("target", mAdapter.getItem(pos));
+                in.putExtra("transfer", call_selected);
+                getTargetFragment().onActivityResult(getTargetRequestCode(), 0, in);
+                dismiss();
+            }
+        });
+        list.setEmptyView(rootView.findViewById(R.id.empty_view));
+
+        mEditText = (AutoCompleteTextView) rootView.findViewById(R.id.external_number);
+        mEditText.setAdapter(autoCompleteAdapter);
+
+        final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView)
+                .setTitle("Transfer " + call_selected.getContacts().get(0))
+                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                        
+                    }
+                }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+
+                        dismiss();
+                    }
+                }).create();
+
+        a.setOnShowListener(new OnShowListener() {
+
+            @Override
+            public void onShow(DialogInterface dialog) {
+                Button b = a.getButton(AlertDialog.BUTTON_POSITIVE);
+                b.setOnClickListener(new View.OnClickListener() {
+
+                    @Override
+                    public void onClick(View view) {
+                        if(mEditText.getText().length() == 0){
+                            Toast.makeText(getActivity(), "Enter a number to transfer this call", Toast.LENGTH_SHORT).show();
+                        } else {
+                            Intent in = new Intent();
+                            in.putExtra("to_number", mEditText.getText().toString());
+                            in.putExtra("transfer", call_selected);
+                            getTargetFragment().onActivityResult(getTargetRequestCode(), 1, in);
+                            dismiss();
+                        }
+                    }
+                });
+
+            }
+        });
+        return a;
+    }
+
+    @Override
+    public Loader<Bundle> onCreateLoader(int id, Bundle args) {
+        Uri baseUri;
+
+        if (args != null) {
+            baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(args.getString("filter")));
+        } else {
+            baseUri = Contacts.CONTENT_URI;
+        }
+        ContactsLoader l = new ContactsLoader(getActivity(), baseUri);
+        l.forceLoad();
+        return l;
+    }
+
+    @Override
+    public void onLoadFinished(Loader<Bundle> loader, Bundle data) {
+
+        ArrayList<CallContact> tmp = data.getParcelableArrayList("Contacts");
+
+    }
+
+    @Override
+    public void onLoaderReset(Loader<Bundle> loader) {
+        // Thi is called when the last Cursor provided to onLoadFinished
+        // mListAdapter.swapCursor(null);
+    }
+
+    private class AutoCompleteAdapter extends ArrayAdapter<Address> implements Filterable {
+
+        private LayoutInflater mInflater;
+        private Geocoder mGeocoder;
+        private StringBuilder mSb = new StringBuilder();
+
+        public AutoCompleteAdapter(final Context context) {
+            super(context, -1);
+            mInflater = LayoutInflater.from(context);
+            mGeocoder = new Geocoder(context);
+        }
+
+        @Override
+        public View getView(final int position, final View convertView, final ViewGroup parent) {
+            final TextView tv;
+            if (convertView != null) {
+                tv = (TextView) convertView;
+            } else {
+                tv = (TextView) mInflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
+            }
+
+            return tv;
+        }
+
+        @Override
+        public Filter getFilter() {
+            Filter myFilter = new Filter() {
+                @Override
+                protected FilterResults performFiltering(final CharSequence constraint) {
+                    List<Address> addressList = null;
+                    if (constraint != null) {
+                        try {
+                            addressList = mGeocoder.getFromLocationName((String) constraint, 5);
+                        } catch (IOException e) {
+                        }
+                    }
+                    if (addressList == null) {
+                        addressList = new ArrayList<Address>();
+                    }
+
+                    final FilterResults filterResults = new FilterResults();
+                    filterResults.values = addressList;
+                    filterResults.count = addressList.size();
+
+                    return filterResults;
+                }
+
+                @SuppressWarnings("unchecked")
+                @Override
+                protected void publishResults(final CharSequence contraint, final FilterResults results) {
+                    clear();
+                    for (Address address : (List<Address>) results.values) {
+                        add(address);
+                    }
+                    if (results.count > 0) {
+                        notifyDataSetChanged();
+                    } else {
+                        notifyDataSetInvalidated();
+                    }
+                }
+
+                @Override
+                public CharSequence convertResultToString(final Object resultValue) {
+                    return resultValue == null ? "" : ((Address) resultValue).getAddressLine(0);
+                }
+            };
+            return myFilter;
+        }
+    }
+
+    private class SimpleCallListAdapter extends BaseAdapter {
+
+        private LayoutInflater mInflater;
+        ArrayList<SipCall> calls;
+
+        public SimpleCallListAdapter(final Context context, ArrayList<SipCall> calls2) {
+            super();
+            mInflater = LayoutInflater.from(context);
+            calls = calls2;
+        }
+
+        @Override
+        public View getView(final int position, final View convertView, final ViewGroup parent) {
+            final TextView tv;
+            if (convertView != null) {
+                tv = (TextView) convertView;
+            } else {
+                tv = (TextView) mInflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
+            }
+
+            tv.setText(calls.get(position).getContacts().get(0).getmDisplayName());
+            return tv;
+        }
+
+        @Override
+        public int getCount() {
+            return calls.size();
+        }
+
+        @Override
+        public SipCall getItem(int pos) {
+            return calls.get(pos);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return 0;
+        }
+    }
+}