blockchain: add name registration

- Allow to register name during account creation
- New account settings allow to see registered name,
  if any, or to register a name.

Tuleap: #1157
Change-Id: Ib26cf3325efeee10db0a088f3dd5a9c12de149fb
diff --git a/ring-android/app/src/main/AndroidManifest.xml b/ring-android/app/src/main/AndroidManifest.xml
index d11ee57..326713d 100644
--- a/ring-android/app/src/main/AndroidManifest.xml
+++ b/ring-android/app/src/main/AndroidManifest.xml
@@ -49,6 +49,7 @@
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
     <uses-feature
         android:name="android.hardware.wifi"
@@ -67,22 +68,21 @@
         android:allowBackup="true"
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name"
-        android:supportsRtl="true"
-        android:resizeableActivity="true">
+        android:resizeableActivity="true"
+        android:supportsRtl="true">
         <activity
             android:name=".client.HomeActivity"
+            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
             android:label="@string/title_activity_sflphone_home"
-            android:theme="@style/AppThemeBase"
-            android:windowSoftInputMode="adjustResize"
-            android:screenOrientation="fullUser"
             android:launchMode="singleTask"
-            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize">
+            android:screenOrientation="fullUser"
+            android:theme="@style/AppThemeBase"
+            android:windowSoftInputMode="adjustResize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
-
             <intent-filter>
                 <action android:name="android.intent.action.DIAL" />
                 <action android:name="android.intent.action.VIEW" />
@@ -134,28 +134,27 @@
 
                 <data android:scheme="ring" />
             </intent-filter>
-
         </activity>
         <activity
             android:name=".client.AccountWizard"
-            android:theme="@style/AppThemeBase"
+            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
             android:screenOrientation="fullUser"
-            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize">
+            android:theme="@style/AppThemeBase">
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value="cx.ring.client.AccountEditionActivity" />
         </activity>
         <activity
             android:name=".client.AccountEditionActivity"
+            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
             android:label="@string/app_name"
-            android:theme="@style/AppThemeBase"
             android:screenOrientation="fullUser"
-            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"/>
+            android:theme="@style/AppThemeBase" />
         <activity
             android:name=".client.NewConversationActivity"
             android:label="@string/app_name"
-            android:theme="@style/AppThemeBase"
-            android:screenOrientation="fullUser"/>
+            android:screenOrientation="fullUser"
+            android:theme="@style/AppThemeBase" />
 
         <receiver android:name=".service.OutgoingCallHandler">
             <intent-filter>
@@ -172,12 +171,11 @@
 
         <activity
             android:name=".client.CallActivity"
+            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
             android:label="@string/app_name"
             android:screenOrientation="fullUser"
-            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
             android:theme="@style/AppTheme.ActionBar.Transparent"
             android:windowSoftInputMode="adjustPan|stateHidden">
-
             <intent-filter>
                 <action android:name="android.intent.action.CALL" />
 
@@ -224,7 +222,6 @@
 
                 <data android:scheme="ring" />
             </intent-filter>
-
             <intent-filter>
                 <action android:name="android.intent.action.CALL" />
                 <action android:name="android.intent.action.DIAL" />
@@ -238,19 +235,18 @@
         </activity>
         <activity
             android:name=".client.ConversationActivity"
+            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
             android:label="@string/app_name"
             android:parentActivityName=".client.HomeActivity"
-            android:theme="@style/AppThemeBase"
-            android:windowSoftInputMode="adjustResize"
             android:screenOrientation="fullUser"
-            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
-            />
-        <activity android:name=".client.QRCodeScannerActivity"
+            android:theme="@style/AppThemeBase"
+            android:windowSoftInputMode="adjustResize" />
+        <activity
+            android:name=".client.QRCodeScannerActivity"
             android:screenOrientation="fullUser"
             android:stateNotNeeded="true"
             android:theme="@style/zxing_CaptureTheme"
-            android:windowSoftInputMode="stateAlwaysHidden">
-        </activity>
+            android:windowSoftInputMode="stateAlwaysHidden"></activity>
 
         <service
             android:name=".service.LocalService"
@@ -268,4 +264,4 @@
         </service>
     </application>
 
-</manifest>
+</manifest>
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java b/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
index 8289747..4a55281 100644
--- a/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/AccountEditionActivity.java
@@ -22,49 +22,34 @@
 
 package cx.ring.client;
 
-import android.Manifest;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Fragment;
 import android.app.FragmentManager;
-import android.app.ProgressDialog;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
 import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Build;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
+import android.support.annotation.StringRes;
 import android.support.v13.app.FragmentPagerAdapter;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
 import android.support.v4.view.ViewPager;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.Toolbar;
 import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.inputmethod.EditorInfo;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import com.astuetz.PagerSlidingTabStrip;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Observable;
 import java.util.Observer;
@@ -122,41 +107,23 @@
     private boolean mBound = false;
     private LocalService mService;
     private Account mAccSelected = null;
-    private Fragment mCurrentlyDisplayed;
 
-    private Observer mAccountObserver = new Observer() {
+    private Fragment mCurrentlyDisplayed;
+    private ViewPager mViewPager = null;
+    private PagerSlidingTabStrip mSlidingTabLayout = null;
+
+    private final Observer mAccountObserver = new Observer() {
 
         @Override
         public void update(Observable observable, Object data) {
-            if (mAccSelected == null || mService == null) {
-                return;
+            Log.i(TAG, "Observer: account changed !");
+            for (AccountChangedListener l : listeners) {
+                l.accountChanged(mAccSelected);
             }
-
-            final Account acc = mAccSelected;
-            if (getSupportActionBar() != null) {
-                getSupportActionBar().setTitle(acc.getAlias());
-            }
-
-            final IDRingService remote = getRemoteService();
-            if (remote == null) {
-                Log.w(TAG, "Error updating account, remote service is null");
-                return;
-            }
-            mService.getThreadPool().submit(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        remote.setCredentials(acc.getAccountID(), acc.getCredentialsHashMapList());
-                        remote.setAccountDetails(acc.getAccountID(), acc.getDetails());
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Error while setting credentials", e);
-                    }
-                }
-            });
         }
     };
 
-    private ServiceConnection mConnection = new ServiceConnection() {
+    private final ServiceConnection mConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName className, IBinder s) {
             LocalService.LocalBinder binder = (LocalService.LocalBinder) s;
@@ -174,14 +141,13 @@
             mAccSelected.addObserver(mAccountObserver);
             getSupportActionBar().setTitle(mAccSelected.getAlias());
 
-            final ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
+            mViewPager = (ViewPager) findViewById(R.id.pager);
             mViewPager.setOffscreenPageLimit(4);
             mViewPager.setAdapter(new PreferencesPagerAdapter(getFragmentManager(), AccountEditionActivity.this, mAccSelected.isRing()));
 
             final PagerSlidingTabStrip mSlidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tabs);
             mSlidingTabLayout.setViewPager(mViewPager);
 
-
             for (AccountChangedListener listener : listeners) {
                 listener.accountChanged(mAccSelected);
             }
@@ -210,6 +176,13 @@
 
                 }
             });
+
+            if (mAccSelected.isRing()) {
+                mSlidingTabLayout.setVisibility(View.GONE);
+                mViewPager.setVisibility(View.GONE);
+                mCurrentlyDisplayed = new DeviceAccountFragment();
+                getFragmentManager().beginTransaction().add(R.id.fragment_container, mCurrentlyDisplayed).commit();
+            }
         }
 
         @Override
@@ -229,12 +202,30 @@
         setSupportActionBar(toolbar);
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
+        mViewPager = (ViewPager) findViewById(R.id.pager);
+        mSlidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tabs);
+
         if (!mBound) {
             Intent intent = new Intent(this, LocalService.class);
             bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
         }
     }
 
+
+    public void editAdvanced() {
+        mSlidingTabLayout.setVisibility(View.VISIBLE);
+        mViewPager.setVisibility(View.VISIBLE);
+    }
+
+    private void finishAdvanced() {
+        mSlidingTabLayout.setVisibility(View.GONE);
+        mViewPager.setVisibility(View.GONE);
+    }
+
+    private boolean isAdvancedSettings() {
+        return mSlidingTabLayout.getVisibility() == View.VISIBLE;
+    }
+
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
@@ -257,7 +248,9 @@
 
     @Override
     public void onBackPressed() {
-        if (!(mCurrentlyDisplayed instanceof BackHandlerInterface) || !((BackHandlerInterface) mCurrentlyDisplayed).onBackPressed()) {
+        if (isAdvancedSettings()) {
+            finishAdvanced();
+        } else if (!(mCurrentlyDisplayed instanceof BackHandlerInterface) || !((BackHandlerInterface) mCurrentlyDisplayed).onBackPressed()) {
             super.onBackPressed();
         }
     }
@@ -330,6 +323,37 @@
     }
 
     @Override
+    public void saveAccount() {
+        if (mAccSelected == null || mService == null) {
+            return;
+        }
+
+        final Account account = mAccSelected;
+        if (getSupportActionBar() != null) {
+            getSupportActionBar().setTitle(account.getAlias());
+        }
+
+        final IDRingService remote = getRemoteService();
+        if (remote == null) {
+            Log.w(TAG, "Error updating account, remote service is null");
+            return;
+        }
+
+        mService.getThreadPool().submit(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Log.i(TAG, "updating account");
+                    remote.setCredentials(account.getAccountID(), account.getCredentialsHashMapList());
+                    remote.setAccountDetails(account.getAccountID(), account.getDetails());
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Exception updating account", e);
+                }
+            }
+        });
+    }
+
+    @Override
     public IDRingService getRemoteService() {
         return mService.getRemoteService();
     }
@@ -356,8 +380,6 @@
 
     private static class PreferencesPagerAdapter extends FragmentPagerAdapter {
         boolean isRing = false;
-        Fragment[] ringFragments = {new DeviceAccountFragment(), new GeneralAccountFragment(), new MediaPreferenceFragment(), new AdvancedAccountFragment()};
-        Fragment[] sipFragments = {new GeneralAccountFragment(), new MediaPreferenceFragment(), new AdvancedAccountFragment(), new SecurityAccountFragment()};
         private Context ctx;
 
         PreferencesPagerAdapter(FragmentManager fm, Context c, boolean ring) {
@@ -366,6 +388,53 @@
             isRing = ring;
         }
 
+        @Override
+        public int getCount() {
+            return isRing ? 3 : 4;
+        }
+
+        @Override
+        public Fragment getItem(int position) {
+            return isRing ? getRingPanel(position) : getSIPPanel(position);
+        }
+
+        @Override
+        public CharSequence getPageTitle(int position) {
+            int resId = isRing ? getRingPanelTitle(position) : getSIPPanelTitle(position);
+            return ctx.getString(resId);
+        }
+
+        private static Fragment getRingPanel(int position) {
+            Log.i(TAG, "PreferencesPagerAdapter getFragment " + position);
+            switch (position) {
+                case 0:
+                    return new GeneralAccountFragment();
+                case 1:
+                    return new MediaPreferenceFragment();
+                case 2:
+                    return new AdvancedAccountFragment();
+                default:
+                    return null;
+            }
+        }
+
+        private static Fragment getSIPPanel(int position) {
+            Log.i(TAG, "PreferencesPagerAdapter getFragment " + position);
+            switch (position) {
+                case 0:
+                    return new GeneralAccountFragment();
+                case 1:
+                    return new MediaPreferenceFragment();
+                case 2:
+                    return new AdvancedAccountFragment();
+                case 3:
+                    return new SecurityAccountFragment();
+                default:
+                    return null;
+            }
+        }
+
+        @StringRes
         private static int getRingPanelTitle(int position) {
             switch (position) {
                 case 0:
@@ -381,6 +450,7 @@
             }
         }
 
+        @StringRes
         private static int getSIPPanelTitle(int position) {
             switch (position) {
                 case 0:
@@ -395,63 +465,5 @@
                     return -1;
             }
         }
-
-        @Override
-        public int getCount() {
-            // For now we have 4 panels in each account type (Ring/SIP), but it may change
-            return isRing ? ringFragments.length : sipFragments.length;
-        }
-
-        @Override
-        public Fragment getItem(int position) {
-            return isRing ? getRingPanel(position) : getSIPPanel(position);
-        }
-
-        @Override
-        public CharSequence getPageTitle(int position) {
-            int resId = isRing ? getRingPanelTitle(position) : getSIPPanelTitle(position);
-            return ctx.getString(resId);
-        }
-
-        private Fragment getRingPanel(int position) {
-            Log.i(TAG, "PreferencesPagerAdapter getFragment " + position);
-            return ringFragments[position];
-        }
-
-        private Fragment getSIPPanel(int position) {
-            Log.i(TAG, "PreferencesPagerAdapter getFragment " + position);
-            return sipFragments[position];
-        }
     }
-
-    @Override
-    public void saveAccount() {
-        if (mAccSelected == null || mService == null) {
-            return;
-        }
-
-        final Account account = mAccSelected;
-        if (getSupportActionBar() != null) {
-            getSupportActionBar().setTitle(account.getAlias());
-        }
-
-        final IDRingService remote = getRemoteService();
-        if (remote == null) {
-            Log.w(TAG, "Error updating account, remote service is null");
-            return;
-        }
-        mService.getThreadPool().submit(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    Log.w(TAG, "updating account");
-                    remote.setCredentials(account.getAccountID(), account.getCredentialsHashMapList());
-                    remote.setAccountDetails(account.getAccountID(), account.getDetails());
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Exception updating account", e);
-                }
-            }
-        });
-    }
-
 }
diff --git a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
index a2c897e..3f69ef7 100644
--- a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
+++ b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java
@@ -21,40 +21,52 @@
 
 package cx.ring.client;
 
-import android.app.Fragment;
+import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.ProgressDialog;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.support.v13.app.FragmentStatePagerAdapter;
-import android.support.v4.view.ViewPager;
+import android.os.RemoteException;
+import android.support.v4.content.ContextCompat;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.Toolbar;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.MenuItem;
+import android.widget.Toast;
 
-import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import cx.ring.R;
 import cx.ring.fragments.AccountCreationFragment;
 import cx.ring.fragments.AccountMigrationFragment;
+import cx.ring.fragments.RingAccountCreationFragment;
+import cx.ring.fragments.RingAccountLoginFragment;
+import cx.ring.model.account.Account;
+import cx.ring.model.account.AccountConfig;
+import cx.ring.model.account.ConfigKey;
 import cx.ring.service.IDRingService;
 import cx.ring.service.LocalService;
 
 public class AccountWizard extends AppCompatActivity implements LocalService.Callbacks {
     static final String TAG = AccountWizard.class.getName();
     private boolean mBound = false;
-    private LocalService service;
-
-    @BindView(R.id.pager)
-    ViewPager mViewPager;
+    private LocalService mService;
+    private boolean mCreatingAccount = false;
 
     @BindView(R.id.main_toolbar)
     Toolbar mToolbar;
@@ -63,7 +75,7 @@
 
         @Override
         public void onServiceConnected(ComponentName className, IBinder binder) {
-            service = ((LocalService.LocalBinder) binder).getService();
+            mService = ((LocalService.LocalBinder) binder).getService();
             mBound = true;
         }
 
@@ -83,21 +95,13 @@
         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
         getSupportActionBar().setHomeButtonEnabled(true);
 
-        if (getIntent().getData() != null && !TextUtils.isEmpty(getIntent().getData().getLastPathSegment())) {
-            String accountId = getIntent().getData().getLastPathSegment();
-            SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager(), accountId);
-            mViewPager.setAdapter(mSectionsPagerAdapter);
-        } else {
-            SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(AccountWizard.this, getFragmentManager());
-            mViewPager.setAdapter(mSectionsPagerAdapter);
-        }
-
         if (!mBound) {
             Log.i(TAG, "onCreate: Binding service...");
             Intent intent = new Intent(this, LocalService.class);
             bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
         }
 
