diff --git a/ring-android/app/src/main/java/cx/ring/account/AccountsAdapter.java b/ring-android/app/src/main/java/cx/ring/account/AccountsAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..bdc59160a54f75b18623cbd0dffd053ca9b14c68
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/account/AccountsAdapter.java
@@ -0,0 +1,170 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Aline Bonnet <aline.bonnet@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, see <http://www.gnu.org/licenses/>.
+ */
+
+package cx.ring.account;
+
+import android.graphics.Color;
+import android.support.v4.content.ContextCompat;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import cx.ring.R;
+import cx.ring.model.Account;
+import cx.ring.model.ConfigKey;
+
+public class AccountsAdapter extends BaseAdapter {
+    static final String TAG = AccountsAdapter.class.getSimpleName();
+    private final ArrayList<Account> accounts = new ArrayList<>();
+    private AccountListeners mListeners;
+
+    public AccountsAdapter(AccountListeners listeners) {
+        mListeners = listeners;
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    @Override
+    public int getCount() {
+        return accounts.size();
+    }
+
+    @Override
+    public Account getItem(int pos) {
+        return accounts.get(pos);
+    }
+
+    @Override
+    public long getItemId(int pos) {
+        return 0;
+    }
+
+    @Override
+    public View getView(final int pos, View convertView, ViewGroup parent) {
+        View rowView = convertView;
+        AccountView entryView;
+
+        if (rowView == null) {
+            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+            rowView = inflater.inflate(R.layout.item_account_pref, parent, false);
+
+            entryView = new AccountView();
+            entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
+            entryView.host = (TextView) rowView.findViewById(R.id.account_host);
+            entryView.loadingIndicator = rowView.findViewById(R.id.loading_indicator);
+            entryView.errorIndicator = (ImageView) rowView.findViewById(R.id.error_indicator);
+            entryView.enabled = (CheckBox) rowView.findViewById(R.id.account_checked);
+            entryView.errorIndicator.setColorFilter(parent.getContext().getResources().getColor(R.color.error_red));
+            entryView.errorIndicator.setVisibility(View.GONE);
+            entryView.loadingIndicator.setVisibility(View.GONE);
+            rowView.setTag(entryView);
+        } else {
+            entryView = (AccountView) rowView.getTag();
+        }
+
+        final Account item = accounts.get(pos);
+        entryView.alias.setText(item.getAlias());
+        entryView.host.setTextColor(ContextCompat.getColor(parent.getContext(), R.color.text_color_secondary));
+
+        if (item.isIP2IP()) {
+            entryView.host.setText(item.getRegistrationState());
+        } else if (item.isSip()) {
+            entryView.host.setText(item.getHost() + " - " + item.getRegistrationState());
+        } else {
+            entryView.host.setText(item.getDetail(ConfigKey.ACCOUNT_USERNAME));
+        }
+
+        entryView.enabled.setChecked(item.isEnabled());
+        entryView.enabled.setOnClickListener(new View.OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+                item.setEnabled(!item.isEnabled());
+                mListeners.onItemClicked(item.getAccountID(), item.getDetails());
+            }
+        });
+
+        if (item.isEnabled()) {
+            if (item.isTrying()) {
+                entryView.errorIndicator.setVisibility(View.GONE);
+                entryView.loadingIndicator.setVisibility(View.VISIBLE);
+            } else if (item.needsMigration()) {
+                entryView.host.setText(R.string.account_update_needed);
+                entryView.host.setTextColor(Color.RED);
+                entryView.errorIndicator.setImageResource(R.drawable.ic_warning);
+                entryView.errorIndicator.setColorFilter(Color.RED);
+                entryView.errorIndicator.setVisibility(View.VISIBLE);
+            } else if (item.isInError()) {
+                entryView.errorIndicator.setImageResource(R.drawable.ic_error_white);
+                entryView.errorIndicator.setColorFilter(Color.RED);
+                entryView.errorIndicator.setVisibility(View.VISIBLE);
+                entryView.loadingIndicator.setVisibility(View.GONE);
+            } else if (!item.isRegistered()) {
+                entryView.errorIndicator.setImageResource(R.drawable.ic_network_disconnect_black_24dp);
+                entryView.errorIndicator.setColorFilter(Color.BLACK);
+                entryView.errorIndicator.setVisibility(View.VISIBLE);
+                entryView.loadingIndicator.setVisibility(View.GONE);
+            } else {
+                entryView.errorIndicator.setVisibility(View.GONE);
+                entryView.loadingIndicator.setVisibility(View.GONE);
+            }
+        } else {
+            entryView.errorIndicator.setVisibility(View.GONE);
+            entryView.loadingIndicator.setVisibility(View.GONE);
+        }
+
+        return rowView;
+    }
+
+    /**
+     * ******************
+     * ViewHolder Pattern
+     * *******************
+     */
+    public class AccountView {
+        public TextView alias;
+        public TextView host;
+        public View loadingIndicator;
+        public ImageView errorIndicator;
+        public CheckBox enabled;
+    }
+
+    public void replaceAll(List<Account> results) {
+        Log.d(TAG, "AccountsAdapter replaceAll " + results.size());
+        accounts.clear();
+        accounts.addAll(results);
+        notifyDataSetChanged();
+    }
+
+    public interface AccountListeners {
+        void onItemClicked(String accountId, HashMap<String, String> details);
+    }
+}
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/AccountsManagementFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/AccountsManagementFragment.java
index af6229d1d0a398949358a7ccabdad1993d14964a..a3667ed6a50458349719161200f4a74521c35e01 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/AccountsManagementFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/AccountsManagementFragment.java
@@ -22,10 +22,7 @@
 
 package cx.ring.fragments;
 
-import android.app.Fragment;
-import android.content.Context;
 import android.content.Intent;
-import android.graphics.Color;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.design.widget.FloatingActionButton;
@@ -36,44 +33,34 @@ import android.view.MenuInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.CheckBox;
-import android.widget.ImageView;
 import android.widget.ListView;
-import android.widget.TextView;
 
-import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
-import javax.inject.Inject;
-
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import butterknife.OnItemClick;
 import cx.ring.R;
+import cx.ring.account.AccountsAdapter;
+import cx.ring.account.AccountsManagementPresenter;
+import cx.ring.account.AccountsManagementView;
 import cx.ring.application.RingApplication;
 import cx.ring.account.AccountEditionActivity;
 import cx.ring.client.AccountWizard;
 import cx.ring.client.HomeActivity;
 import cx.ring.model.Account;
-import cx.ring.model.ConfigKey;
-import cx.ring.model.ServiceEvent;
-import cx.ring.services.AccountService;
+import cx.ring.mvp.BaseFragment;
 import cx.ring.utils.ContentUriHandler;
-import cx.ring.utils.Observable;
-import cx.ring.utils.Observer;
 
-public class AccountsManagementFragment extends Fragment implements HomeActivity.Refreshable, Observer<ServiceEvent> {
+public class AccountsManagementFragment extends BaseFragment<AccountsManagementPresenter> implements AccountsManagementView,
+        AccountsAdapter.AccountListeners {
     static final String TAG = AccountsManagementFragment.class.getSimpleName();
 
     public static final int ACCOUNT_CREATE_REQUEST = 1;
     public static final int ACCOUNT_EDIT_REQUEST = 2;
     private AccountsAdapter mAccountsAdapter;
 
-    @Inject
-    AccountService mAccountService;
-
     @BindView(R.id.accounts_list)
     ListView mDnDListView;
 
@@ -88,7 +75,7 @@ public class AccountsManagementFragment extends Fragment implements HomeActivity
         // dependency injection
         ((RingApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
 
-        mAccountsAdapter = new AccountsAdapter(getActivity());
+        mAccountsAdapter = new AccountsAdapter(this);
     }
 
     @Override
@@ -108,34 +95,20 @@ public class AccountsManagementFragment extends Fragment implements HomeActivity
 
     @OnItemClick(R.id.accounts_list)
     @SuppressWarnings("unused")
-    void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
-        Account selectedAccount = mAccountsAdapter.getItem(pos);
-        if (selectedAccount.needsMigration()) {
-            launchAccountMigrationActivity(mAccountsAdapter.getItem(pos));
-        } else {
-            launchAccountEditActivity(mAccountsAdapter.getItem(pos));
-        }
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mAccountService.removeObserver(this);
+    void onItemClick(int pos) {
+        presenter.clickAccount(mAccountsAdapter.getItem(pos));
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        mAccountService.addObserver(this);
-        refresh();
         ((HomeActivity) getActivity()).setToolbarState(true, R.string.menu_item_accounts);
-        FloatingActionButton btn = ((HomeActivity) getActivity()).getActionButton();
-        btn.setImageResource(R.drawable.ic_add_white);
-        btn.setOnClickListener(new OnClickListener() {
+        FloatingActionButton button = ((HomeActivity) getActivity()).getActionButton();
+        button.setImageResource(R.drawable.ic_add_white);
+        button.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                Intent intent = new Intent(getActivity(), AccountWizard.class);
-                startActivityForResult(intent, ACCOUNT_CREATE_REQUEST);
+                presenter.addClicked();
             }
         });
     }
@@ -150,192 +123,54 @@ public class AccountsManagementFragment extends Fragment implements HomeActivity
         menu.clear();
     }
 
-    private void launchAccountEditActivity(Account acc) {
+    @Override
+    public void launchAccountEditActivity(Account account) {
         Log.d(TAG, "Launch account edit activity");
 
         Intent intent = new Intent(getActivity(), AccountEditionActivity.class)
                 .setAction(Intent.ACTION_EDIT)
-                .setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, acc.getAccountID()));
+                .setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, account.getAccountID()));
         startActivityForResult(intent, ACCOUNT_EDIT_REQUEST);
     }
 