+        ringChoose();
     }
 
     @Override
@@ -119,11 +123,11 @@
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
-        case android.R.id.home:
-            checkAccountPresence();
-            return true;
-        default:
-            return super.onOptionsItemSelected(item);
+            case android.R.id.home:
+                checkAccountPresence();
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
         }
     }
 
@@ -132,63 +136,221 @@
      * If not, exit the app
      */
     private void checkAccountPresence() {
-        if (mBound && !service.getAccounts().isEmpty()) {
-            finish();
+        if (mBound && !mService.getAccounts().isEmpty()) {
+            FragmentManager fm = getFragmentManager();
+            if (fm.getBackStackEntryCount() >= 1) {
+                fm.popBackStack();
+            } else {
+                finish();
+            }
         } else {
-            service.stopSelf();
+            mService.stopSelf();
             finishAffinity();
         }
     }
 
     @Override
     public void onBackPressed() {
-        checkAccountPresence();
+        FragmentManager fm = getFragmentManager();
+        if (fm.getBackStackEntryCount() >= 1) {
+            fm.popBackStack();
+            return;
+        }
+        super.onBackPressed();
     }
 
-    public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
-        private final ArrayList<Fragment> fragments;
-        private final String mAccountId;
+    @SuppressWarnings("unchecked")
+    public void initAccountCreation(boolean isRingAccount, String newUsername, String pin, String password, String host) {
+        final String accountType = isRingAccount ? AccountConfig.ACCOUNT_TYPE_RING : AccountConfig.ACCOUNT_TYPE_SIP;
 
-        SectionsPagerAdapter(Context c, FragmentManager fm) {
-            this(fm, null);
-        }
-
-        SectionsPagerAdapter(FragmentManager fm, String accountId) {
-            super(fm);
-            fragments = new ArrayList<>();
-            mAccountId = accountId;
-
-            if (TextUtils.isEmpty(mAccountId)) {
-                fragments.add(new AccountCreationFragment());
-            } else {
-                AccountMigrationFragment fragment = new AccountMigrationFragment();
-                // give the installation id to display
-                Bundle bundle = new Bundle();
-                bundle.putString(AccountMigrationFragment.ACCOUNT_ID, mAccountId);
-                fragment.setArguments(bundle);
-                fragments.add(fragment);
+        try {
+            HashMap<String, String> accountDetails = (HashMap<String, String>) mService.getRemoteService().getAccountTemplate(accountType);
+            for (Map.Entry<String, String> e : accountDetails.entrySet()) {
+                Log.d(TAG, "Default account detail: " + e.getKey() + " -> " + e.getValue());
             }
+            //~ Checking the state of the Camera permission to enable Video or not.
+            boolean hasCameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
+            accountDetails.put(ConfigKey.VIDEO_ENABLED.key(), Boolean.toString(hasCameraPermission));
+
+            //~ Sipinfo is forced for any sipaccount since overrtp is not supported yet.
+            //~ This will have to be removed when it will be supported.
+            accountDetails.put(ConfigKey.ACCOUNT_DTMF_TYPE.key(), getString(R.string.account_sip_dtmf_type_sipinfo));
+
+            if (isRingAccount) {
+                accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), "Ring");
+                accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), "bootstrap.ring.cx");
+                if (newUsername != null && !newUsername.isEmpty()) {
+                    accountDetails.put(ConfigKey.ACCOUNT_REGISTERED_NAME.key(), newUsername);
+                }
+                if (password != null && !password.isEmpty()) {
+                    accountDetails.put(ConfigKey.ARCHIVE_PASSWORD.key(), password);
+                }
+                if (pin != null && !pin.isEmpty()) {
+                    accountDetails.put(ConfigKey.ARCHIVE_PIN.key(), pin);
+                }
+                // Enable UPNP by default for Ring accounts
+                accountDetails.put(ConfigKey.ACCOUNT_UPNP_ENABLE.key(), AccountConfig.TRUE_STR);
+                createNewAccount(accountDetails, newUsername);
+            } else {
+                accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), newUsername);
+                if (!TextUtils.isEmpty(host)) {
+                    accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), host);
+                    accountDetails.put(ConfigKey.ACCOUNT_USERNAME.key(), newUsername);
+                    accountDetails.put(ConfigKey.ACCOUNT_PASSWORD.key(), password);
+                }
+                createNewAccount(accountDetails, null);
+            }
+
+        } catch (RemoteException e) {
+            Toast.makeText(this, "Error creating account", Toast.LENGTH_SHORT).show();
+            Log.e(TAG, "Error creating account", e);
+        }
+
+    }
+
+    public void ringChoose() {
+        boolean migrate = getIntent().getData() != null && !TextUtils.isEmpty(getIntent().getData().getLastPathSegment());
+
+        FragmentManager fragmentManager = getFragmentManager();
+        fragmentManager
+                .beginTransaction()
+                .replace(R.id.fragment_container, migrate ? new AccountMigrationFragment() : new AccountCreationFragment())
+                .commit();
+    }
+
+    public void ringCreate(boolean switchFragment) {
+        FragmentManager fragmentManager = getFragmentManager();
+        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+        if (!switchFragment) {
+            fragmentTransaction.addToBackStack(null);
+        }
+        fragmentTransaction
+                .replace(R.id.fragment_container, new RingAccountCreationFragment())
+                .commit();
+    }
+
+    public void ringLogin(boolean switchFragment) {
+        FragmentManager fragmentManager = getFragmentManager();
+        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+        if (!switchFragment) {
+            fragmentTransaction.addToBackStack(null);
+        }
+        fragmentTransaction
+                .replace(R.id.fragment_container, new RingAccountLoginFragment())
+                .commit();
+    }
+
+    private class CreateAccountTask extends AsyncTask<HashMap<String, String>, Void, String> {
+        private ProgressDialog progress = null;
+        private final String username;
+        private final Context ctx;
+
+        CreateAccountTask(String registerUsername, Context c) {
+            Log.d(TAG, "CreateAccountTask ");
+            username = registerUsername;
+            ctx = c;
         }
 
         @Override
-        public Fragment getItem(int i) {
-            return fragments.get(i);
+        protected void onPreExecute() {
+            progress = new ProgressDialog(ctx);
+            progress.setTitle(R.string.dialog_wait_create);
+            progress.setMessage(ctx.getString(R.string.dialog_wait_create_details));
+            progress.setCancelable(false);
+            progress.setCanceledOnTouchOutside(false);
+            progress.show();
         }
 
+        @SafeVarargs
         @Override
-        public int getCount() {
-            return 1;
+        protected final String doInBackground(HashMap<String, String>... accs) {
+            final Account account = mService.createAccount(accs[0]);
+            account.stateListener = new Account.OnStateChangedListener() {
+                @Override
+                public void stateChanged(String state, int code) {
+                    Log.i(TAG, "stateListener -> stateChanged " + state + " " + code);
+                    if (!AccountConfig.STATE_INITIALIZING.contentEquals(state)) {
+                        account.stateListener = null;
+                        if (progress != null) {
+                            if (progress.isShowing()) {
+                                progress.dismiss();
+                            }
+                            progress = null;
+                        }
+                        //Intent resultIntent = new Intent();
+                        AlertDialog.Builder dialog = new AlertDialog.Builder(ctx);
+                        dialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int id) {
+                                //do things
+                            }
+                        });
+                        boolean success = false;
+                        switch (state) {
+                            case AccountConfig.STATE_ERROR_GENERIC:
+                                dialog.setTitle(R.string.account_cannot_be_found_title)
+                                        .setMessage(R.string.account_cannot_be_found_message);
+                                break;
+                            case AccountConfig.STATE_ERROR_NETWORK:
+                                dialog.setTitle(R.string.account_no_network_title)
+                                        .setMessage(R.string.account_no_network_message);
+                                break;
+                            default:
+                                dialog.setTitle(R.string.account_device_added_title)
+                                        .setMessage(R.string.account_device_added_message);
+                                success = true;
+                                break;
+                        }
+                        AlertDialog alertDialog = dialog.show();
+                        if (success) {
+                            if (!TextUtils.isEmpty(username)) {
+                                Log.i(TAG, "Account created, registering " + username);
+                                mService.registerName(account, "", username, new LocalService.NameRegistrationCallback() {
+                                    @Override
+                                    public void onRegistered(String name) {
+                                        Log.i(TAG, "Account wizard, onRegistered " + name);
+                                    }
+
+                                    @Override
+                                    public void onError(String name, CharSequence err) {
+                                        Log.w(TAG, "Account wizard, onError " + name);
+                                    }
+                                });
+                            }
+
+                            alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                                @Override
+                                public void onDismiss(DialogInterface dialogInterface) {
+                                    setResult(Activity.RESULT_OK, new Intent());
+                                    finish();
+                                }
+                            });
+                        }
+                    }
+                }
+            };
+            return account.getAccountID();
         }
     }
 
+    private void createNewAccount(HashMap<String, String> accountDetails, String registerName) {
+        if (mCreatingAccount) {
+            return;
+        }
+
+        mCreatingAccount = true;
+
+        //noinspection unchecked
+        new CreateAccountTask(registerName, this).execute(accountDetails);
+    }
+
     @Override
     public IDRingService getRemoteService() {
-        return service.getRemoteService();
+        return mService.getRemoteService();
     }
 
     @Override
     public LocalService getService() {
-        return service;
+        return mService;
     }
 
 }
diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
index 7be2dfc..c7a480a 100644
--- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
@@ -467,7 +467,7 @@
             fContent = fragmentManager.findFragmentById(R.id.main_frame);
             if (fContent == null) {
                 fContent = new SmartListFragment();
-                fragmentManager.beginTransaction().replace(R.id.main_frame, fContent, HOME_TAG).commitAllowingStateLoss();
+                fragmentManager.beginTransaction().replace(R.id.main_frame, fContent, HOME_TAG).addToBackStack(HOME_TAG).commitAllowingStateLoss();
             } else if (fContent instanceof Refreshable) {
                 fragmentManager.beginTransaction().replace(R.id.main_frame, fContent).addToBackStack(HOME_TAG).commit();
                 ((Refreshable) fContent).refresh();
@@ -673,7 +673,7 @@
     }
 
     private void setVideoEnabledFromPermission() {
-        //~ Setting correct AccountDetailBasic.CONFIG_VIDEO_ENABLED value based on the state of the
+        //~ Setting correct VIDEO_ENABLED value based on the state of the
         //~ permission. It can handle the case where the user decides to remove a permission from
         //~ the Android general settings.
         if (!LocalService.checkPermission(this, Manifest.permission.CAMERA) && service != null) {
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
index 1f884f4..d39d29a 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/AccountCreationFragment.java
@@ -20,7 +20,6 @@
 
 package cx.ring.fragments;
 
-import android.Manifest;
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -42,7 +41,6 @@
 import android.provider.MediaStore;
 import android.provider.OpenableColumns;
 import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
 import android.support.v7.app.AppCompatActivity;
 import android.text.TextUtils;
 import android.util.Log;
@@ -50,8 +48,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.LinearLayout;
@@ -64,17 +60,13 @@
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.Writer;
-import java.util.HashMap;
 
 import butterknife.BindView;
 import butterknife.ButterKnife;
 import butterknife.OnClick;
 import butterknife.OnEditorAction;
-import butterknife.OnFocusChange;
 import cx.ring.R;
-import cx.ring.model.account.Account;
-import cx.ring.model.account.AccountConfig;
-import cx.ring.model.account.ConfigKey;
+import cx.ring.client.AccountWizard;
 import cx.ring.service.LocalService;
 
 public class AccountCreationFragment extends Fragment {
@@ -88,18 +80,9 @@
     private String mHostname;
     private String mUsername;
     private String mPassword;
-    private String mAccountType;
 
     private String mDataPath;
     private LocalService.Callbacks mCallbacks = LocalService.DUMMY_CALLBACKS;
-    private CreateAccountTask mAccountTask;
-
-    // UI references.
-    @BindView(R.id.addAccountLayout)
-    LinearLayout mAddAccountLayout;
-
-    @BindView(R.id.newAccountLayout)
-    LinearLayout mNewAccountLayout;
 
     @BindView(R.id.sipFormLinearLayout)
     LinearLayout mSipFormLinearLayout;
@@ -122,34 +105,6 @@
     @BindView(R.id.create_sip_button)
     Button mCreateSIPAccountButton;
 
-    @BindView(R.id.ring_password)
-    EditText mRingPassword;
-
-    @BindView(R.id.ring_password_repeat)
-    EditText mRingPasswordRepeat;
-
-    @BindView(R.id.ring_add_pin)
-    EditText mRingPin;
-
-    @BindView(R.id.ring_add_password)
-    EditText mRingAddPassword;
-
-    private void flipForm(boolean addAccount, boolean newAccount) {
-        mAddAccountLayout.setVisibility(addAccount ? View.VISIBLE : View.GONE);
-        mNewAccountLayout.setVisibility(newAccount ? View.VISIBLE : View.GONE);
-        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
-        if (newAccount) {
-            mRingPassword.requestFocus();
-            imm.showSoftInput(mRingPassword, InputMethodManager.SHOW_IMPLICIT);
-        } else if (addAccount) {
-            mRingPin.requestFocus();
-            imm.showSoftInput(mRingPin, InputMethodManager.SHOW_IMPLICIT);
-        }
-        if (addAccount || newAccount) {
-            mSipFormLinearLayout.setVisibility(View.GONE);
-        }
-    }
-
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
         final View inflatedView = inflater.inflate(R.layout.frag_account_creation, parent, false);
@@ -160,29 +115,6 @@
         return inflatedView;
     }
 
-    private boolean checkPassword(@NonNull TextView pwd, TextView confirm) {
-        boolean error = false;
-        if (pwd.getText().length() == 0) {
-            error = true;
-        } else {
-            if (pwd.getText().length() < 6) {
-                pwd.setError(getString(R.string.error_password_char_count));
-                error = true;
-            } else {
-                pwd.setError(null);
-            }
-        }
-        if (confirm != null) {
-            if (!pwd.getText().toString().equals(confirm.getText().toString())) {
-                confirm.setError(getString(R.string.error_passwords_not_equals));
-                error = true;
-            } else {
-                confirm.setError(null);
-            }
-        }
-        return error;
-    }
-
     @OnEditorAction(R.id.password)
     @SuppressWarnings("unused")
     public boolean keyPressedOnPasswordField(TextView v, int actionId, KeyEvent event) {
@@ -194,73 +126,20 @@
         return true;
     }
 
-    /***********************
-     * Ring Account Creation
-     ***********************/
-    @OnEditorAction(R.id.ring_password)
-    @SuppressWarnings("unused")
-    public boolean keyPressedOnRingPasswordField(TextView v, int actionId, KeyEvent event) {
-        if (actionId == EditorInfo.IME_ACTION_NEXT) {
-            return checkPassword(v, null);
-        }
-        return false;
-    }
-
-    @OnFocusChange(R.id.ring_password)
-    @SuppressWarnings("unused")
-    public void onFocusChangeOnPasswordField(TextView v, boolean hasFocus) {
-        if (!hasFocus) {
-            checkPassword(v, null);
-        }
-    }
-
-    @OnEditorAction(R.id.ring_password_repeat)
-    @SuppressWarnings("unused")
-    public boolean keyPressedOnPasswordRepeatField(TextView v, int actionId, KeyEvent event) {
-        if (actionId == EditorInfo.IME_ACTION_DONE) {
-            if (mRingPassword.getText().length() != 0 && !checkPassword(mRingPassword, v)) {
-                createRingAccount();
-                return true;
-            }
-        }
-        return false;
-    }
-
     @OnClick(R.id.ring_create_btn)
     public void createRingAccount() {
-        if (mNewAccountLayout.getVisibility() == View.GONE) {
-            flipForm(false, true);
-        } else {
-            if (!checkPassword(mRingPassword, mRingPasswordRepeat)) {
-                mAccountType = AccountConfig.ACCOUNT_TYPE_RING;
-                mUsername = mAlias;
-                initAccountCreation(null, mRingPassword.getText().toString());
-            }
+        AccountWizard accountWizard = (AccountWizard) getActivity();
+        if (accountWizard != null) {
+            accountWizard.ringCreate(false);
         }
     }
 
-    /************************
-     * Ring Account ADD
-     ***********************/
-    @OnEditorAction(R.id.ring_add_password)
-    @SuppressWarnings("unused")
-    public boolean keyPressedOnPasswordAddField(TextView v, int actionId, KeyEvent event) {
-        if (actionId == EditorInfo.IME_ACTION_DONE) {
-            addRingAccount();
-            return true;
-        }
-        return false;
-    }
-
     @OnClick(R.id.ring_add_account)
     @SuppressWarnings("unused")
     public void addRingAccount() {
-        if (mAddAccountLayout.getVisibility() == View.GONE) {
-            flipForm(true, false);
-        } else if (mRingPin.getText().length() != 0 && mRingAddPassword.getText().length() != 0) {
-            mAccountType = AccountConfig.ACCOUNT_TYPE_RING;
-            mUsername = mAlias;
-            initAccountCreation(mRingPin.getText().toString(), mRingAddPassword.getText().toString());
+        AccountWizard accountWizard = (AccountWizard) getActivity();
+        if (accountWizard != null) {
+            accountWizard.ringLogin(false);
         }
     }
 
@@ -269,7 +148,6 @@
      ***********************/
     @OnClick(R.id.create_sip_button)
     public void createSIPAccount() {
-        mAccountType = AccountConfig.ACCOUNT_TYPE_SIP;
         mAlias = mAliasView.getText().toString();
         mHostname = mHostnameView.getText().toString();
         mUsername = mUsernameView.getText().toString();
@@ -297,7 +175,6 @@
     public void onClickHeader(View v) {
         if (null != mSipFormLinearLayout) {
             if (mSipFormLinearLayout.getVisibility() != View.VISIBLE) {
-                flipForm(false, false);
                 mSipFormLinearLayout.setVisibility(View.VISIBLE);
                 //~ Let the time to perform setVisibility before scrolling.
                 mSIPLoginForm.postDelayed(new Runnable() {
@@ -562,7 +439,6 @@
         return alertDialog;
     }
 
-
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@@ -672,7 +548,10 @@
         } else if (warningIPAccount) {
             showIP2IPDialog();
         } else {
-            initAccountCreation(null, null);
+            AccountWizard accountWizard = (AccountWizard) getActivity();
+            if (accountWizard != null) {
+                accountWizard.initAccountCreation(false, mUsernameView.getText().toString(), null, mPasswordView.getText().toString(), mHostnameView.getText().toString());
+            }
         }
     }
 
@@ -683,7 +562,9 @@
                 .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int whichButton) {
-                        initAccountCreation(null, null);
+                        AccountWizard a = (AccountWizard) getActivity();
+                        if (a != null)
+                            a.initAccountCreation(false, mAliasView.getText().toString(), null, null, null);
                     }
                 })
                 .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@@ -694,137 +575,4 @@
                 })
                 .create().show();
     }
-
-    @SuppressWarnings("unchecked")
-    private void initAccountCreation(String pin, String password) {
-        try {
-            HashMap<String, String> accountDetails = (HashMap<String, String>) mCallbacks.getRemoteService().getAccountTemplate(mAccountType);
-            accountDetails.put(ConfigKey.ACCOUNT_TYPE.key(), mAccountType);
-            //~ Checking the state of the Camera permission to enable Video or not.
-            boolean hasCameraPermission = ContextCompat.checkSelfPermission(getActivity(),
-                    Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
-            accountDetails.put(ConfigKey.VIDEO_ENABLED.key(), Boolean.toString(hasCameraPermission));
-
-            //~ Sipinfo is forced for any sipaccount since overrtp is not supported yet.
-            //~ This will have to be removed when it will be supported.
-            accountDetails.put(ConfigKey.ACCOUNT_DTMF_TYPE.key(), getString(R.string.account_sip_dtmf_type_sipinfo));
-
-            if (mAccountType.equals(AccountConfig.ACCOUNT_TYPE_RING)) {
-                accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), "Ring");
-                accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), "bootstrap.ring.cx");
-                if (password != null && !password.isEmpty()) {
-                    accountDetails.put(ConfigKey.ARCHIVE_PASSWORD.key(), password);
-                }
-                if (pin != null && !pin.isEmpty()) {
-                    accountDetails.put(ConfigKey.ARCHIVE_PIN.key(), pin);
-                }
-                // Enable UPNP by default for Ring accounts
-                accountDetails.put(ConfigKey.ACCOUNT_UPNP_ENABLE.key(), AccountConfig.TRUE_STR);
-                createNewAccount(accountDetails);
-            } else {
-                accountDetails.put(ConfigKey.ACCOUNT_ALIAS.key(), mAlias);
-                if (!TextUtils.isEmpty(mHostname)) {
-                    accountDetails.put(ConfigKey.ACCOUNT_HOSTNAME.key(), mHostname);
-                    accountDetails.put(ConfigKey.ACCOUNT_USERNAME.key(), mUsername);
-                    accountDetails.put(ConfigKey.ACCOUNT_PASSWORD.key(), mPassword);
-                }
-                createNewAccount(accountDetails);
-            }
-
-        } catch (RemoteException e) {
-            Toast.makeText(getActivity(), R.string.account_creation_error, Toast.LENGTH_SHORT).show();
-            Log.d(TAG, "Error while creating account", e);
-        }
-
-    }
-
-    private class CreateAccountTask extends AsyncTask<HashMap<String, String>, Void, String> {
-        private ProgressDialog progress = null;
-
-        @Override
-        protected void onPreExecute() {
-            progress = new ProgressDialog(getActivity());
-            progress.setTitle(R.string.dialog_wait_create);
-            progress.setMessage(getString(R.string.dialog_wait_create_details));
-            progress.setCancelable(false);
-            progress.setCanceledOnTouchOutside(false);
-            progress.show();
-        }
-
-        @Override
-        protected void onPostExecute(String s) {
-            super.onPostExecute(s);
-            mAccountTask = null;
-        }
-
-        @SafeVarargs
-        @Override
-        protected final String doInBackground(HashMap<String, String>... accounts) {
-            final Account account = mCallbacks.getService().createAccount(accounts[0]);
-            account.stateListener = new Account.OnStateChangedListener() {
-                @Override
-                public void stateChanged(String state, int code) {
-                    if (!AccountConfig.STATE_INITIALIZING.contentEquals(state)) {
-                        account.stateListener = null;
-                        if (progress != null) {
-                            if (progress.isShowing()) {
-                                progress.dismiss();
-                            }
-                            progress = null;
-                        }
-
-                        if (account.isSip()) {
-                            getActivity().setResult(Activity.RESULT_OK, new Intent());
-                            getActivity().finish();
-                            return;
-                        }
-
-                        AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
-                        dialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int id) {
-                                //do things
-                            }
-                        });
-                        boolean success = false;
-                        switch (state) {
-                            case AccountConfig.STATE_ERROR_GENERIC:
-                                dialog.setTitle(R.string.account_cannot_be_found_title)
-                                        .setMessage(R.string.account_cannot_be_found_message);
-                                break;
-                            case AccountConfig.STATE_ERROR_NETWORK:
-                                dialog.setTitle(R.string.account_no_network_title)
-                                        .setMessage(R.string.account_no_network_message);
-                                break;
-                            default:
-                                dialog.setTitle(R.string.account_device_added_title)
-                                        .setMessage(R.string.account_device_added_message);
-                                success = true;
-                                break;
-                        }
-                        AlertDialog d = dialog.show();
-                        if (success) {
-                            d.setOnDismissListener(new DialogInterface.OnDismissListener() {
-                                @Override
-                                public void onDismiss(DialogInterface dialogInterface) {
-                                    getActivity().setResult(Activity.RESULT_OK, new Intent());
-                                    getActivity().finish();
-                                }
-                            });
-                        }
-                    }
-                }
-            };
-            return account.getAccountID();
-        }
-    }
-
-    private void createNewAccount(HashMap<String, String> accountDetails) {
-        if (mAccountTask != null) {
-            return;
-        }
-
-        //noinspection unchecked
-        mAccountTask = new CreateAccountTask();
-        mAccountTask.execute(accountDetails);
-    }
 }
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/DeviceAccountFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/DeviceAccountFragment.java
index 37673ae..09f519f 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/DeviceAccountFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/DeviceAccountFragment.java
@@ -55,18 +55,22 @@
 import butterknife.ButterKnife;
 import butterknife.OnClick;
 import butterknife.OnEditorAction;
-
 import cx.ring.R;
+import cx.ring.client.AccountEditionActivity;
 import cx.ring.interfaces.AccountCallbacks;
 import cx.ring.interfaces.AccountChangedListener;
 import cx.ring.interfaces.BackHandlerInterface;
 import cx.ring.model.account.Account;
+import cx.ring.model.account.ConfigKey;
+import cx.ring.service.LocalService;
 import cx.ring.utils.KeyboardVisibilityManager;
 import cx.ring.views.LinkNewDeviceLayout;
 
 import static cx.ring.client.AccountEditionActivity.DUMMY_CALLBACKS;
 