-    private void launchAccountMigrationActivity(Account acc) {
+    @Override
+    public void launchAccountMigrationActivity(Account account) {
         Log.d(TAG, "Launch account migration activity");
 
         Intent intent = new Intent()
                 .setClass(getActivity(), AccountWizard.class)
-                .setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, acc.getAccountID()));
+                .setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, account.getAccountID()));
         startActivityForResult(intent, ACCOUNT_EDIT_REQUEST);
     }
 
     @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-        refresh();
+    public void launchWizardActivity() {
+        Intent intent = new Intent(getActivity(), AccountWizard.class);
+        startActivityForResult(intent, ACCOUNT_CREATE_REQUEST);
     }
 
     @Override
-    public void update(Observable observable, ServiceEvent event) {
-
-        if (event == null) {
-            return;
-        }
-
-        switch (event.getEventType()) {
-            case ACCOUNTS_CHANGED:
-            case REGISTRATION_STATE_CHANGED:
-                RingApplication.uiHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        refresh();
-                    }
-                });
-                break;
-            default:
-                Log.d(TAG, "This event is not handled here");
-                break;
-        }
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        presenter.refresh();
     }
 
-    /**
-     * Adapter for accounts List
-     *
-     * @author lisional
-     */
-    public class AccountsAdapter extends BaseAdapter {
-
-        private final ArrayList<Account> accounts = new ArrayList<>();
-        private final Context mContext;
-
-        public AccountsAdapter(Context c) {
-            super();
-            mContext = c;
-        }
-
-        @Override
-        public boolean hasStableIds() {
-            return true;
-        }
-
-        @Override
-        public int getCount() {
-            return accounts.size();
-        }
-
-        @Override
-        public Account getItem(int pos) {
-            return accounts.get(pos);
-        }
-
-        @Override
-        public long getItemId(int pos) {
-            return 0;
-        }
-
-        @Override
-        public View getView(final int pos, View convertView, ViewGroup parent) {
-            View rowView = convertView;
-            AccountView entryView;
-
-            if (rowView == null) {
-                LayoutInflater inflater = LayoutInflater.from(mContext);
-                rowView = inflater.inflate(R.layout.item_account_pref, parent, false);
-
-                entryView = new AccountView();
-                entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
-                entryView.host = (TextView) rowView.findViewById(R.id.account_host);
-                entryView.loadingIndicator = rowView.findViewById(R.id.loading_indicator);
-                entryView.errorIndicator = (ImageView) rowView.findViewById(R.id.error_indicator);
-                entryView.enabled = (CheckBox) rowView.findViewById(R.id.account_checked);
-                entryView.errorIndicator.setColorFilter(mContext.getResources().getColor(R.color.error_red));
-                entryView.errorIndicator.setVisibility(View.GONE);
-                entryView.loadingIndicator.setVisibility(View.GONE);
-                rowView.setTag(entryView);
-            } else {
-                entryView = (AccountView) rowView.getTag();
-            }
-
-            final Account item = accounts.get(pos);
-            entryView.alias.setText(item.getAlias());
-            entryView.host.setTextColor(getResources().getColor(R.color.text_color_secondary));
-
-            if (item.isIP2IP()) {
-                entryView.host.setText(item.getRegistrationState());
-            } else if (item.isSip()) {
-                entryView.host.setText(item.getHost() + " - " + item.getRegistrationState());
-            } else {
-                entryView.host.setText(item.getDetail(ConfigKey.ACCOUNT_USERNAME));
-            }
-
-            entryView.enabled.setChecked(item.isEnabled());
-            entryView.enabled.setOnClickListener(new OnClickListener() {
-
-                @Override
-                public void onClick(View v) {
-                    item.setEnabled(!item.isEnabled());
-                    mAccountService.setAccountDetails(item.getAccountID(), item.getDetails());
-                }
-            });
-
-            if (item.isEnabled()) {
-                if (item.isTrying()) {
-                    entryView.errorIndicator.setVisibility(View.GONE);
-                    entryView.loadingIndicator.setVisibility(View.VISIBLE);
-                } else if (item.needsMigration()) {
-                    entryView.host.setText(R.string.account_update_needed);
-                    entryView.host.setTextColor(Color.RED);
-                    entryView.errorIndicator.setImageResource(R.drawable.ic_warning);
-                    entryView.errorIndicator.setColorFilter(Color.RED);
-                    entryView.errorIndicator.setVisibility(View.VISIBLE);
-                } else if (item.isInError()) {
-                    entryView.errorIndicator.setImageResource(R.drawable.ic_error_white);
-                    entryView.errorIndicator.setColorFilter(Color.RED);
-                    entryView.errorIndicator.setVisibility(View.VISIBLE);
-                    entryView.loadingIndicator.setVisibility(View.GONE);
-                } else if (!item.isRegistered()) {
-                    entryView.errorIndicator.setImageResource(R.drawable.ic_network_disconnect_black_24dp);
-                    entryView.errorIndicator.setColorFilter(Color.BLACK);
-                    entryView.errorIndicator.setVisibility(View.VISIBLE);
-                    entryView.loadingIndicator.setVisibility(View.GONE);
-                } else {
-                    entryView.errorIndicator.setVisibility(View.GONE);
-                    entryView.loadingIndicator.setVisibility(View.GONE);
+    @Override
+    public void refresh(final List<Account> accounts) {
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mAccountsAdapter.replaceAll(accounts);
+                if (mAccountsAdapter.isEmpty() && mDnDListView != null) {
+                    mDnDListView.setEmptyView(mEmptyView);
                 }
-            } else {
-                entryView.errorIndicator.setVisibility(View.GONE);
-                entryView.loadingIndicator.setVisibility(View.GONE);
+                mAccountsAdapter.notifyDataSetChanged();
             }
-
-            return rowView;
-        }
-
-        /**
-         * ******************
-         * ViewHolder Pattern
-         * *******************
-         */
-        public class AccountView {
-            public TextView alias;
-            public TextView host;
-            public View loadingIndicator;
-            public ImageView errorIndicator;
-            public CheckBox enabled;
-        }
-
-        public void replaceAll(List<Account> results) {
-            Log.d(TAG, "AccountsAdapter replaceAll " + results.size());
-            accounts.clear();
-            accounts.addAll(results);
-            notifyDataSetChanged();
-        }
+        });
     }
 
     @Override