-public class DeviceAccountFragment extends Fragment implements AccountChangedListener, BackHandlerInterface {
+public class DeviceAccountFragment extends Fragment implements AccountChangedListener,
+        BackHandlerInterface,
+        RegisterNameDialog.RegisterNameDialogListener {
 
     private static final String TAG = DeviceAccountFragment.class.getSimpleName();
 
@@ -88,6 +92,30 @@
     @BindView(R.id.account_link_info)
     TextView mExportInfos;
 
+    @BindView(R.id.account_edit_btn)
+    View mEditBtn;
+
+    @BindView(R.id.account_alias_txt)
+    TextView mAccountNameTxt;
+
+    @BindView(R.id.account_id_txt)
+    TextView mAccountIdTxt;
+
+    @BindView(R.id.registered_name_txt)
+    TextView mAccountUsernameTxt;
+
+    @BindView(R.id.register_name_btn)
+    Button mRegisterNameBtn;
+
+    @BindView(R.id.group_registering_name)
+    ViewGroup registeringNameGroup;
+
+    @BindView(R.id.group_register_name)
+    ViewGroup mRegisterNameGroup;
+
+    @BindView(R.id.group_registered_name)
+    ViewGroup mRegisteredNameGroup;
+
     @BindView(R.id.device_list)
     ListView mDeviceList;
 
@@ -99,24 +127,6 @@
     private AccountCallbacks mCallbacks = DUMMY_CALLBACKS;
     private DeviceAdapter mDeviceAdapter;
 
-    /*
-    Fragment LifeCycle
-     */
-    @Nullable
-    @Override
-    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        ViewGroup devLayout = (ViewGroup) inflater.inflate(R.layout.frag_device_list, container, false);
-
-        ButterKnife.bind(this, devLayout);
-
-        Account account = mCallbacks.getAccount();
-        if (account != null) {
-            accountChanged(account);
-        }
-        mLinkAccountView.setContainer(this);
-        hidePopWizard();
-        return devLayout;
-    }
 
     @Override
     public void onAttach(Activity activity) {
@@ -144,6 +154,18 @@
     public void accountChanged(Account account) {
         mDeviceAdapter = new DeviceAdapter(getActivity(), account.getDevices());
         mDeviceList.setAdapter(mDeviceAdapter);
+
+        mAccountNameTxt.setText(account.getAlias());
+        mAccountIdTxt.setText(account.getUsername());
+        String username = account.getRegisteredName();
+        boolean currentRegisteredName = account.registeringUsername;
+        boolean hasRegisteredName = !currentRegisteredName && username != null && !username.isEmpty();
+        registeringNameGroup.setVisibility(currentRegisteredName ? View.VISIBLE : View.GONE);
+        mRegisterNameGroup.setVisibility((!hasRegisteredName && !currentRegisteredName) ? View.VISIBLE : View.GONE);
+        mRegisteredNameGroup.setVisibility(hasRegisteredName ? View.VISIBLE : View.GONE);
+        if (hasRegisteredName) {
+            mAccountUsernameTxt.setText(username);
+        }
         account.devicesListener = new Account.OnDevicesChangedListener() {
             @Override
             public void devicesChanged(Map<String, String> devices) {
@@ -159,6 +181,7 @@
     */
     @Override
     public boolean onBackPressed() {
+
         if (isDisplayingWizard()) {
             hideWizard();
             return true;
@@ -251,6 +274,31 @@
         }
     }
 
+    @OnClick(R.id.register_name_btn)
+    public void showUsernameRegistrationPopup() {
+        RegisterNameDialog registrationDialog = new RegisterNameDialog();
+        registrationDialog.setListener(this);
+        registrationDialog.show(getFragmentManager(), TAG);
+    }
+
+    @Override
+    public void onRegisterName(String name, String password) {
+        final Account account = mCallbacks.getAccount();
+        account.setDetail(ConfigKey.ACCOUNT_REGISTERED_NAME, name);
+        mCallbacks.getService().registerName(account, password, name, new LocalService.NameRegistrationCallback() {
+            @Override
+            public void onRegistered(String name) {
+                Log.w(TAG, "Account wizard, onRegistered " + name);
+                mCallbacks.saveAccount();
+            }
+
+            @Override
+            public void onError(String name, CharSequence err) {
+                Log.w(TAG, "Account wizard, onError " + name);
+            }
+        });
+    }
+
     class DeviceAdapter extends BaseAdapter {
         private final Context mCtx;
         private final ArrayList<Map.Entry<String, String>> devices = new ArrayList<>();
@@ -358,4 +406,28 @@
         }
     }
 
+    @Nullable
+    @Override
+    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        if (container == null) return null;
+        ViewGroup devLayout = (ViewGroup) inflater.inflate(R.layout.frag_device_list, container, false);
+
+        ButterKnife.bind(this, devLayout);
+
+        Account account = mCallbacks.getAccount();
+        if (account != null) {
+            accountChanged(account);
+        }
+
+        mLinkAccountView.setContainer(this);
+        hidePopWizard();
+
+        return devLayout;
+    }
+
+    @OnClick(R.id.account_edit_btn)
+    public void editAccount() {
+        ((AccountEditionActivity) getActivity()).editAdvanced();
+    }
+
 }
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/RegisterNameDialog.java b/ring-android/app/src/main/java/cx/ring/fragments/RegisterNameDialog.java
new file mode 100644
index 0000000..39b57a1
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/fragments/RegisterNameDialog.java
@@ -0,0 +1,182 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@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.fragments;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.design.widget.TextInputLayout;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import butterknife.BindString;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnEditorAction;
+import cx.ring.R;
+import cx.ring.service.LocalService;
+import cx.ring.utils.BlockchainUtils;
+
+public class RegisterNameDialog extends DialogFragment {
+    static final String TAG = RegisterNameDialog.class.getSimpleName();
+
+    public interface RegisterNameDialogListener {
+        void onRegisterName(String name, String password);
+    }
+
+    @BindView(R.id.ring_username_txt_box)
+    public TextInputLayout mUsernameTxtBox;
+
+    @BindView(R.id.ring_username)
+    public EditText mUsernameTxt;
+
+    @BindView(R.id.ring_password_txt_box)
+    public TextInputLayout mPasswordTxtBox;
+
+    @BindView(R.id.ring_password_txt)
+    public EditText mPasswordTxt;
+
+    @BindString(R.string.register_name)
+    public String mRegisterTitle;
+
+    @BindString(R.string.register_username)
+    public String mRegisterMessage;
+
+    @BindString(R.string.prompt_new_username)
+    public String mPromptUsername;
+
+    @BindString(R.string.prompt_password)
+    public String mPromptPassword;
+
+    private TextWatcher mUsernameTextWatcher;
+
+    private RegisterNameDialogListener mListener = null;
+
+    void setListener(RegisterNameDialogListener l) {
+        mListener = l;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+        View view = getActivity().getLayoutInflater().inflate(R.layout.frag_register_name, null);
+
+        ButterKnife.bind(this, view);
+
+        BlockchainUtils.attachUsernameTextFilter(mUsernameTxt);
+        mUsernameTextWatcher = BlockchainUtils.attachUsernameTextWatcher((LocalService.Callbacks) getActivity(), mUsernameTxtBox, mUsernameTxt);
+
+        AlertDialog dialog = (AlertDialog) getDialog();
+        if (dialog != null) {
+            dialog.setView(view);
+            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+        }
+
+        builder.setView(view);
+
+        builder.setMessage(mRegisterMessage)
+                .setTitle(mRegisterTitle)
+                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        validate();
+                    }
+                })
+                .setNegativeButton(android.R.string.cancel,
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int whichButton) {
+                        dismiss();
+                    }
+                }
+        );
+
+        return builder.create();
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        if (mUsernameTxt != null) {
+            mUsernameTextWatcher = BlockchainUtils.attachUsernameTextWatcher((LocalService.Callbacks) getActivity(), mUsernameTxtBox, mUsernameTxt);
+        }
+    }
+
+    @Override
+    public void onDetach() {
+        if (mUsernameTxt != null) {
+            mUsernameTxt.removeTextChangedListener(mUsernameTextWatcher);
+        }
+        super.onDetach();
+    }
+
+    public String getUsername() {
+        return mUsernameTxt.getText().toString();
+    }
+
+    public boolean checkInput() {
+        if (mUsernameTxt.getText().toString().isEmpty()) {
+            mUsernameTxtBox.setErrorEnabled(true);
+            mUsernameTxtBox.setError(mPromptUsername);
+            return false;
+        } else {
+            mUsernameTxtBox.setErrorEnabled(false);
+            mUsernameTxtBox.setError(null);
+        }
+        if (mPasswordTxt.getText().toString().isEmpty()) {
+            mPasswordTxtBox.setErrorEnabled(true);
+            mPasswordTxtBox.setError(mPromptPassword);
+            return false;
+        } else {
+            mPasswordTxtBox.setErrorEnabled(false);
+            mPasswordTxtBox.setError(null);
+        }
+        return true;
+    }
+
+    boolean validate() {
+        if (checkInput() && mListener != null) {
+            final String username = mUsernameTxt.getText().toString();
+            final String password = mPasswordTxt.getText().toString();
+            getDialog().dismiss();
+            mListener.onRegisterName(username, password);
+            return true;
+        }
+        return false;
+    }
+
+    @OnEditorAction({R.id.ring_username, R.id.ring_password_txt})
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        if (v == mPasswordTxt) {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                return validate();
+            }
+        }
+        return false;
+    }
+}
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/RingAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/RingAccountCreationFragment.java
new file mode 100644
index 0000000..4b99ce3
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/fragments/RingAccountCreationFragment.java
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2004-2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@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.
+ */
+
+package cx.ring.fragments;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.design.widget.TextInputLayout;
+import android.support.v7.app.ActionBar;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnCheckedChanged;
+import butterknife.OnClick;
+import butterknife.OnEditorAction;
+import butterknife.OnFocusChange;
+import cx.ring.R;
+import cx.ring.client.AccountWizard;
+import cx.ring.service.LocalService;
+import cx.ring.utils.BlockchainUtils;
+
+public class RingAccountCreationFragment extends Fragment {
+    static final String TAG = RingAccountCreationFragment.class.getSimpleName();
+    private static final int PASSWORD_MIN_LENGTH = 6;
+
+    @BindView(R.id.switch_ring_username)
+    Switch mUsernameSwitch;
+
+    @BindView(R.id.ring_username_txt_box)
+    TextInputLayout mUsernameTxtBox;
+
+    @BindView(R.id.ring_username)
+    EditText mUsernameTxt;
+
+    private TextWatcher mUsernameTextWatcher;
+
+    @BindView(R.id.ring_password_txt_box)
+    TextInputLayout mPasswordTxtBox;
+
+    @BindView(R.id.ring_password)
+    EditText mPasswordTxt;
+
+    @BindView(R.id.ring_password_repeat_txt_box)
+    TextInputLayout mPasswordRepeatTxtBox;
+
+    @BindView(R.id.add_button)
+    Button mAddAccountBtn;
+
+    @BindView(R.id.ring_username_box)
+    ViewGroup mUsernameBox;
+
+    private boolean checkPassword(@NonNull TextInputLayout pwd, TextInputLayout confirm) {
+        boolean error = false;
+        pwd.setError(null);
+        if (mUsernameSwitch.isChecked()) {
+            if (mUsernameTxt.getText().toString().isEmpty()) {
+                mUsernameTxtBox.setErrorEnabled(true);
+                mUsernameTxtBox.setError(getString(R.string.error_username_empty));
+                return true;
+            }
+        }
+        if (pwd.getEditText().getText().length() == 0) {
+            error = true;
+        } else {
+            if (pwd.getEditText().getText().length() < PASSWORD_MIN_LENGTH) {
+                pwd.setError(getString(R.string.error_password_char_count));
+                error = true;
+            } else {
+                pwd.setError(null);
+            }
+        }
+        if (confirm != null) {
+            if (!pwd.getEditText().getText().toString().equals(confirm.getEditText().getText().toString())) {
+                confirm.setError(getString(R.string.error_passwords_not_equals));
+                error = true;
+            } else {
+                confirm.setError(null);
+            }
+        }
+        mAddAccountBtn.setEnabled(!error);
+        return error;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
+        final View view = inflater.inflate(R.layout.frag_acc_ring_create, parent, false);
+        ButterKnife.bind(this, view);
+
+        BlockchainUtils.attachUsernameTextFilter(mUsernameTxt);
+
+        if (isAdded()) {
+            mUsernameTextWatcher = BlockchainUtils.attachUsernameTextWatcher((LocalService.Callbacks) getActivity(), mUsernameTxtBox, mUsernameTxt);
+        }
+
+        return view;
+    }
+
+    @OnCheckedChanged(R.id.switch_ring_username)
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        mUsernameBox.setVisibility(isChecked ? View.VISIBLE : View.GONE);
+    }
+
+    @OnEditorAction(R.id.ring_password)
+    public boolean onPasswordEditorAction(TextView view, int actionId, KeyEvent event) {
+        Log.w(TAG, "onEditorAction " + actionId + " " + (event == null ? null : event.toString()));
+        if (actionId == EditorInfo.IME_ACTION_DONE) {
+            if (mPasswordTxt.getText().length() != 0 && !checkPassword(mPasswordTxtBox, mPasswordRepeatTxtBox)) {
+                mAddAccountBtn.callOnClick();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @OnFocusChange(R.id.ring_password)
+    public void onFocusChange(View view, boolean hasFocus) {
+        if (!hasFocus) {
+            checkPassword(mPasswordTxtBox, null);
+        }
+    }
+
+    @OnEditorAction(R.id.ring_password_repeat)
+    public boolean onPasswordRepeatEditorAction(TextView view, int actionId, KeyEvent event) {
+        Log.w(TAG, "onEditorAction " + actionId + " " + (event == null ? null : event.toString()));
+        if (actionId == EditorInfo.IME_ACTION_DONE) {
+            if (mPasswordTxt.getText().length() != 0 && !checkPassword(mPasswordTxtBox, mPasswordRepeatTxtBox)) {
+                mAddAccountBtn.callOnClick();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @OnClick(R.id.add_button)
+    public void onAddButtonClick(View view) {
+        if (!checkPassword(mPasswordTxtBox, mPasswordRepeatTxtBox))
+            ((AccountWizard) getActivity()).initAccountCreation(true, mUsernameTxt.getText().toString(), null, mPasswordTxt.getText().toString(), null);
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        ActionBar ab = ((AccountWizard) activity).getSupportActionBar();
+        if (ab != null) {
+            ab.setTitle(R.string.account_create_title);
+        }
+        if (mUsernameTxt != null) {
+            mUsernameTextWatcher = BlockchainUtils.attachUsernameTextWatcher((LocalService.Callbacks) getActivity(), mUsernameTxtBox, mUsernameTxt);
+        }
+    }
+
+    @Override
+    public void onDetach() {
+        if (mUsernameTxt != null) {
+            mUsernameTxt.removeTextChangedListener(mUsernameTextWatcher);
+        }
+        super.onDetach();
+    }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/RingAccountLoginFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/RingAccountLoginFragment.java
new file mode 100644
index 0000000..d7ca140
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/fragments/RingAccountLoginFragment.java
@@ -0,0 +1,97 @@
+/*
+ *  Copyright (C) 2004-2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@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.
+ */
+
+package cx.ring.fragments;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.v7.widget.AppCompatButton;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import cx.ring.R;
+import cx.ring.client.AccountWizard;
+
+public class RingAccountLoginFragment extends Fragment {
+    static final String TAG = RingAccountLoginFragment.class.getSimpleName();
+
+    @BindView(R.id.ring_add_pin)
+    EditText mPinTxt;
+
+    @BindView(R.id.ring_password)
+    EditText mPasswordTxt;
+
+    @BindView(R.id.link_button)
+    AppCompatButton mLinkAccountBtn;
+
+    void checkNextState() {
+        mLinkAccountBtn.setEnabled(!mPinTxt.getText().toString().isEmpty() && !mPasswordTxt.getText().toString().isEmpty());
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
+        final View view = inflater.inflate(R.layout.frag_acc_ring_login, parent, false);
+
+        ButterKnife.bind(this, view);
+
+        mPinTxt.addTextChangedListener(inputWatcher);
+        mPasswordTxt.addTextChangedListener(inputWatcher);
+
+        checkNextState();
+        return view;
+    }
+
+    @OnClick(R.id.link_button)
+    public void onLinkClick(View view) {
+        ((AccountWizard) getActivity()).initAccountCreation(true, null, mPinTxt.getText().toString(), mPasswordTxt.getText().toString(), null);
+    }
+
+    private final TextWatcher inputWatcher = new TextWatcher() {
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            checkNextState();
+        }
+    };
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        AccountWizard account = (AccountWizard) getActivity();
+        if (account != null) {
+            account.getSupportActionBar().setTitle(R.string.account_import_title);
+        }
+    }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/model/account/Account.java b/ring-android/app/src/main/java/cx/ring/model/account/Account.java
index 7daf2a5..0e078b4 100644
--- a/ring-android/app/src/main/java/cx/ring/model/account/Account.java
+++ b/ring-android/app/src/main/java/cx/ring/model/account/Account.java
@@ -15,8 +15,7 @@
  *  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.
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package cx.ring.model.account;
@@ -29,17 +28,19 @@
 public class Account extends java.util.Observable {
     private static final String TAG = Account.class.getName();
 
-    private final String accountID;
+    private String accountID;
+
     private AccountConfig mVolatileDetails;
     private AccountConfig mDetails;
     private ArrayList<AccountCredentials> credentialsDetails = new ArrayList<>();
-
     private Map<String, String> devices = new HashMap<>();
 
     public OnDevicesChangedListener devicesListener = null;
     public OnExportEndedListener exportListener = null;
     public OnStateChangedListener stateListener = null;
 
+    public boolean registeringUsername = false;
+
     public Account(String bAccountID) {
         accountID = bAccountID;
         mDetails = new AccountConfig();
@@ -170,7 +171,7 @@
     }
 
     public String getRegisteredName() {
-        return mVolatileDetails.get(ConfigKey.ACCOUNT_REGISTRED_NAME);
+        return mVolatileDetails.get(ConfigKey.ACCOUNT_REGISTERED_NAME);
     }
 
     public String getAlias() {
diff --git a/ring-android/app/src/main/java/cx/ring/model/account/ConfigKey.java b/ring-android/app/src/main/java/cx/ring/model/account/ConfigKey.java
index ddcbabe..d44d929 100644
--- a/ring-android/app/src/main/java/cx/ring/model/account/ConfigKey.java
+++ b/ring-android/app/src/main/java/cx/ring/model/account/ConfigKey.java
@@ -78,7 +78,7 @@
     TLS_VERIFY_CLIENT("TLS.verifyClient"),
     TLS_REQUIRE_CLIENT_CERTIFICATE("TLS.requireClientCertificate"),
     TLS_NEGOTIATION_TIMEOUT_SEC("TLS.negotiationTimeoutSec"),
-    ACCOUNT_REGISTRED_NAME("Account.registredName"),
+    ACCOUNT_REGISTERED_NAME("Account.registredName"),
     ACCOUNT_REGISTRATION_STATUS("Account.registrationStatus"),
     ACCOUNT_REGISTRATION_STATE_CODE("Account.registrationCode"),
     ACCOUNT_REGISTRATION_STATE_DESC("Account.registrationDescription"),
diff --git a/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java b/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java
index 5d7353b..dc2a0ff 100644
--- a/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java
+++ b/ring-android/app/src/main/java/cx/ring/service/ConfigurationManagerCallback.java
@@ -38,6 +38,8 @@
     static public final String ACCOUNT_STATE_CHANGED = BuildConfig.APPLICATION_ID + "account.stateChanged";
     static public final String INCOMING_TEXT = BuildConfig.APPLICATION_ID + ".message.incomingTxt";
     static public final String MESSAGE_STATE_CHANGED = BuildConfig.APPLICATION_ID + ".message.stateChanged";
+    static public final String NAME_LOOKUP_ENDED = BuildConfig.APPLICATION_ID + ".name.lookupEnded";
+    static public final String NAME_REGISTRATION_ENDED = BuildConfig.APPLICATION_ID + ".name.registrationEnded";
 
     static public final String MESSAGE_STATE_CHANGED_EXTRA_ID = "id";
     static public final String MESSAGE_STATE_CHANGED_EXTRA_STATUS = "status";
@@ -154,4 +156,26 @@
         intent.putExtra("pin", pin);
         mService.sendBroadcast(intent);
     }
+
+    @Override
+    public void nameRegistrationEnded(String account, int state, String name) {
+        Log.w(TAG, "nameRegistrationEnded: " + account + " " + state + " " + name);
+        Intent intent = new Intent(NAME_REGISTRATION_ENDED);
+        intent.putExtra("account", account);
+        intent.putExtra("state", state);
+        intent.putExtra("name", name);
+        mService.sendBroadcast(intent);
+    }
+
+    @Override
+    public void registeredNameFound(String account, int state, String address, String name) {
+        Log.w(TAG, "registeredNameFound: " + account + " " + state + " " + name + " " + address);
+        Intent intent = new Intent(NAME_LOOKUP_ENDED);
+        intent.putExtra("account", account);
+        intent.putExtra("state", state);
+        intent.putExtra("name", name);
+        intent.putExtra("address", address);
+        mService.sendBroadcast(intent);
+    }
+
 }
diff --git a/ring-android/app/src/main/java/cx/ring/service/DRingService.java b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
index 3ea9992..c9651ac 100644
--- a/ring-android/app/src/main/java/cx/ring/service/DRingService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
@@ -1476,5 +1476,55 @@
                 }
             });
         }
+
+        public void lookupName(final String account, final String nameserver, final String name) {
+            getExecutor().execute(new SipRunnable() {
+                @Override
+                protected void doRun() throws SameThreadException, RemoteException {
+                    Log.i(TAG, "DRingService.lookupName thread running() " + name);
+                    if (!Ringservice.lookupName(account, nameserver, name)) {
+                        Intent intent = new Intent(ConfigurationManagerCallback.NAME_LOOKUP_ENDED);
+                        intent.putExtra("account", account);
+                        intent.putExtra("state", -1);
+                        intent.putExtra("name", name);
+                        sendBroadcast(intent);
+                    }
+                    Log.i(TAG, "DRingService.lookupName DONE " + name);
+                }
+            });
+        }
+
+        public void lookupAddress(final String account, final String nameserver, final String address) {
+            getExecutor().execute(new SipRunnable() {
+                @Override
+                protected void doRun() throws SameThreadException, RemoteException {
+                    Log.i(TAG, "DRingService.lookupAddress thread running() " + address);
+                    if (!Ringservice.lookupAddress(account, nameserver, address)) {
+                        Intent intent = new Intent(ConfigurationManagerCallback.NAME_LOOKUP_ENDED);
+                        intent.putExtra("account", account);
+                        intent.putExtra("state", -1);
+                        intent.putExtra("address", address);
+                        sendBroadcast(intent);
+                    }
+                }
+            });
+        }
+
+        public void registerName(final String account, final String password, final String name) {
+            getExecutor().execute(new SipRunnable() {
+                @Override
+                protected void doRun() throws SameThreadException, RemoteException {
+                    Log.w(TAG, "DRingService.registerName thread running() " + name);
+                    if (!Ringservice.registerName(account, password, name)) {
+                        Intent intent = new Intent(ConfigurationManagerCallback.NAME_REGISTRATION_ENDED);
+                        intent.putExtra("account", account);
+                        intent.putExtra("state", -1);
+                        intent.putExtra("name", name);
+                        sendBroadcast(intent);
+                    }
+                }
+            });
+        }
+
     };
 }