-    public void refresh() {
-        mAccountsAdapter.replaceAll(mAccountService.getAccounts());
-        if (mAccountsAdapter.isEmpty() && mDnDListView != null) {
-            mDnDListView.setEmptyView(mEmptyView);
-        }
-        mAccountsAdapter.notifyDataSetChanged();
+    public void onItemClicked(String accountId, HashMap<String, String> details) {
+        presenter.itemClicked(accountId, details);
     }
 }
diff --git a/ring-android/libringclient/src/main/java/cx/ring/account/AccountsManagementPresenter.java b/ring-android/libringclient/src/main/java/cx/ring/account/AccountsManagementPresenter.java
new file mode 100644
index 0000000000000000000000000000000000000000..f26e651e884f5264a98bbe40851a7b5f7f3a6a0d
--- /dev/null
+++ b/ring-android/libringclient/src/main/java/cx/ring/account/AccountsManagementPresenter.java
@@ -0,0 +1,99 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Aline Bonnet <aline.bonnet@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, see <http://www.gnu.org/licenses/>.
+ */
+
+package cx.ring.account;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import cx.ring.model.Account;
+import cx.ring.model.ServiceEvent;
+import cx.ring.mvp.RootPresenter;
+import cx.ring.services.AccountService;
+import cx.ring.utils.Log;
+import cx.ring.utils.Observable;
+import cx.ring.utils.Observer;
+
+public class AccountsManagementPresenter extends RootPresenter<AccountsManagementView> implements Observer<ServiceEvent> {
+
+    private static final String TAG = AccountsManagementPresenter.class.getSimpleName();
+
+    private AccountService mAccountService;
+
+    @Inject
+    public AccountsManagementPresenter(AccountService accountService) {
+        mAccountService = accountService;
+    }
+
+    @Override
+    public void afterInjection() {
+
+    }
+
+    @Override
+    public void bindView(AccountsManagementView view) {
+        super.bindView(view);
+        mAccountService.addObserver(this);
+        view.refresh(mAccountService.getAccounts());
+    }
+
+    @Override
+    public void unbindView() {
+        super.unbindView();
+        mAccountService.removeObserver(this);
+    }
+
+    public void clickAccount(Account account) {
+        if (account.needsMigration()) {
+            getView().launchAccountMigrationActivity(account);
+        } else {
+            getView().launchAccountEditActivity(account);
+        }
+    }
+
+    public void refresh() {
+        getView().refresh(mAccountService.getAccounts());
+    }
+
+    public void addClicked() {
+        getView().launchWizardActivity();
+    }
+
+    public void itemClicked(String accountId, Map<String, String> details) {
+        mAccountService.setAccountDetails(accountId, details);
+    }
+
+    @Override
+    public void update(Observable observable, ServiceEvent event) {
+        if (event == null) {
+            return;
+        }
+
+        switch (event.getEventType()) {
+            case ACCOUNTS_CHANGED:
+            case REGISTRATION_STATE_CHANGED:
+                getView().refresh(mAccountService.getAccounts());
+                break;
+            default:
+                Log.d(TAG, "This event is not handled here");
+                break;
+        }
+    }
+}
diff --git a/ring-android/libringclient/src/main/java/cx/ring/account/AccountsManagementView.java b/ring-android/libringclient/src/main/java/cx/ring/account/AccountsManagementView.java
new file mode 100644
index 0000000000000000000000000000000000000000..81a19f12d526e45f5be434e0b948956c36a33d4f
--- /dev/null
+++ b/ring-android/libringclient/src/main/java/cx/ring/account/AccountsManagementView.java
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Aline Bonnet <aline.bonnet@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, see <http://www.gnu.org/licenses/>.
+ */
+
+package cx.ring.account;
+
+import java.util.List;
+
+import cx.ring.model.Account;
+
+public interface AccountsManagementView {
+
+    void refresh(List<Account> accounts);
+
+    void launchAccountMigrationActivity(Account account);
+
+    void launchAccountEditActivity(Account account);
+
+    void launchWizardActivity();
+}