diff --git a/ring-android/app/src/main/java/cx/ring/service/IDRingService.aidl b/ring-android/app/src/main/java/cx/ring/service/IDRingService.aidl
index 0c50e0a..c7bf03b 100644
--- a/ring-android/app/src/main/java/cx/ring/service/IDRingService.aidl
+++ b/ring-android/app/src/main/java/cx/ring/service/IDRingService.aidl
@@ -32,6 +32,10 @@
     void hold(in String callID);
     void unhold(in String callID);
 
+    void lookupName(in String account, in String nameserver, in String name);
+    void lookupAddress(in String account, in String nameserver, in String address);
+    void registerName(in String account, in String password, in String name);
+
     List getAccountList();
     String addAccount(in Map accountDetails);
     void removeAccount(in String accoundId);
diff --git a/ring-android/app/src/main/java/cx/ring/service/LocalService.java b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
index 31077f4..79c15b5 100644
--- a/ring-android/app/src/main/java/cx/ring/service/LocalService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
@@ -152,6 +152,27 @@
 
     private boolean mAreConversationsLoaded = false;
 
+    public interface NameLookupCallback {
+        void onFound(String name, String address);
+
+        void onInvalidName(String name);
+
+        void onError(String name, String address);
+    }
+
+    ;
+    final private Map<String, ArrayList<NameLookupCallback>> currentNameLookup = new HashMap<>();
+    final private Map<String, ArrayList<NameLookupCallback>> currentAddressLookup = new HashMap<>();
+
+    public interface NameRegistrationCallback {
+        void onRegistered(String name);
+
+        void onError(String name, CharSequence err);
+    }
+
+    ;
+    final private Map<String, ArrayList<NameRegistrationCallback>> currentNameRegistrations = new HashMap<>();
+
     public ContactsLoader.Result getSortedContacts() {
         Log.w(TAG, "getSortedContacts " + lastContactLoaderResult.contacts.size() + " contacts, " + lastContactLoaderResult.starred.size() + " starred.");
         return lastContactLoaderResult;
@@ -247,6 +268,54 @@
         }
     }
 
+    public void lookupName(final String account, final String name, final NameLookupCallback cb) {
+        try {
+            ArrayList<NameLookupCallback> cbs = currentNameLookup.get(name);
+            if (cbs == null) {
+                cbs = new ArrayList<>();
+                currentNameLookup.put(name, cbs);
+            }
+            cbs.add(cb);
+            mService.lookupName(account == null ? "" : account, "", name);
+        } catch (RemoteException e) {
+            cb.onError(name, null);
+        }
+    }
+
+    public void lookupAddress(final String account, final String address, final NameLookupCallback cb) {
+        try {
+            ArrayList<NameLookupCallback> cbs = currentAddressLookup.get(address);
+            if (cbs == null) {
+                cbs = new ArrayList<>();
+                currentAddressLookup.put(address, cbs);
+            }
+            cbs.add(cb);
+            mService.lookupAddress(account, null, address);
+        } catch (RemoteException e) {
+            cb.onError(null, address);
+        }
+    }
+
+    public void registerName(final Account account, final String password, final String name, final NameRegistrationCallback cb) {
+        if (account.registeringUsername) {
+            Log.w(TAG, "Already trying to register username");
+            return;
+        }
+        try {
+            ArrayList<NameRegistrationCallback> cbs = currentNameRegistrations.get(name);
+            if (cbs == null) {
+                cbs = new ArrayList<>();
+                currentNameRegistrations.put(name, cbs);
+            }
+            cbs.add(cb);
+            account.registeringUsername = true;
+            mService.registerName(account.getAccountID(), password, name);
+        } catch (RemoteException e) {
+            account.registeringUsername = false;
+        }
+        account.notifyObservers();
+    }
+
     public void sendTextMessage(Conference conf, String txt) {
         try {
             mService.sendTextMessage(conf.getId(), txt);
@@ -1418,6 +1487,79 @@
                     }
                     break;
                 }
+                case ConfigurationManagerCallback.NAME_LOOKUP_ENDED: {
+                    String name = intent.getStringExtra("name");
+                    String address = intent.getStringExtra("address");
+                    int state = intent.getIntExtra("state", -1);
+                    ArrayList<NameLookupCallback> name_cbs = currentNameLookup.get(name);
+                    ArrayList<NameLookupCallback> addr_cbs = currentAddressLookup.get(address);
+                    if (name_cbs != null) {
+                        for (NameLookupCallback cb : name_cbs) {
+                            if (state == 0)
+                                cb.onFound(name, address);
+                            else if (state == 1)
+                                cb.onInvalidName(name);
+                            else
+                                cb.onError(name, address);
+                        }
+                        name_cbs.clear();
+                    }
+                    if (addr_cbs != null) {
+                        for (NameLookupCallback cb : addr_cbs) {
+                            if (state == 0)
+                                cb.onFound(name, address);
+                            else if (state == 1)
+                                cb.onInvalidName(name);
+                            else
+                                cb.onError(name, address);
+                        }
+                        addr_cbs.clear();
+                    }
+                    break;
+                }
+                case ConfigurationManagerCallback.NAME_REGISTRATION_ENDED: {
+                    Account acc = getAccount(intent.getStringExtra("account"));
+                    if (acc == null) {
+                        Log.w(TAG, "Can't find account for name registration callback");
+                        break;
+                    }
+                    String name = intent.getStringExtra("name");
+                    int state = intent.getIntExtra("state", -1);
+                    acc.registeringUsername = false;
+                    ArrayList<NameRegistrationCallback> reg_cbs = currentNameRegistrations.get(name);
+                    if (reg_cbs != null) {
+                        for (NameRegistrationCallback cb : reg_cbs) {
+                            if (state == 0) {
+                                try {
+                                    acc.setVolatileDetails((Map<String, String>) mService.getVolatileAccountDetails(acc.getAccountID()));
+                                } catch (RemoteException e) {
+                                    e.printStackTrace();
+                                }
+                                cb.onRegistered(name);
+                            } else {
+                                int res = -1;
+                                switch (state) {
+                                    case 1:
+                                        res = R.string.register_name_wrong_password;
+                                        break;
+                                    case 2:
+                                        res = R.string.register_name_invalid;
+                                        break;
+                                    case 3:
+                                        res = R.string.register_name_already_taken;
+                                        break;
+                                    case 4:
+                                        res = R.string.register_name_network_error;
+                                        break;
+                                }
+                                cb.onError(name, getText(res));
+                            }
+                        }
+                        reg_cbs.clear();
+                    }
+                    acc.notifyObservers();
+                    break;
+                }
                 case CallManagerCallBack.INCOMING_CALL: {
                     String callId = intent.getStringExtra("call");
                     String accountId = intent.getStringExtra("account");
@@ -1545,6 +1687,8 @@
         intentFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_DEVICES_CHANGED);
         intentFilter.addAction(ConfigurationManagerCallback.INCOMING_TEXT);
         intentFilter.addAction(ConfigurationManagerCallback.MESSAGE_STATE_CHANGED);
+        intentFilter.addAction(ConfigurationManagerCallback.NAME_LOOKUP_ENDED);
+        intentFilter.addAction(ConfigurationManagerCallback.NAME_REGISTRATION_ENDED);
 
         intentFilter.addAction(CallManagerCallBack.INCOMING_CALL);
         intentFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
diff --git a/ring-android/app/src/main/java/cx/ring/utils/BlockchainTextWatcher.java b/ring-android/app/src/main/java/cx/ring/utils/BlockchainTextWatcher.java
new file mode 100644
index 0000000..6e43d3e
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/utils/BlockchainTextWatcher.java
@@ -0,0 +1,196 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Thibault Wittemberg <thibault.wittemberg@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.utils;
+
+import android.support.annotation.NonNull;
+import android.support.design.widget.TextInputLayout;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.widget.EditText;
+
+import java.lang.ref.WeakReference;
+
+import cx.ring.R;
+import cx.ring.service.LocalService;
+
+public class BlockchainTextWatcher implements TextWatcher, LocalService.NameLookupCallback {
+
+    private static final String TAG = BlockchainTextWatcher.class.getName();
+
+    private WeakReference<TextInputLayout> mInputLayout;
+    private WeakReference<EditText> mInputText;
+    private WeakReference<LocalService> mLocalService;
+    private BlockchainInputHandler mBlockchainInputHandler;
+    private String mUserNameAlreadyTaken;
+    private String mInvalidUsername;
+    private String mLookinForAvailability;
+
+    public BlockchainTextWatcher(final LocalService.Callbacks callbacks, final TextInputLayout inputLayout, final EditText inputText) {
+        mInputLayout = new WeakReference<>(inputLayout);
+        mInputText = new WeakReference<>(inputText);
+
+        if (callbacks != null && callbacks.getService() != null) {
+            mLocalService = new WeakReference<>(callbacks.getService());
+            LocalService localService = callbacks.getService();
+            mUserNameAlreadyTaken = localService.getString(R.string.username_already_taken);
+            mInvalidUsername = localService.getString(R.string.invalid_username);
+            mLookinForAvailability = localService.getString(R.string.looking_for_username_availability);
+            mBlockchainInputHandler = new BlockchainInputHandler(mLocalService, this);
+        } else {
+            mLocalService = new WeakReference<>(null);
+            mBlockchainInputHandler = new BlockchainInputHandler(mLocalService, this);
+        }
+    }
+
+    @Override
+    public void onFound(String name, String address) {
+        if (mInputText.get() != null) {
+            String searchedText = mInputText.get().getText().toString();
+            Log.w(TAG, "Name lookup UI : onFound " + name + " " + address + " (current " + searchedText + ")");
+            if (name.equals(searchedText)) {
+                mInputLayout.get().setErrorEnabled(true);
+                mInputLayout.get().setError(mUserNameAlreadyTaken);
+            }
+        }
+    }
+
+    @Override
+    public void onInvalidName(String name) {
+        if (mInputText.get() != null) {
+            String searchedText = mInputText.get().getText().toString();
+            Log.w(TAG, "Name lookup UI : onInvalidName " + name + " (current " + searchedText + ")");
+            if (name.equals(searchedText)) {
+
+                if (TextUtils.isEmpty(name)) {
+                    mInputLayout.get().setErrorEnabled(false);
+                    mInputLayout.get().setError(null);
+                } else {
+                    mInputLayout.get().setErrorEnabled(true);
+                    mInputLayout.get().setError(mInvalidUsername);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onError(String name, String address) {
+        if (mInputText.get() != null) {
+            String searchedText = mInputText.get().getText().toString();
+            Log.w(TAG, "Name lookup UI : onError " + name + " " + address + " (current " + searchedText + ")");
+            if (name.equals(searchedText)) {
+                mInputLayout.get().setErrorEnabled(false);
+                mInputLayout.get().setError(null);
+            }
+        }
+    }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+        if (mInputText.get() != null) {
+            mInputText.get().setError(null);
+        }
+    }
+
+    @Override
+    public void afterTextChanged(final Editable txt) {
+        final String name = txt.toString();
+
+        if (mInputLayout.get() == null || mInputText.get() == null) {
+            return;
+        }
+
+        if (TextUtils.isEmpty(name)) {
+            mInputLayout.get().setErrorEnabled(false);
+            mInputLayout.get().setError(null);
+        } else {
+            mInputLayout.get().setErrorEnabled(true);
+            mInputLayout.get().setError(mLookinForAvailability);
+        }
+
+        if (mBlockchainInputHandler.isAlive()) {
+            mBlockchainInputHandler.enqueueNextLookup(name);
+        } else {
+            mBlockchainInputHandler = new BlockchainInputHandler(mLocalService, this);
+            mBlockchainInputHandler.enqueueNextLookup(name);
+        }
+    }
+
+    private class BlockchainInputHandler extends Thread {
+
+        private WeakReference<LocalService> mLocalService;
+        private String mTextToLookup;
+        private LocalService.NameLookupCallback mLookupCallback;
+
+        private boolean mIsWaitingForInputs = false;
+        private long mLastEnqueuedInputTimeStamp = -1;
+
+        public BlockchainInputHandler(@NonNull WeakReference<LocalService> localService, @NonNull LocalService.NameLookupCallback lookupCallback) {
+            mLocalService = localService;
+            mLookupCallback = lookupCallback;
+        }
+
+        public void enqueueNextLookup(String text) {
+
+            if (mLocalService.get() == null) {
+                return;
+            }
+
+            mLastEnqueuedInputTimeStamp = System.currentTimeMillis();
+            mTextToLookup = text;
+
+            if (!mIsWaitingForInputs) {
+                mIsWaitingForInputs = true;
+                start();
+            }
+        }
+
+        @Override
+        public void run() {
+            while (mIsWaitingForInputs) {
+                try {
+                    Thread.sleep(100);
+
+                    long timeFromLastEnqueuedInput = System.currentTimeMillis() - mLastEnqueuedInputTimeStamp;
+                    if (timeFromLastEnqueuedInput >= 6000) {
+                        // we've been waiting for a long time, stop the wait
+                        // the next user input will trigger the next wait
+                        mIsWaitingForInputs = false;
+                    } else if (timeFromLastEnqueuedInput >= 3000) {
+                        // trigger the blockchain lookup
+                        final LocalService localService = mLocalService.get();
+                        localService.lookupName("", mTextToLookup, mLookupCallback);
+                        // stop the wait
+                        mIsWaitingForInputs = false;
+                    }
+
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Error while waiting for next Blockchain lookup", e);
+                }
+            }
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/utils/BlockchainUtils.java b/ring-android/app/src/main/java/cx/ring/utils/BlockchainUtils.java
new file mode 100644
index 0000000..c3d1a84
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/utils/BlockchainUtils.java
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Thibault Wittemberg <thibault.wittemberg@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.utils;
+
+import android.support.design.widget.TextInputLayout;
+import android.text.InputFilter;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextWatcher;
+import android.widget.EditText;
+
+import cx.ring.service.LocalService;
+
+public class BlockchainUtils {
+
+    public static TextWatcher attachUsernameTextWatcher(final LocalService.Callbacks callbacks, final TextInputLayout inputLayout, final EditText inputText) {
+        TextWatcher textWatcher = new BlockchainTextWatcher(callbacks, inputLayout, inputText);
+        inputText.addTextChangedListener(textWatcher);
+        return textWatcher;
+    }
+
+    public static void attachUsernameTextFilter(final EditText inputText) {
+        InputFilter filter = new InputFilter() {
+
+            @Override
+            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
+                boolean keepOriginal = true;
+                StringBuilder sb = new StringBuilder(end - start);
+                for (int i = start; i < end; i++) {
+                    char c = source.charAt(i);
+                    if (isCharAllowed(c)) {
+                        sb.append(c);
+                    } else {
+                        keepOriginal = false;
+                    }
+                }
+                if (keepOriginal) {
+                    return null;
+                } else {
+                    if (source instanceof Spanned) {
+                        SpannableString sp = new SpannableString(sb);
+                        return sp;
+                    } else {
+                        return sb;
+                    }
+                }
+            }
+
+            private boolean isCharAllowed(char c) {
+                String textToTest = "" + c;
+                return textToTest.matches("[a-z0-9_\\-]");
+            }
+        };
+
+        inputText.setFilters(new InputFilter[]{filter});
+    }
+}
diff --git a/ring-android/app/src/main/java/cx/ring/views/BoundedLinearLayout.java b/ring-android/app/src/main/java/cx/ring/views/BoundedLinearLayout.java
index f19dbee..fc49ba1 100644
--- a/ring-android/app/src/main/java/cx/ring/views/BoundedLinearLayout.java
+++ b/ring-android/app/src/main/java/cx/ring/views/BoundedLinearLayout.java
@@ -1,3 +1,22 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@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.
+ */
 package cx.ring.views;
 
 import android.content.Context;
@@ -8,9 +27,7 @@
 import cx.ring.R;
 
 public class BoundedLinearLayout extends LinearLayout {
-
     private final int mBoundedWidth;
-
     private final int mBoundedHeight;
 
     public BoundedLinearLayout(Context context) {
@@ -31,13 +48,13 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         // Adjust width as necessary
         int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
-        if(mBoundedWidth > 0 && mBoundedWidth < measuredWidth) {
+        if (mBoundedWidth > 0 && mBoundedWidth < measuredWidth) {
             int measureMode = MeasureSpec.getMode(widthMeasureSpec);
             widthMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedWidth, measureMode);
         }
         // Adjust height as necessary
         int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
-        if(mBoundedHeight > 0 && mBoundedHeight < measuredHeight) {
+        if (mBoundedHeight > 0 && mBoundedHeight < measuredHeight) {
             int measureMode = MeasureSpec.getMode(heightMeasureSpec);
             heightMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedHeight, measureMode);
         }
diff --git a/ring-android/app/src/main/java/cx/ring/views/BoundedRelativeLayout.java b/ring-android/app/src/main/java/cx/ring/views/BoundedRelativeLayout.java
new file mode 100644
index 0000000..712501d
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/views/BoundedRelativeLayout.java
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@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.
+ */
+package cx.ring.views;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.RelativeLayout;
+
+import cx.ring.R;
+
+public class BoundedRelativeLayout extends RelativeLayout {
+    private final int mBoundedWidth;
+    private final int mBoundedHeight;
+
+    public BoundedRelativeLayout(Context context) {
+        super(context);
+        mBoundedWidth = 0;
+        mBoundedHeight = 0;
+    }
+
+    public BoundedRelativeLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoundedView);
+        mBoundedWidth = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_width, 0);
+        mBoundedHeight = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_height, 0);
+        a.recycle();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // Adjust width as necessary
+        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
+        if (mBoundedWidth > 0 && mBoundedWidth < measuredWidth) {
+            int measureMode = MeasureSpec.getMode(widthMeasureSpec);
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedWidth, measureMode);
+        }
+        // Adjust height as necessary
+        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
+        if (mBoundedHeight > 0 && mBoundedHeight < measuredHeight) {
+            int measureMode = MeasureSpec.getMode(heightMeasureSpec);
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedHeight, measureMode);
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/views/BoundedScrollView.java b/ring-android/app/src/main/java/cx/ring/views/BoundedScrollView.java
new file mode 100644
index 0000000..20a69b3
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/views/BoundedScrollView.java
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@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.
+ */
+package cx.ring.views;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.ScrollView;
+
+import cx.ring.R;
+
+public class BoundedScrollView extends ScrollView {
+    private final int mBoundedWidth;
+    private final int mBoundedHeight;
+
+    public BoundedScrollView(Context context) {
+        super(context);
+        mBoundedWidth = 0;
+        mBoundedHeight = 0;
+    }
+
+    public BoundedScrollView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoundedView);
+        mBoundedWidth = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_width, 0);
+        mBoundedHeight = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_height, 0);
+        a.recycle();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // Adjust width as necessary
+        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
+        if (mBoundedWidth > 0 && mBoundedWidth < measuredWidth) {
+            int measureMode = MeasureSpec.getMode(widthMeasureSpec);
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedWidth, measureMode);
+        }
+        // Adjust height as necessary
+        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
+        if (mBoundedHeight > 0 && mBoundedHeight < measuredHeight) {
+            int measureMode = MeasureSpec.getMode(heightMeasureSpec);
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedHeight, measureMode);
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/jni/configurationmanager.i b/ring-android/app/src/main/jni/configurationmanager.i
index 384a039..45f8415 100644
--- a/ring-android/app/src/main/jni/configurationmanager.i
+++ b/ring-android/app/src/main/jni/configurationmanager.i
@@ -47,6 +47,9 @@
     virtual void errorAlert(int alert){}
     virtual void getHardwareAudioFormat(std::vector<int32_t>* /*params_ret*/){}
     virtual void getAppDataPath(const std::string& /* name */, std::vector<std::string>* /*path_ret*/){}
+
+    virtual void nameRegistrationEnded(const std::string& /*account_id*/, int state, const std::string& /*name*/){}
+    virtual void registeredNameFound(const std::string& /*account_id*/, int state, const std::string& /*address*/, const std::string& /*name*/){}
 };
 %}
 
@@ -67,6 +70,10 @@
 uint64_t sendAccountTextMessage(const std::string& accountID, const std::string& to, const std::map<std::string, std::string>& message);
 int getMessageStatus(uint64_t id);
 
+bool lookupName(const std::string& account, const std::string& nameserver, const std::string& name);
+bool lookupAddress(const std::string& account, const std::string& nameserver, const std::string& address);
+bool registerName(const std::string& account, const std::string& password, const std::string& name);
+
 std::map<std::string, std::string> getTlsDefaultSettings();
 
 std::vector<unsigned> getCodecList();
@@ -200,4 +207,7 @@
     virtual void errorAlert(int alert){}
     virtual void getHardwareAudioFormat(std::vector<int32_t>* /*params_ret*/){}
     virtual void getAppDataPath(const std::string& /* name */, std::vector<std::string>* /*path_ret*/){}
+
+    virtual void nameRegistrationEnded(const std::string& /*account_id*/, int state, const std::string& /*name*/){}
+    virtual void registeredNameFound(const std::string& /*account_id*/, int state, const std::string& /*address*/, const std::string& /*name*/){}
 };
diff --git a/ring-android/app/src/main/jni/jni_interface.i b/ring-android/app/src/main/jni/jni_interface.i
index bdf7767..41cf43e 100644
--- a/ring-android/app/src/main/jni/jni_interface.i
+++ b/ring-android/app/src/main/jni/jni_interface.i
@@ -61,22 +61,26 @@
   public static $javaclassname toSwig(java.util.Map<String,String> in) {
     $javaclassname n = new $javaclassname();
     for (java.util.Map.Entry<String, String> entry : in.entrySet()) {
-      n.set(entry.getKey(), entry.getValue());
+      if (entry.getValue() != null) {
+        n.set(entry.getKey(), entry.getValue());
+      }
     }
     return n;
   }
   public java.util.HashMap<String,String> toNative() {
     java.util.HashMap<String,String> out = new java.util.HashMap<>((int)size());
     StringVect keys = keys();
-    for (String s : keys)
-      out.put(s, get(s));
+    for (String s : keys) {
+        out.put(s, get(s));
+    }
     return out;
   }
   public java.util.HashMap<String,String> toNativeFromUtf8() {
       java.util.HashMap<String,String> out = new java.util.HashMap<>((int)size());
       StringVect keys = keys();
-      for (String s : keys)
-          out.put(s, getRaw(s).toJavaString());
+      for (String s : keys) {
+        out.put(s, getRaw(s).toJavaString());
+      }
       return out;
   }
 %}
@@ -84,8 +88,9 @@
     std::vector<std::string> keys() const {
         std::vector<std::string> k;
         k.reserve($self->size());
-        for (const auto& i : *$self)
+        for (const auto& i : *$self) {
             k.push_back(i.first);
+        }
         return k;
     }
     void setRaw(std::string key, const vector<uint8_t>& value) {
@@ -119,8 +124,9 @@
 %typemap(javacode) vector< map<string,string> > %{
   public java.util.ArrayList<java.util.Map<String, String>> toNative() {
     java.util.ArrayList<java.util.Map<String, String>> out = new java.util.ArrayList<>();
-    for (int i = 0; i < size(); ++i)
-      out.add(get(i).toNative());
+    for (int i = 0; i < size(); ++i) {
+        out.add(get(i).toNative());
+    }
     return out;
   }
 %}
@@ -138,14 +144,16 @@
       dat = in.getBytes();
     }
     Blob n = new Blob(dat.length);
-    for (int i=0; i<dat.length; i++)
+    for (int i=0; i<dat.length; i++) {
       n.set(i, dat[i]);
+    }
     return n;
   }
   public String toJavaString() {
     byte[] dat = new byte[(int)size()];
-    for (int i=0; i<dat.length; i++)
+    for (int i=0; i<dat.length; i++) {
         dat[i] = (byte)get(i);
+    }
     try {
         return new String(dat, "utf-8");
     } catch (java.io.UnsupportedEncodingException e) {
@@ -229,28 +237,11 @@
         exportable_callback<ConfigurationSignal::CertificateExpired>(bind(&ConfigurationCallback::certificateExpired, confM, _1 )),
         exportable_callback<ConfigurationSignal::CertificateStateChanged>(bind(&ConfigurationCallback::certificateStateChanged, confM, _1, _2, _3 )),
         exportable_callback<ConfigurationSignal::GetHardwareAudioFormat>(bind(&ConfigurationCallback::getHardwareAudioFormat, confM, _1 )),
-        exportable_callback<ConfigurationSignal::GetAppDataPath>(bind(&ConfigurationCallback::getAppDataPath, confM, _1, _2 ))
+        exportable_callback<ConfigurationSignal::GetAppDataPath>(bind(&ConfigurationCallback::getAppDataPath, confM, _1, _2 )),
+        exportable_callback<ConfigurationSignal::RegisteredNameFound>(bind(&ConfigurationCallback::registeredNameFound, confM, _1, _2, _3, _4 )),
+        exportable_callback<ConfigurationSignal::NameRegistrationEnded>(bind(&ConfigurationCallback::nameRegistrationEnded, confM, _1, _2, _3 ))
     };
 
-/*
-    // Presence event handlers
-    const std::map<std::string, SharedCallback> presEvHandlers = {
-        exportable_callback<PresenceSignal::NewServerSubscriptionRequest>(bind(&DBusPresenceManager::newServerSubscriptionRequest, presM, _1)),
-        exportable_callback<PresenceSignal::ServerError>(bind(&DBusPresenceManager::serverError, presM, _1, _2, _3)),
-        exportable_callback<PresenceSignal::NewBuddyNotification>(bind(&DBusPresenceManager::newBuddyNotification, presM, _1, _2, _3, _4)),
-        exportable_callback<PresenceSignal::SubscriptionStateChanged>(bind(&DBusPresenceManager::subscriptionStateChanged, presM, _1, _2, _3)),
-    };
-
-#ifdef RING_VIDEO
-    // Video event handlers
-    const std::map<std::string, SharedCallback> videoEvHandlers = {
-        exportable_callback<VideoSignal::DeviceEvent>(bind(&DBusVideoManager::deviceEvent, videoM)),
-        exportable_callback<VideoSignal::DecodingStarted>(bind(&DBusVideoManager::startedDecoding, videoM, _1, _2, _3, _4, _5)),
-        exportable_callback<VideoSignal::DecodingStopped>(bind(&DBusVideoManager::stoppedDecoding, videoM, _1, _2, _3)),
-    };
-#endif
-*/
-
     const std::map<std::string, SharedCallback> videoEvHandlers = {
         exportable_callback<VideoSignal::GetCameraInfo>(bind(&VideoCallback::getCameraInfo, videoM, _1, _2, _3, _4)),
         exportable_callback<VideoSignal::SetParameters>(bind(&VideoCallback::setParameters, videoM, _1, _2, _3, _4, _5)),
@@ -265,7 +256,6 @@
 
     registerCallHandlers(callEvHandlers);
     registerConfHandlers(configEvHandlers);
-/*    registerPresHandlers(presEvHandlers); */
     registerVideoHandlers(videoEvHandlers);
 
     DRing::start();
diff --git a/ring-android/app/src/main/res/drawable-hdpi/ic_edit_black_24dp.png b/ring-android/app/src/main/res/drawable-hdpi/ic_edit_black_24dp.png
new file mode 100644
index 0000000..e531d72
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable-hdpi/ic_edit_black_24dp.png
Binary files differ
diff --git a/ring-android/app/src/main/res/drawable-mdpi/ic_edit_black_24dp.png b/ring-android/app/src/main/res/drawable-mdpi/ic_edit_black_24dp.png
new file mode 100644
index 0000000..9efbaae
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable-mdpi/ic_edit_black_24dp.png
Binary files differ
diff --git a/ring-android/app/src/main/res/drawable-xhdpi/ic_edit_black_24dp.png b/ring-android/app/src/main/res/drawable-xhdpi/ic_edit_black_24dp.png
new file mode 100644
index 0000000..87f8de1
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable-xhdpi/ic_edit_black_24dp.png
Binary files differ
diff --git a/ring-android/app/src/main/res/drawable-xxhdpi/ic_edit_black_24dp.png b/ring-android/app/src/main/res/drawable-xxhdpi/ic_edit_black_24dp.png
new file mode 100644
index 0000000..4af4ae6
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable-xxhdpi/ic_edit_black_24dp.png
Binary files differ
diff --git a/ring-android/app/src/main/res/drawable-xxxhdpi/ic_edit_black_24dp.png b/ring-android/app/src/main/res/drawable-xxxhdpi/ic_edit_black_24dp.png
new file mode 100644
index 0000000..d6761ba
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable-xxxhdpi/ic_edit_black_24dp.png
Binary files differ
diff --git a/ring-android/app/src/main/res/drawable/background_tabs.xml b/ring-android/app/src/main/res/drawable/background_tabs.xml
index 885cf03..53e85df 100644
--- a/ring-android/app/src/main/res/drawable/background_tabs.xml
+++ b/ring-android/app/src/main/res/drawable/background_tabs.xml
@@ -2,7 +2,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime">
 
     <item android:state_pressed="true" android:drawable="@color/background_tab_pressed" />
-    <item android:state_focused="true" android:drawable="@color/background_tab_pressed"/>
-    <item android:drawable="@android:color/transparent"/>
-
+    <item android:state_focused="true" android:drawable="@color/background_tab_pressed" />
+    <item android:drawable="@android:color/transparent" />
 </selector>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/activity_account_settings.xml b/ring-android/app/src/main/res/layout/activity_account_settings.xml
index 41475d2..22f98d5 100644
--- a/ring-android/app/src/main/res/layout/activity_account_settings.xml
+++ b/ring-android/app/src/main/res/layout/activity_account_settings.xml
@@ -1,4 +1,4 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
@@ -14,14 +14,15 @@
         android:layout_alignParentStart="true"
         android:layout_alignParentTop="true"
         android:background="@color/color_primary_light"
-        android:orientation="vertical"
         android:elevation="4dp"
-        app:elevation="4dp">
+        android:orientation="vertical">
+
 
         <android.support.v7.widget.Toolbar
             android:id="@+id/main_toolbar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:background="@color/color_primary_light"
             android:minHeight="?attr/actionBarSize"
             android:popupTheme="@style/Theme.AppCompat.Light.NoActionBar"
             android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
@@ -50,4 +51,9 @@
         android:layout_alignParentBottom="true"
         android:layout_below="@id/header_container" />
 
-</RelativeLayout>
\ No newline at end of file
+    <FrameLayout
+        android:id="@+id/fragment_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/activity_home.xml b/ring-android/app/src/main/res/layout/activity_home.xml
index 67d25c5..71646e5 100644
--- a/ring-android/app/src/main/res/layout/activity_home.xml
+++ b/ring-android/app/src/main/res/layout/activity_home.xml
@@ -57,7 +57,7 @@
             android:elevation="@dimen/toolbar_elevation"
             android:layout_below="@+id/main_toolbar"
             android:background="@color/color_primary_light"
-            android:visibility="visible"
+            android:visibility="gone"
             android:paddingLeft="@dimen/toolbar_content_inset"
             android:gravity="center_vertical">
 
@@ -97,11 +97,7 @@
             app:elevation="6dp"
             app:fabSize="mini"
             app:pressedTranslationZ="12dp"
-            app:rippleColor="@android:color/white">
-
-
-
-            </android.support.design.widget.FloatingActionButton>
+            app:rippleColor="@android:color/white" />
 
     </RelativeLayout>
 
diff --git a/ring-android/app/src/main/res/layout/activity_wizard.xml b/ring-android/app/src/main/res/layout/activity_wizard.xml
index 37d0c24..abc4a41 100644
--- a/ring-android/app/src/main/res/layout/activity_wizard.xml
+++ b/ring-android/app/src/main/res/layout/activity_wizard.xml
@@ -18,8 +18,8 @@
         app:elevation="4dp"
         app:titleTextAppearance="@style/ToolbarTitle" />
 
-    <android.support.v4.view.ViewPager
-        android:id="@+id/pager"
+    <FrameLayout
+        android:id="@+id/fragment_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
 
diff --git a/ring-android/app/src/main/res/layout/dialog_new_device.xml b/ring-android/app/src/main/res/layout/dialog_new_device.xml
index 268b2a4..039f4d3 100644
--- a/ring-android/app/src/main/res/layout/dialog_new_device.xml
+++ b/ring-android/app/src/main/res/layout/dialog_new_device.xml
@@ -4,16 +4,21 @@
     android:layout_height="wrap_content"
     android:orientation="vertical">
 
-    <EditText
-        android:id="@+id/pwd_txt"
+    <android.support.design.widget.TextInputLayout
+        android:id="@+id/ring_password_txt_box"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:layout_marginLeft="20dp"
-        android:layout_marginRight="20dp"
-        android:layout_marginTop="8dp"
-        android:ems="10"
-        android:hint="@string/account_new_device_password"
-        android:inputType="textPassword" />
+        android:layout_height="wrap_content">
 
+        <android.support.design.widget.TextInputEditText
+            android:id="@+id/pwd_txt"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginLeft="20dp"
+            android:layout_marginRight="20dp"
+            android:layout_marginTop="8dp"
+            android:ems="10"
+            android:hint="@string/account_new_device_password"
+            android:inputType="textPassword" />
+    </android.support.design.widget.TextInputLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/dialog_username_registration.xml b/ring-android/app/src/main/res/layout/dialog_username_registration.xml
new file mode 100644
index 0000000..e8d5deb
--- /dev/null
+++ b/ring-android/app/src/main/res/layout/dialog_username_registration.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/ring_username_box"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <android.support.design.widget.TextInputLayout
+        android:id="@+id/ring_username_txt_box"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="16dp"
+        android:layout_marginLeft="12dp"
+        android:layout_marginRight="12dp">
+
+        <android.support.design.widget.TextInputEditText
+            android:id="@+id/ring_username"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/prompt_new_username"
+            android:imeOptions="actionNext"
+            android:inputType="textVisiblePassword"
+            android:lines="1"
+            android:maxLines="1" />
+    </android.support.design.widget.TextInputLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/frag_acc_ring_create.xml b/ring-android/app/src/main/res/layout/frag_acc_ring_create.xml
new file mode 100644
index 0000000..c6e16fd
--- /dev/null
+++ b/ring-android/app/src/main/res/layout/frag_acc_ring_create.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/activity_account_creation"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#eeeeee"
+    tools:context="cx.ring.client.AccountWizard">
+
+    <cx.ring.views.BoundedScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_centerHorizontal="true"
+        android:layout_gravity="center_horizontal"
+        android:background="@color/cardview_light_background"
+        app:bounded_width="500dp"
+        android:layout_above="@+id/add_action_panel">
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="@dimen/activity_vertical_margin"
+            android:paddingLeft="@dimen/activity_horizontal_margin"
+            android:paddingRight="@dimen/activity_horizontal_margin"
+            android:paddingTop="@dimen/activity_vertical_margin">
+
+            <ImageView
+                android:id="@+id/imageView6"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="true"
+                android:layout_margin="16dp"
+                android:contentDescription="@string/app_name"
+                android:src="@drawable/ring_logo_48dp" />
+
+            <TextView
+                android:id="@+id/ring_acc_descr_txt"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_toLeftOf="@+id/imageView6"
+                android:layout_toStartOf="@+id/imageView6"
+                android:paddingBottom="16dp"
+                android:paddingEnd="16dp"
+                android:paddingStart="16dp"
+                android:paddingTop="16dp"
+                android:text="@string/help_ring"
+                android:textColor="@color/text_color_primary"
+                android:textSize="14sp" />
+
+            <LinearLayout
+                android:id="@+id/newAccountLayout"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_below="@+id/ring_acc_descr_txt"
+                android:animateLayoutChanges="true"
+                android:orientation="vertical">
+
+                <Switch
+                    android:id="@+id/switch_ring_username"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:checked="true"
+                    android:padding="16dp"
+                    android:text="@string/register_username"
+                    android:textColor="@color/text_color_secondary" />
+
+                <LinearLayout
+                    android:id="@+id/ring_username_box"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical">
+
+                    <android.support.design.widget.TextInputLayout
+                        android:id="@+id/ring_username_txt_box"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginBottom="16dp"
+                        android:layout_marginLeft="12dp"
+                        android:layout_marginRight="12dp">
+
+                        <android.support.design.widget.TextInputEditText
+                            android:id="@+id/ring_username"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:hint="@string/prompt_new_username"
+                            android:imeOptions="actionNext"
+                            android:inputType="textVisiblePassword"
+                            android:lines="1"
+                            android:maxLines="1" />
+                    </android.support.design.widget.TextInputLayout>
+
+                </LinearLayout>
+
+                <TextView
+                    android:id="@+id/ring_password_help_txt"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingBottom="8dp"
+                    android:paddingEnd="16dp"
+                    android:paddingStart="16dp"
+                    android:paddingTop="16dp"
+                    android:text="@string/help_password_choose"
+                    android:textColor="@color/text_color_secondary"
+                    android:textSize="14sp" />
+
+                <android.support.design.widget.TextInputLayout
+                    android:id="@+id/ring_password_txt_box"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp">
+
+                    <android.support.design.widget.TextInputEditText
+                        android:id="@+id/ring_password"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:hint="@string/prompt_new_password"
+                        android:imeOptions="actionNext"
+                        android:inputType="textPassword" />
+                </android.support.design.widget.TextInputLayout>
+
+                <android.support.design.widget.TextInputLayout
+                    android:id="@+id/ring_password_repeat_txt_box"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp">
+
+                    <android.support.design.widget.TextInputEditText
+                        android:id="@+id/ring_password_repeat"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:hint="@string/prompt_new_password_repeat"
+                        android:imeActionId="@integer/register_sip_account_actionid"
+                        android:imeActionLabel="@string/action_create_short"
+                        android:inputType="textPassword" />
+                </android.support.design.widget.TextInputLayout>
+
+            </LinearLayout>
+        </RelativeLayout>
+    </cx.ring.views.BoundedScrollView>
+
+    <LinearLayout
+        android:id="@+id/add_action_panel"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:background="@color/color_primary_dark">
+
+        <android.support.v7.widget.AppCompatButton
+            android:id="@+id/add_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="?attr/selectableItemBackground"
+            android:paddingBottom="5dp"
+            android:paddingTop="5dp"
+            android:text="@string/action_create"
+            android:textColor="@color/white" />
+
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/ring-android/app/src/main/res/layout/frag_acc_ring_login.xml b/ring-android/app/src/main/res/layout/frag_acc_ring_login.xml
new file mode 100644
index 0000000..93fe72c
--- /dev/null
+++ b/ring-android/app/src/main/res/layout/frag_acc_ring_login.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/activity_account_creation"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#eeeeee">
+
+    <cx.ring.views.BoundedScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_centerHorizontal="true"
+        android:layout_gravity="center_horizontal"
+        android:background="@color/cardview_light_background"
+        app:bounded_width="500dp">
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="@dimen/activity_vertical_margin"
+            android:paddingLeft="@dimen/activity_horizontal_margin"
+            android:paddingRight="@dimen/activity_horizontal_margin"
+            android:paddingTop="@dimen/activity_vertical_margin">
+
+            <ImageView
+                android:id="@+id/imageView6"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="true"
+                android:layout_margin="16dp"
+                android:contentDescription="@string/app_name"
+                android:src="@drawable/ring_logo_48dp" />
+
+            <TextView
+                android:id="@+id/ring_acc_descr_txt"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_toLeftOf="@+id/imageView6"
+                android:layout_toStartOf="@+id/imageView6"
+                android:paddingBottom="24dp"
+                android:paddingEnd="16dp"
+                android:paddingStart="16dp"
+                android:paddingTop="16dp"
+                android:text="@string/help_ring"
+                android:textColor="@color/text_color_primary"
+                android:textSize="14sp" />
+
+            <LinearLayout
+                android:id="@+id/newAccountLayout"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_below="@+id/ring_acc_descr_txt"
+                android:animateLayoutChanges="true"
+                android:orientation="vertical">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingBottom="8dp"
+                    android:paddingEnd="16dp"
+                    android:paddingStart="16dp"
+                    android:paddingTop="16dp"
+                    android:text="@string/help_password_enter"
+                    android:textColor="@color/text_color_secondary"
+                    android:textSize="14sp" />
+
+                <EditText
+                    android:id="@+id/ring_password"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="8dp"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp"
+                    android:hint="@string/prompt_password"
+                    android:imeOptions="actionNext"
+                    android:inputType="textPassword" />
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingBottom="8dp"
+                    android:paddingEnd="16dp"
+                    android:paddingStart="16dp"
+                    android:paddingTop="16dp"
+                    android:text="@string/help_pin_enter"
+                    android:textColor="@color/text_color_secondary"
+                    android:textSize="14sp" />
+
+                <EditText
+                    android:id="@+id/ring_add_pin"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginBottom="8dp"
+                    android:layout_marginEnd="12dp"
+                    android:layout_marginLeft="12dp"
+                    android:layout_marginRight="12dp"
+                    android:layout_marginStart="12dp"
+                    android:digits="0123456789abcdefABCDEF"
+                    android:hint="Enter PIN"
+                    android:imeOptions="actionNext"
+                    android:inputType="text"
+                    android:maxLines="1" />
+            </LinearLayout>
+        </RelativeLayout>
+    </cx.ring.views.BoundedScrollView>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:background="@color/color_primary_dark">
+
+        <android.support.v7.widget.AppCompatButton
+            android:id="@+id/link_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="?attr/selectableItemBackground"
+            android:paddingBottom="5dp"
+            android:paddingTop="5dp"
+            android:text="@string/account_link_button"
+            android:textColor="@color/white" />
+
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/ring-android/app/src/main/res/layout/frag_account_creation.xml b/ring-android/app/src/main/res/layout/frag_account_creation.xml
index 52485f2..6d0697e 100644
--- a/ring-android/app/src/main/res/layout/frag_account_creation.xml
+++ b/ring-android/app/src/main/res/layout/frag_account_creation.xml
@@ -23,24 +23,26 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/login_form"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="match_parent"
     android:background="#eeeeee"
     tools:context=".client.AccountWizard">
 
     <cx.ring.views.BoundedLinearLayout
         style="@style/AccountFormContainer"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_horizontal"
         android:animateLayoutChanges="false"
         android:descendantFocusability="beforeDescendants"
         android:focusableInTouchMode="true"
         android:orientation="vertical"
+        android:padding="0dp"
         app:bounded_width="320dp">
 
         <android.support.v7.widget.CardView
             android:id="@+id/ring_card_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="16dp"
+            android:layout_margin="16dp"
             android:animateLayoutChanges="false">
 
             <RelativeLayout
@@ -65,11 +67,11 @@
                     android:id="@+id/ring_acc_title_txt"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_alignParentLeft="true"
                     android:layout_alignParentStart="true"
+                    android:layout_alignParentLeft="true"
                     android:layout_alignParentTop="true"
-                    android:layout_toLeftOf="@+id/imageView6"
                     android:layout_toStartOf="@+id/imageView6"
+                    android:layout_toLeftOf="@+id/imageView6"
                     android:paddingLeft="16dp"
                     android:paddingRight="16dp"
                     android:paddingTop="24dp"
@@ -78,11 +80,11 @@
                     android:textSize="24sp" />
 
                 <TextView
-                    android:id="@+id/textView"
+                    android:id="@+id/ring_acc_descr_txt"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_alignParentLeft="true"
                     android:layout_alignParentStart="true"
+                    android:layout_alignParentLeft="true"
                     android:layout_below="@+id/ring_acc_title_txt"
                     android:paddingBottom="24dp"
                     android:paddingLeft="16dp"
@@ -92,70 +94,13 @@
                     android:textColor="@color/text_color_primary"
                     android:textSize="14sp" />
 
-                <LinearLayout
-                    android:id="@+id/addAccountLayout"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:layout_below="@id/textView"
-                    android:orientation="vertical"
-                    android:visibility="gone">
-
-                    <TextView
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:paddingBottom="24dp"
-                        android:paddingLeft="16dp"
-                        android:paddingRight="16dp"
-                        android:paddingTop="16dp"
-                        android:text="@string/account_link_infos"
-                        android:textColor="@color/text_color_primary"
-                        android:textSize="14sp" />
-
-                    <android.support.design.widget.TextInputLayout
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        app:passwordToggleEnabled="true">
-
-                        <android.support.design.widget.TextInputEditText
-                            android:id="@+id/ring_add_pin"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            android:layout_marginBottom="8dp"
-                            android:layout_marginEnd="12dp"
-                            android:layout_marginLeft="12dp"
-                            android:layout_marginRight="12dp"
-                            android:layout_marginStart="12dp"
-                            android:hint="@string/account_link_prompt_pin"
-                            android:imeOptions="actionNext"
-                            android:inputType="text"
-                            android:maxLines="1" />
-                    </android.support.design.widget.TextInputLayout>
-
-                    <android.support.design.widget.TextInputLayout
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        app:passwordToggleEnabled="true">
-
-                        <android.support.design.widget.TextInputEditText
-                            android:id="@+id/ring_add_password"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            android:layout_marginBottom="8dp"
-                            android:layout_marginEnd="12dp"
-                            android:layout_marginLeft="12dp"
-                            android:layout_marginRight="12dp"
-                            android:layout_marginStart="12dp"
-                            android:hint="@string/account_link_prompt_password"
-                            android:inputType="textPassword" />
-                    </android.support.design.widget.TextInputLayout>
-                </LinearLayout>
 
                 <Button
                     android:id="@+id/ring_add_account"
                     style="@style/Widget.AppCompat.Button.Borderless.Colored"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_below="@id/addAccountLayout"
+                    android:layout_below="@id/ring_acc_descr_txt"
                     android:background="?android:attr/selectableItemBackground"
                     android:text="@string/account_link_button" />
 
@@ -166,68 +111,11 @@
                     android:background="@color/color_primary_light"
                     android:orientation="vertical">
 
-                    <LinearLayout
-                        android:id="@+id/newAccountLayout"
-                        android:layout_width="match_parent"
-                        android:layout_height="match_parent"
-                        android:background="@color/color_primary_light"
-                        android:orientation="vertical"
-                        android:visibility="gone">
-
-                        <TextView
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            android:paddingBottom="24dp"
-                            android:paddingLeft="16dp"
-                            android:paddingRight="16dp"
-                            android:paddingTop="16dp"
-                            android:text="@string/account_new_infos"
-                            android:textColor="@color/text_color_primary"
-                            android:textSize="14sp" />
-
-                        <android.support.design.widget.TextInputLayout
-                            android:id="@+id/password_layout"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            app:passwordToggleEnabled="true">
-
-                            <android.support.design.widget.TextInputEditText
-                                android:id="@+id/ring_password"
-                                android:layout_width="match_parent"
-                                android:layout_height="wrap_content"
-                                android:layout_marginBottom="8dp"
-                                android:layout_marginLeft="12dp"
-                                android:layout_marginRight="12dp"
-                                android:hint="@string/prompt_new_password"
-                                android:imeOptions="actionNext"
-                                android:inputType="textPassword" />
-                        </android.support.design.widget.TextInputLayout>
-
-                        <android.support.design.widget.TextInputLayout
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            app:passwordToggleEnabled="true">
-
-                            <android.support.design.widget.TextInputEditText
-                                android:id="@+id/ring_password_repeat"
-                                android:layout_width="match_parent"
-                                android:layout_height="wrap_content"
-                                android:layout_marginBottom="8dp"
-                                android:layout_marginLeft="12dp"
-                                android:layout_marginRight="12dp"
-                                android:hint="@string/prompt_new_password_repeat"
-                                android:imeActionId="@integer/register_sip_account_actionid"
-                                android:imeActionLabel="@string/action_create_short"
-                                android:inputType="textPassword" />
-                        </android.support.design.widget.TextInputLayout>
-                    </LinearLayout>
-
                     <Button
                         android:id="@+id/ring_create_btn"
                         style="?attr/borderlessButtonStyle"
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
-                        android:layout_weight="1"
                         android:background="?android:attr/selectableItemBackground"
                         android:text="@string/account_new_button"
                         android:textColor="@color/text_color_primary_dark" />
@@ -237,12 +125,12 @@
 
         </android.support.v7.widget.CardView>
 
-        <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
+        <android.support.v7.widget.CardView
             android:id="@+id/card_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
-            android:layout_marginBottom="8dp"
+            android:layout_margin="16dp"
             android:animateLayoutChanges="false"
             android:clickable="true"
             android:foreground="?android:attr/selectableItemBackground">
diff --git a/ring-android/app/src/main/res/layout/frag_device_list.xml b/ring-android/app/src/main/res/layout/frag_device_list.xml
index 8f6a3b8..05a2317 100644
--- a/ring-android/app/src/main/res/layout/frag_device_list.xml
+++ b/ring-android/app/src/main/res/layout/frag_device_list.xml
@@ -16,55 +16,212 @@
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <RelativeLayout
+
+    <cx.ring.views.BoundedScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="vertical">
+        android:layout_gravity="center_horizontal"
+        app:bounded_width="360dp">
 
-        <TextView
-            android:id="@+id/headerText"
-            style="@style/Subheader"
-            android:layout_width="match_parent"
-            android:layout_height="48dp"
-            android:layout_alignParentTop="true"
-            android:gravity="center_vertical"
-            android:paddingEnd="72dp"
-            android:paddingStart="72dp"
-            android:text="@string/normal_devices_titles" />
-
-        <FrameLayout
+        <android.support.v7.widget.CardView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_below="@id/headerText"
-            android:background="@color/white"
-            android:elevation="2dp">
+            android:layout_marginBottom="16dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginTop="16dp">
 
-            <ListView
-                android:id="@+id/device_list"
+            <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
+                android:layout_height="match_parent"
+                android:orientation="vertical">
 
-            <TextView
-                android:id="@+id/empty_account_list"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:gravity="center"
-                android:text="@string/empty_account_list"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:textColor="@color/text_color_secondary"
-                android:visibility="gone" />
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal">
 
-        </FrameLayout>
+                    <TextView
+                        android:id="@+id/account_alias_txt"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:paddingBottom="8dp"
+                        android:paddingEnd="16dp"
+                        android:paddingStart="16dp"
+                        android:paddingTop="24dp"
+                        android:text="@string/ring_account"
+                        android:textAppearance="@style/Base.TextAppearance.AppCompat.Large" />
 
-    </RelativeLayout>
+                    <ImageButton
+                        android:id="@+id/account_edit_btn"
+                        style="@style/Widget.AppCompat.Button.Borderless"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="bottom"
+                        android:background="?selectableItemBackgroundBorderless"
+                        app:srcCompat="@drawable/ic_settings_black_24dp" />
+
+                </LinearLayout>
+
+                <TextView
+                    android:id="@+id/account_id_txt"
+                    style="@style/Subheader"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:ellipsize="middle"
+                    android:gravity="center_vertical"
+                    android:lines="1"
+                    android:paddingBottom="8dp"
+                    android:paddingLeft="16dp"
+                    android:paddingRight="16dp"
+                    android:paddingTop="4dp"
+                    android:textIsSelectable="false"
+                    tools:text="ring:8F29045378ACA68F2ACA2346078ACA68F2ACA290" />
+
+                <LinearLayout
+                    android:id="@+id/group_register_name"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_margin="16dp"
+                    android:gravity="center_horizontal"
+                    android:orientation="vertical">
+
+                    <TextView
+                        android:id="@+id/register_name_help_txt"
+                        style="@style/Subheader"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:gravity="center_vertical"
+                        android:paddingBottom="8dp"
+                        android:paddingTop="8dp"
+                        android:text="@string/no_registered_name_for_account" />
+
+                    <Button
+                        android:id="@+id/register_name_btn"
+                        style="@style/Widget.AppCompat.Button.Colored"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:paddingEnd="16dp"
+                        android:paddingStart="16dp"
+                        android:text="@string/register_name" />
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:id="@+id/group_registering_name"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_margin="16dp"
+                    android:orientation="horizontal"
+                    android:visibility="gone">
+
+                    <TextView
+                        android:id="@+id/textView"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:text="@string/trying_to_register_name" />
+
+                    <ProgressBar
+                        android:id="@+id/progressBar"
+                        style="?android:attr/progressBarStyleSmall"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content" />
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:id="@+id/group_registered_name"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_margin="16dp"
+                    android:orientation="horizontal"
+                    android:visibility="gone">
+
+                    <TextView
+                        android:id="@+id/registred_name_help_txt"
+                        style="@style/Subheader"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:gravity="center_vertical"
+                        android:paddingBottom="16dp"
+                        android:paddingEnd="16dp"
+                        android:paddingRight="16dp"
+                        android:paddingTop="4dp"
+                        android:text="@string/registered_username" />
+
+                    <TextView
+                        android:id="@+id/registered_name_txt"
+                        style="@style/Base.TextAppearance.AppCompat.Title"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:paddingBottom="16dp"
+                        android:paddingEnd="8dp"
+                        android:paddingLeft="16dp"
+                        android:paddingRight="8dp"
+                        android:paddingStart="16dp"
+                        android:paddingTop="4dp"
+                        tools:text="Wagaf"
+                        android:textAlignment="viewStart"
+                        android:layout_gravity="start"/>
+                </LinearLayout>
+
+                <TextView
+                    android:id="@+id/headerText"
+                    style="@style/Subheader"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_vertical"
+                    android:paddingBottom="8dp"
+                    android:paddingEnd="16dp"
+                    android:paddingStart="16dp"
+                    android:paddingTop="8dp"
+                    android:text="@string/normal_devices_titles" />
+
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="1dip"
+                    android:background="?android:attr/listDivider" />
+
+                <FrameLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+
+                    <ListView
+                        android:id="@+id/device_list"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:divider="#CCCCCC"
+                        android:dividerHeight="1dp"
+                        android:footerDividersEnabled="true"
+                        android:headerDividersEnabled="true" />
+
+                    <TextView
+                        android:id="@+id/empty_account_list"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center"
+                        android:gravity="center"
+                        android:text="@string/empty_account_list"
+                        android:textAppearance="?android:attr/textAppearanceMedium"
+                        android:textColor="@color/text_color_secondary"
+                        android:visibility="gone" />
+
+                </FrameLayout>
+
+            </LinearLayout>
+        </android.support.v7.widget.CardView>
+    </cx.ring.views.BoundedScrollView>
 
     <include
         layout="@layout/add_new_device_layout"
-        android:layout_gravity="bottom"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content" />
-</FrameLayout>
\ No newline at end of file
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom" />
+</FrameLayout>
diff --git a/ring-android/app/src/main/res/layout/frag_register_name.xml b/ring-android/app/src/main/res/layout/frag_register_name.xml
new file mode 100644
index 0000000..f03ce48
--- /dev/null
+++ b/ring-android/app/src/main/res/layout/frag_register_name.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingTop="16dp">
+
+    <android.support.design.widget.TextInputLayout
+        android:id="@+id/ring_username_txt_box"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="16dp"
+        android:layout_marginLeft="12dp"
+        android:layout_marginRight="12dp">
+
+        <android.support.design.widget.TextInputEditText
+            android:id="@+id/ring_username"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/prompt_new_username"
+            android:imeOptions="actionNext"
+            android:inputType="text"
+            android:lines="1"
+            android:maxLines="1" />
+    </android.support.design.widget.TextInputLayout>
+
+    <android.support.design.widget.TextInputLayout
+        android:id="@+id/ring_password_txt_box"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="16dp"
+        android:layout_marginLeft="12dp"
+        android:layout_marginRight="12dp">
+
+        <android.support.design.widget.TextInputEditText
+            android:id="@+id/ring_password_txt"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/account_new_device_password"
+            android:imeOptions="actionDone"
+            android:inputType="textPassword"
+            android:lines="1"
+            android:maxLines="1" />
+    </android.support.design.widget.TextInputLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/item_device.xml b/ring-android/app/src/main/res/layout/item_device.xml
index e340b3d..59e0dc3 100644
--- a/ring-android/app/src/main/res/layout/item_device.xml
+++ b/ring-android/app/src/main/res/layout/item_device.xml
@@ -25,7 +25,6 @@
         android:id="@+id/icon_device"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
         android:layout_alignParentStart="true"
         android:layout_centerVertical="true"
         app:srcCompat="@drawable/ic_desktop_windows_black_24dp" />
@@ -34,10 +33,8 @@
         android:id="@+id/txt_device_label"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
         android:layout_alignParentStart="true"
         android:layout_centerVertical="true"
-        android:layout_marginLeft="56dp"
         android:layout_marginStart="56dp"
         android:text="8E24CCF4"
         android:textAppearance="@style/ListPrimary" />
@@ -48,10 +45,8 @@
         android:layout_height="wrap_content"
         android:layout_alignBaseline="@+id/txt_device_label"
         android:layout_alignParentEnd="true"
-        android:layout_alignParentRight="true"
-        android:layout_marginLeft="24dp"
         android:layout_marginStart="24dp"
-        android:layout_toRightOf="@+id/txt_device_label"
+        android:layout_toEndOf="@+id/txt_device_label"
         android:ellipsize="middle"
         android:maxLines="1"
         android:text="e3806a4963993ed1e8adc5c0ed9809c354dfc872"
diff --git a/ring-android/app/src/main/res/values-w820dp/dimens.xml b/ring-android/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/ring-android/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/ring-android/app/src/main/res/values/colors.xml b/ring-android/app/src/main/res/values/colors.xml
index 3f90077..c2e8bcf 100644
--- a/ring-android/app/src/main/res/values/colors.xml
+++ b/ring-android/app/src/main/res/values/colors.xml
@@ -17,7 +17,7 @@
     <color name="sfl_light_blue">#006f82</color>
 
     <color name="lighter_gray">#ddd</color>
-    <color name="darker_gray">#aaa</color>
+    <color name="darker_gray">#aaaaaa</color>
     <color name="light">#eee</color>
 
     <color name="text_shadow">#054b55</color>
diff --git a/ring-android/app/src/main/res/values/strings.xml b/ring-android/app/src/main/res/values/strings.xml
index 76f4a73..e6c6059 100644
--- a/ring-android/app/src/main/res/values/strings.xml
+++ b/ring-android/app/src/main/res/values/strings.xml
@@ -170,6 +170,14 @@
     <string name="add_call_contact_number_to_contacts">Add %1$s ?</string>
     <string name="prompt_new_password">New password</string>
     <string name="prompt_new_password_repeat">Repeat new password</string>
+    <string name="account_create_title">Create a Ring account</string>
+    <string name="help_username_register">Choose a Ring username that will be registered in the public blockchain-based registry.</string>
+    <string name="prompt_new_username">Enter new username</string>
+    <string name="help_password_choose">Choose a strong password you will remember to protect your Ring account.</string>
+    <string name="btn_use_existing_account">Use an existing Ring account instead</string>
+    <string name="btn_create_account">Create new account instead</string>
+    <string name="help_password_enter">Enter your main Ring account password</string>
+    <string name="help_pin_enter">Enter the PIN from another configured Ring account. Use the \"export account on Ring\" feature to obtain a PIN.</string>
 
     <string name="account_device_updated_message">You have successfully updated your Ring account.</string>
 
diff --git a/ring-android/app/src/main/res/values/strings_account.xml b/ring-android/app/src/main/res/values/strings_account.xml
index c5136f2..1d816ec 100644
--- a/ring-android/app/src/main/res/values/strings_account.xml
+++ b/ring-android/app/src/main/res/values/strings_account.xml
@@ -25,7 +25,7 @@
     <string name="prompt_hostname">Hostname</string>
     <string name="prompt_username">Username</string>
     <string name="prompt_password">Password</string>
-    <string name="action_create">Add account</string>
+    <string name="action_create">Create account</string>
     <string name="action_create_short">Register</string>
     <string name="error_field_required">This field is required</string>
     <string name="dialog_wait_create">Adding account</string>
@@ -146,7 +146,7 @@
     <string name="account_restore_decryption_password">Decryption password</string>
     <string name="account_new_device">Add new device</string>
     <string name="account_new_device_message">Unlock Ring account to associate new device.</string>
-    <string name="account_new_device_password">Enter main account password</string>
+    <string name="account_new_device_password">Enter main password to unlock account</string>
 
     <string name="restore_dialog_title">Restoring</string>
     <string name="restore_backup_wait">Please wait…</string>
@@ -190,6 +190,7 @@
     <string name="account_device_updated_title">Account device updated</string>
 
     <string name="account_link_button">Link this device to an account</string>
+    <string name="account_import_title">Link to an existing account</string>
     <string name="account_link_prompt_password">Enter your password</string>
     <string name="account_link_prompt_pin">Enter PIN</string>
     <string name="account_wizard_title">Ring account</string>
@@ -201,4 +202,20 @@
     <string name="account_start_export_button">Generate Pin</string>
     <string name="account_end_export_button">close</string>
     <string name="account_end_export_infos">Your Pin is:\n\n%%\n\nTo complete the process, you need to open Ring on the new device. Create a new account with \"Link this device to an account\". Your pin is valid for 10 minutes.</string>
+
+    <!-- Name registration -->
+    <string name="register_name_wrong_password">Can\'t register name: wrong account password.</string>
+    <string name="register_name_invalid">Can\'t register name: invalid name.</string>
+    <string name="register_name_already_taken">Can\'t register name: name already taken.</string>
+    <string name="register_name_network_error">Can\'t register name: network or server error.</string>
+    <string name="error_username_empty">Enter a username</string>
+    <string name="no_registered_name_for_account">No registered name found for this account</string>
+    <string name="register_name">Register name</string>
+    <string name="trying_to_register_name">Trying to register name</string>
+    <string name="registered_username">Registered username</string>
+    <string name="register_username">Register a public Ring username that will be stored in the public blockchain registry</string>
+    <string name="username_already_taken">Username already taken</string>
+    <string name="invalid_username">Invalid username</string>
+    <string name="looking_for_username_availability">Looking for username availability ...</string>
+
 </resources>