From 390147ee2b00689a897a0d59622336c5659caba9 Mon Sep 17 00:00:00 2001
From: Francesco Andreuzzi <andreuzzi.francesco@gmail.com>
Date: Tue, 13 Jun 2017 19:12:14 +0200
Subject: [PATCH] 5.3

---
 app/build.gradle                              |   6 +-
 app/proguard-rules.pro                        |   6 +-
 app/src/main/AndroidManifest.xml              |  45 +-
 .../consolelauncher/LauncherActivity.java     | 171 +++-
 .../andre/consolelauncher/MainManager.java    | 104 ++-
 .../ohi/andre/consolelauncher/UIManager.java  | 180 +++-
 .../consolelauncher/commands/Command.java     |  34 +-
 .../commands/CommandAbstraction.java          |  13 +-
 .../commands/CommandGroup.java                |   2 -
 .../commands/CommandTuils.java                | 144 +++-
 .../commands/CommandsPreferences.java         |   6 +-
 .../consolelauncher/commands/ExecutePack.java |   4 +
 .../commands/main/MainPack.java               |  21 +-
 .../consolelauncher/commands/main/Param.java  |  14 +
 .../commands/main/raw/about.java              |  58 --
 .../commands/main/raw/airplane.java           |   9 +-
 .../commands/main/raw/alias.java              |   9 +-
 .../commands/main/raw/aliasfile.java          |  82 --
 .../commands/main/raw/apps.java               | 170 ++--
 .../commands/main/raw/beep.java               |  63 ++
 .../commands/main/raw/bluetooth.java          |   9 +-
 .../commands/main/raw/calc.java               |   7 +-
 .../commands/main/raw/call.java               |  32 +-
 .../consolelauncher/commands/main/raw/cd.java |   7 +-
 .../commands/main/raw/clear.java              |   9 +-
 .../commands/main/raw/cntcts.java             | 185 +++++
 .../commands/main/raw/config.java             | 119 +++
 .../consolelauncher/commands/main/raw/cp.java |   7 +-
 .../commands/main/raw/data.java               |   7 +-
 .../commands/main/raw/donate.java             |   9 +-
 .../commands/main/raw/exit.java               |  53 ++
 .../commands/main/raw/flash.java              |  11 +-
 .../commands/main/raw/help.java               |   7 +-
 .../commands/main/raw/hideapp.java            |   9 +-
 .../commands/main/raw/listen.java             |   7 +-
 .../commands/main/raw/location.java           | 108 +++
 .../consolelauncher/commands/main/raw/ls.java |   7 +-
 .../consolelauncher/commands/main/raw/mv.java |   7 +-
 .../commands/main/raw/next.java               |   9 +-
 .../commands/main/raw/notifications.java      | 134 +++
 .../commands/main/raw/open.java               |   7 +-
 .../commands/main/raw/previous.java           |   9 +-
 .../commands/main/raw/rate.java               |   9 +-
 .../commands/main/raw/refresh.java            |  15 +-
 .../commands/main/raw/remove.java             |  66 --
 .../commands/main/raw/restart.java            |   9 +-
 .../consolelauncher/commands/main/raw/rm.java |   7 +-
 .../commands/main/raw/search.java             | 189 +++--
 .../commands/main/raw/share.java              |   7 +-
 .../commands/main/raw/shellcommands.java      |   8 +-
 .../commands/main/raw/sms.java                |  21 +-
 .../commands/main/raw/status.java             |   9 +-
 .../commands/main/raw/stop.java               |   9 +-
 .../commands/main/raw/time.java               |  10 +-
 .../commands/main/raw/track.java              |   9 +-
 .../commands/main/raw/tracks.java             |   9 +-
 .../commands/main/raw/tui.java                | 119 +++
 .../commands/main/raw/tuisettings.java        |  84 --
 .../commands/main/raw/tuixt.java              |   8 +-
 .../commands/main/raw/tutorial.java           |   9 +-
 .../commands/main/raw/unhideapp.java          |   7 +-
 .../commands/main/raw/uninstall.java          |  11 +-
 .../commands/main/raw/vibrate.java            |  72 ++
 .../commands/main/raw/wifi.java               |   9 +-
 .../commands/specific/ParamCommand.java       |  44 +
 .../commands/tuixt/TuixtActivity.java         |  17 +-
 .../commands/tuixt/TuixtPack.java             |   2 -
 .../commands/tuixt/raw/exit.java              |   9 +-
 .../commands/tuixt/raw/help.java              |   8 +-
 .../commands/tuixt/raw/save.java              |   9 +-
 .../managers/AliasManager.java                |  93 ++-
 .../consolelauncher/managers/AppsManager.java | 591 +++++++++----
 .../managers/ContactManager.java              | 311 ++++++-
 .../consolelauncher/managers/FileManager.java |  55 +-
 .../managers/MusicManager.java                |  47 +-
 .../managers/PreferencesManager.java          | 322 --------
 .../consolelauncher/managers/SkinManager.java | 292 +++----
 .../managers/TerminalMAnager.java             |  72 +-
 .../managers/XMLPrefsManager.java             | 774 ++++++++++++++++++
 .../notifications/NotificationManager.java    | 282 +++++++
 .../notifications/NotificationService.java    | 131 +++
 .../suggestions/SuggestionRunnable.java       |  17 +
 .../suggestions/SuggestionsManager.java       | 207 +++--
 .../andre/consolelauncher/tuils/Assist.java   |  85 ++
 .../consolelauncher/tuils/KeeperService.java  |   1 -
 .../consolelauncher/tuils/ShellUtils.java     | 327 +++-----
 .../tuils/SquareImageView.java                |   2 -
 .../tuils/StoppableThread.java                |  22 +
 .../andre/consolelauncher/tuils/Tuils.java    |  81 +-
 .../tuils/interfaces/Inputable.java           |   2 +
 .../tuils/interfaces/OnNewInputListener.java  |   9 -
 .../tuils/stuff/FakeLauncherActivity.java     |   9 +
 app/src/main/res/layout/input_down_layout.xml |  37 +-
 app/src/main/res/raw/alias.txt                |   6 -
 app/src/main/res/raw/settings.txt             |  69 --
 app/src/main/res/values/strings.xml           |  87 +-
 app/src/main/res/values/styles.xml            |   2 +
 build.gradle                                  |   2 +-
 98 files changed, 4580 insertions(+), 2040 deletions(-)
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/Param.java
 delete mode 100755 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/about.java
 delete mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/aliasfile.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/beep.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cntcts.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/exit.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/location.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/notifications.java
 delete mode 100755 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/remove.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tui.java
 delete mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuisettings.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/vibrate.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/specific/ParamCommand.java
 delete mode 100755 app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java
 create mode 100755 app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationManager.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationService.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/tuils/Assist.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/tuils/StoppableThread.java
 delete mode 100644 app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnNewInputListener.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/tuils/stuff/FakeLauncherActivity.java
 delete mode 100755 app/src/main/res/raw/alias.txt
 delete mode 100755 app/src/main/res/raw/settings.txt

diff --git a/app/build.gradle b/app/build.gradle
index 8c55618..9803dca 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,15 +2,15 @@ apply plugin: 'com.android.application'
 android {
 
     compileSdkVersion 25
-    buildToolsVersion '25.0.1'
+    buildToolsVersion '25.0.2'
     defaultConfig {
         applicationId "ohi.andre.consolelauncher"
 
         minSdkVersion 8
         targetSdkVersion 23
 
-        versionCode 88
-        versionName "5.2.1"
+        versionCode 90
+        versionName "5.3b"
     }
 
     buildTypes {
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 49853cc..0f65de5 100755
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -6,4 +6,8 @@
 
 -keepclassmembers class * extends com.stephentuso.welcome.WelcomeActivity {
     public static java.lang.String welcomeKey();
-}
\ No newline at end of file
+}
+
+-dontwarn javax.annotation.**
+-dontwarn javax.inject.**
+-dontwarn sun.misc.Unsafe
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6ccc615..4f04de9 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -19,11 +19,17 @@
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.SEND_SMS" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
 
     <permission
         android:name="android.permission.FLASHLIGHT"
@@ -51,6 +57,8 @@
     <uses-feature
         android:name="android.hardware.bluetooth"
         android:required="false" />
+    <uses-feature android:name="android.hardware.location.gps"
+        android:required="false"/>
 
     <!-- t-ui -->
     <application
@@ -61,9 +69,14 @@
         <activity
             android:name=".LauncherActivity"
             android:configChanges="keyboardHidden|orientation|screenSize"
-            android:excludeFromRecents="true"
+
             android:launchMode="singleTask"
+            android:clearTaskOnLaunch="true"
             android:stateNotNeeded="true"
+            android:resumeWhilePausing="true"
+            android:taskAffinity=""
+            android:enabled="true"
+
             android:windowSoftInputMode="stateAlwaysVisible|adjustResize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -96,7 +109,10 @@
             android:name=".commands.tuixt.TuixtActivity"
             android:theme="@style/Custom.Solid"
             android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
-            android:label="@string/tuixt_label">
+            android:label="@string/tuixt_label"
+
+            android:excludeFromRecents="true"
+            android:noHistory="true">
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value=".LauncherActivity" />
@@ -162,12 +178,35 @@
 
         <activity android:name=".tuils.tutorial.TutorialActivity"
             android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen"
-            android:windowSoftInputMode="stateAlwaysHidden">
+            android:windowSoftInputMode="stateAlwaysHidden"
+
+            android:excludeFromRecents="true">
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value=".LauncherActivity" />
         </activity>
 
+        <service android:name=".managers.notifications.NotificationService"
+            android:label="@string/notification_reader"
+            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
+            android:stopWithTask="true">
+
+            <intent-filter>
+                <action android:name="android.service.notification.NotificationListenerService" />
+            </intent-filter>
+
+        </service>
+
+        <activity
+            android:name=".tuils.stuff.FakeLauncherActivity"
+            android:enabled="false">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.HOME" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
     </application>
 
 </manifest>
\ No newline at end of file
diff --git a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
index bac18e8..5dea24c 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
@@ -2,10 +2,14 @@ package ohi.andre.consolelauncher;
 
 import android.Manifest;
 import android.annotation.TargetApi;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
@@ -13,11 +17,15 @@ import android.content.res.Resources;
 import android.graphics.Color;
 import android.os.Build;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.content.ContextCompat;
+import android.support.v4.content.LocalBroadcastManager;
 import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
+import android.view.ContextMenu;
 import android.view.KeyEvent;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
@@ -28,7 +36,11 @@ import java.io.IOException;
 
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.tuixt.TuixtActivity;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.ContactManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
+import ohi.andre.consolelauncher.managers.suggestions.SuggestionsManager;
+import ohi.andre.consolelauncher.tuils.Assist;
 import ohi.andre.consolelauncher.tuils.KeeperService;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
@@ -53,8 +65,6 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
 
     private boolean openKeyboardOnStart, fullscreen;
 
-    private PreferencesManager preferencesManager;
-
     private Intent starterIntent;
 
     private CommandExecuter ex = new CommandExecuter() {
@@ -80,6 +90,26 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
                 e.printStackTrace();
             }
         }
+
+        @Override
+        public void changeHint(final String s) {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    ui.setHint(s);
+                }
+            });
+        }
+
+        @Override
+        public void resetHint() {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    ui.resetHint();
+                }
+            });
+        }
     };
 
     private Outputable out = new Outputable() {
@@ -102,16 +132,6 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
             return;
         }
 
-        SharedPreferences preferences = getPreferences(0);
-        boolean firstAccess = preferences.getBoolean(FIRSTACCESS_KEY, true);
-        if (firstAccess) {
-            SharedPreferences.Editor editor = preferences.edit();
-            editor.putBoolean(FIRSTACCESS_KEY, false);
-            editor.commit();
-
-            startActivity(new Intent(this, TutorialActivity.class));
-        }
-
         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             if (!(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED  &&
                     ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) {
@@ -127,19 +147,30 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
 
     private void finishOnCreate() {
 
-        File tuiFolder = Tuils.getFolder();
-        Resources res = getResources();
+        SharedPreferences preferences = getPreferences(0);
+        boolean firstAccess = preferences.getBoolean(FIRSTACCESS_KEY, true);
+        if (firstAccess) {
+            SharedPreferences.Editor editor = preferences.edit();
+            editor.putBoolean(FIRSTACCESS_KEY, false);
+            editor.commit();
+
+            Intent intent = new Intent(this, TutorialActivity.class);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            startActivity(intent);
+        }
+
         starterIntent = getIntent();
 
         try {
-            preferencesManager = new PreferencesManager(res.openRawResource(R.raw.settings), res.openRawResource(R.raw.alias), tuiFolder);
-        } catch (IOException e) {
-            this.startActivity(new Intent(this, LauncherActivity.class));
-            this.finish();
+            XMLPrefsManager.create();
+        } catch (Exception e) {
+            Log.e("andre", "", e);
+//            this.startActivity(new Intent(this, LauncherActivity.class));
+//            this.finish();
             return;
         }
 
-        boolean showNotification = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.NOTIFICATION));
+        boolean showNotification = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.tui_notification);
         Intent keeperIntent = new Intent(this, KeeperService.class);
         if (showNotification) {
             startService(keeperIntent);
@@ -150,9 +181,9 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         DevicePolicyManager policy = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
         ComponentName component = new ComponentName(this, PolicyReceiver.class);
 
-        fullscreen = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.FULLSCREEN));
+        fullscreen = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.fullscreen);
 
-        boolean useSystemWP = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.USE_SYSTEMWP));
+        boolean useSystemWP = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.system_wallpaper);
         if (useSystemWP) {
             if(fullscreen) {
                 setTheme(R.style.Custom_SystemWP_Fullscreen);
@@ -167,7 +198,16 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
             }
         }
 
-        openKeyboardOnStart = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.OPEN_KEYBOARD));
+        NotificationManager.create();
+        boolean notifications = NotificationManager.get(boolean.class, NotificationManager.Options.enabled);
+        if(notifications) {
+            LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));
+            if(!Tuils.hasNotificationAccess(this)) {
+                startActivity(new Intent(Build.VERSION.SDK_INT >= 22 ? Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS : "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
+            }
+        }
+
+        openKeyboardOnStart = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.auto_show_keyboard);
         if (!openKeyboardOnStart) {
             this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
         }
@@ -175,13 +215,15 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         setContentView(R.layout.base_view);
 
         ViewGroup mainView = (ViewGroup) findViewById(R.id.mainview);
-        main = new MainManager(this, in, out, preferencesManager, policy, component);
-        ui = new UIManager(main.getMainPack(), this, mainView, ex, policy, component, preferencesManager, main.getMainPack());
+        main = new MainManager(this, in, out, policy, component);
+        ui = new UIManager(main.getMainPack(), this, mainView, ex, policy, component, main.getMainPack());
         main.setRedirectionListener(ui.buildRedirectionListener());
 
         in.in(Tuils.EMPTYSTRING);
         ui.focusTerminal();
 
+        if(fullscreen) Assist.assistActivity(this);
+
         System.gc();
     }
 
@@ -208,6 +250,8 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
     protected void onDestroy() {
         super.onDestroy();
 
+        stopService(new Intent(this, KeeperService.class));
+
         if(main != null) {
             main.destroy();
         }
@@ -235,20 +279,28 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
-                    reloadOver11();
-                } else {
-                    finish();
-                    startActivity(starterIntent);
-                }
+//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+//                    reloadOver11();
+//                } else {
+//                    finish();
+//                    startActivity(starterIntent);
+//                }
+
+                Intent mStartActivity = new Intent(LauncherActivity.this, LauncherActivity.class);
+                int mPendingIntentId = 123456;
+                PendingIntent mPendingIntent = PendingIntent.getActivity(LauncherActivity.this, mPendingIntentId, mStartActivity,
+                        PendingIntent.FLAG_CANCEL_CURRENT);
+                AlarmManager mgr = (AlarmManager) LauncherActivity.this.getSystemService(Context.ALARM_SERVICE);
+                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
+                System.exit(0);
             }
         });
     }
 
-    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
-    private void reloadOver11() {
-        recreate();
-    }
+//    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+//    private void reloadOver11() {
+//        recreate();
+//    }
 
     @Override
     public void onWindowFocusChanged(boolean hasFocus) {
@@ -259,6 +311,39 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         }
     }
 
+    SuggestionsManager.Suggestion suggestion;
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+        super.onCreateContextMenu(menu, v, menuInfo);
+
+        suggestion = (SuggestionsManager.Suggestion) v.getTag(R.id.suggestion_id);
+
+        if(suggestion.type == SuggestionsManager.Suggestion.TYPE_CONTACT) {
+            ContactManager.Contact contact = (ContactManager.Contact) suggestion.object;
+
+            menu.setHeaderTitle(contact.name);
+            for(int count = 0; count < contact.numbers.size(); count++) {
+                menu.add(0, count, count, contact.numbers.get(count));
+            }
+        }
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        if(suggestion != null) {
+            if(suggestion.type == SuggestionsManager.Suggestion.TYPE_CONTACT) {
+                ContactManager.Contact contact = (ContactManager.Contact) suggestion.object;
+                contact.selectedNumber = item.getItemId();
+
+                in.in(suggestion.getText());
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
@@ -314,4 +399,20 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         if(ui != null) ui.scrollToEnd();
     }
 
+    private BroadcastReceiver onNotice = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+//            Log.e("andre", "received");
+
+            String pack = intent.getStringExtra("package");
+            String title = intent.getStringExtra("title");
+            String text = intent.getStringExtra("text");
+
+            if(ui != null) {
+                ui.setOutput(pack + ": " + (title == null ? Tuils.EMPTYSTRING : title + (text == null ? Tuils.EMPTYSTRING : " --- ")) + (text == null ? Tuils.EMPTYSTRING : text), intent.getIntExtra("color", Color.RED));
+            }
+        }
+    };
+
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
index d60f8c6..874bade 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
@@ -4,6 +4,7 @@ import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Handler;
 import android.os.Looper;
 import android.util.Log;
 
@@ -17,8 +18,10 @@ import ohi.andre.consolelauncher.managers.AliasManager;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.MusicManager;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
 import ohi.andre.consolelauncher.tuils.ShellUtils;
+import ohi.andre.consolelauncher.tuils.StoppableThread;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
 import ohi.andre.consolelauncher.tuils.interfaces.Inputable;
@@ -89,14 +92,36 @@ public class MainManager {
     private Outputable out;
 
     private boolean showAliasValue;
+    private boolean showAppHistory;
 
-    protected MainManager(LauncherActivity c, Inputable i, Outputable o, PreferencesManager prefsMgr, DevicePolicyManager devicePolicyManager, ComponentName componentName) {
+    private Handler handler = new Handler();
+
+    private Thread thread;
+    private boolean busy = false;
+    private void busy() {
+        busy = true;
+
+//        i do this because i don't want to change the hint every single time (users would complain)
+        handler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                if(busy) in.changeHint(mContext.getString(R.string.busy_hint));
+            }
+        }, 650);
+    }
+    private void notBusy() {
+        busy = false;
+        in.resetHint();
+    }
+
+    protected MainManager(LauncherActivity c, Inputable i, Outputable o, DevicePolicyManager devicePolicyManager, ComponentName componentName) {
         mContext = c;
 
         in = i;
         out = o;
 
-        showAliasValue = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOW_ALIAS_VALUE));
+        showAliasValue = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.show_alias_content);
+        showAppHistory = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.show_launch_history);
 
         CommandGroup group = new CommandGroup(mContext, COMMANDS_PKG);
 
@@ -113,17 +138,28 @@ public class MainManager {
             }
         };
 
-        MusicManager music = new MusicManager(mContext, prefsMgr, out);
+        MusicManager music = new MusicManager(mContext, out);
 
-        AppsManager appsMgr = new AppsManager(c, Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.COMPARESTRING_APPS)), out);
-        AliasManager aliasManager = new AliasManager(prefsMgr);
+        AppsManager appsMgr = new AppsManager(c, out);
+        AliasManager aliasManager = new AliasManager();
 
-        mainPack = new MainPack(mContext, prefsMgr, group, aliasManager, appsMgr, music, cont, devicePolicyManager, componentName, c, executer, out, redirectator);
+        mainPack = new MainPack(mContext, group, aliasManager, appsMgr, music, cont, devicePolicyManager, componentName, c, executer, out, redirectator);
     }
 
-    //    command manager
+//    command manager
     public void onCommand(String input, String alias) {
 
+        if(busy) {
+            if(input.equalsIgnoreCase("ctrlc")) {
+                thread.interrupt();
+                notBusy();
+                return;
+            }
+
+            out.onOutput(mContext.getString(R.string.busy));
+            return;
+        }
+
         input = Tuils.removeUnncesarySpaces(input);
 
         if(redirect != null) {
@@ -199,29 +235,34 @@ public class MainManager {
         final int COMMAND_NOTFOUND = 127;
 
         @Override
-        public boolean trigger(final ExecutePack info, String input) throws Exception {
+        public boolean trigger(final ExecutePack info, final String input) throws Exception {
 
 //            this is the last trigger, it has to say "command not found"
 
-            boolean su = false;
-            if (CommandTuils.isSuCommand(input)) {
-                su = true;
-                input = input.substring(3);
-                if (input.startsWith(ShellUtils.COMMAND_SU_ADD + Tuils.SPACE)) {
-                    input = input.substring(3);
-                }
-            }
+//            boolean su = false;
+//            if (CommandTuils.isSuCommand(input)) {
+//                su = true;
+//                input = input.substring(3);
+//                if (input.startsWith(ShellUtils.COMMAND_SU_ADD + Tuils.SPACE)) {
+//                    input = input.substring(3);
+//                }
+//            }
 
             final String cmd = input;
-            final boolean useSU = su;
+            final boolean useSU = false;
 
-            new Thread() {
+            thread = new StoppableThread() {
                 @Override
                 public void run() {
                     super.run();
 
-                    ShellUtils.CommandResult result = ShellUtils.execCommand(cmd, useSU, mainPack.currentDirectory.getAbsolutePath());
-                    if (result.result == COMMAND_NOTFOUND) {
+                    busy();
+
+                    if(Thread.interrupted()) return;
+                    ShellUtils.CommandResult result = ShellUtils.execCommand(new String[] {cmd}, useSU, mainPack.currentDirectory.getAbsolutePath(), out);
+                    if(Thread.interrupted()) return;
+
+                    if (result == null || result.result == COMMAND_NOTFOUND || result.result == -1) {
                         out.onOutput(mContext.getString(R.string.output_commandnotfound));
                     } else {
                         String output = result.toString();
@@ -233,8 +274,11 @@ public class MainManager {
                         }
                         out.onOutput(output);
                     }
+
+                    notBusy();
                 }
-            }.start();
+            };
+            thread.start();
 
             return true;
         }
@@ -254,7 +298,7 @@ public class MainManager {
                 return false;
             }
 
-            out.onOutput("-->" + Tuils.SPACE + intent.getComponent().getClassName());
+            if(showAppHistory) out.onOutput("-->" + Tuils.SPACE + intent.getComponent().getClassName());
 
             mContext.startActivity(intent);
 
@@ -268,11 +312,13 @@ public class MainManager {
         public boolean trigger(final ExecutePack info, final String input) throws Exception {
 
             final boolean[] returnValue = new boolean[1];
-            Thread t = new Thread() {
+            thread = new StoppableThread() {
                 @Override
                 public void run() {
                     super.run();
 
+                    busy();
+
                     Looper.prepare();
 
                     mainPack.lastCommand = input;
@@ -286,20 +332,24 @@ public class MainManager {
                         }
 
                         if (returnValue[0]) {
-
+                            if(Thread.interrupted()) return;
                             String output = command.exec(mContext.getResources(), info);
+                            if(Thread.interrupted()) return;
+
                             if(output != null) {
                                 out.onOutput(output);
                             }
                         }
                     } catch (Exception e) {
-                        Log.e("andre", "", e);
                         out.onOutput(e.toString());
+                        Log.e("andre", "", e);
                     }
+
+                    notBusy();
                 }
             };
 
-            t.start();
+            thread.start();
 
             synchronized (returnValue) {
                 returnValue.wait();
diff --git a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
index 118646d..7484bc6 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
@@ -6,7 +6,6 @@ import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Typeface;
-import android.os.Build;
 import android.os.Handler;
 import android.text.Editable;
 import android.text.TextWatcher;
@@ -31,14 +30,14 @@ import java.lang.reflect.Field;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.specific.RedirectCommand;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.managers.TerminalManager;
 import ohi.andre.consolelauncher.managers.suggestions.SuggestionRunnable;
 import ohi.andre.consolelauncher.managers.suggestions.SuggestionsManager;
+import ohi.andre.consolelauncher.tuils.StoppableThread;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
-import ohi.andre.consolelauncher.tuils.interfaces.OnNewInputListener;
 import ohi.andre.consolelauncher.tuils.interfaces.OnRedirectionListener;
 import ohi.andre.consolelauncher.tuils.interfaces.SuggestionViewDecorer;
 import ohi.andre.consolelauncher.tuils.stuff.TrashInterfaces;
@@ -81,6 +80,7 @@ public class UIManager implements OnTouchListener {
     private SuggestionRunnable suggestionRunnable;
     private LinearLayout.LayoutParams suggestionViewParams;
     private SuggestionsManager suggestionsManager;
+    private boolean navigatingWithSpace = false;
 
     private TextView terminalView;
     private Thread lastSuggestionThread;
@@ -92,20 +92,59 @@ public class UIManager implements OnTouchListener {
         }
     };
 
-    boolean doubleTapSU = false;
+    private String doubleTapCmd;
+    private boolean lockOnDbTap;
 
     protected TextWatcher textWatcher = new TextWatcher() {
 
+        int nOfSpace = -1;
+        String originalText;
+
+        boolean call = true;
+
         @Override
         public void beforeTextChanged(CharSequence s, int start, int count, int after) {
         }
 
         @Override
         public void onTextChanged(CharSequence s, int st, int b, int c) {
-            if (suggestionsView == null || suggestionsManager == null || !showSuggestions) {
+            if (suggestionsView == null || suggestionsManager == null || !showSuggestions || !call) {
                 return;
             }
 
+            if(st == s.length() - 1 && b == 0 && c == 1 && s.subSequence(st, s.length()).toString().equals(Tuils.SPACE)) {
+                nOfSpace++;
+                originalText = s.toString();
+            } else {
+                nOfSpace = -1;
+                originalText = null;
+                navigatingWithSpace = false;
+            }
+
+            if(nOfSpace == suggestionsView.getChildCount() + 1) {
+                nOfSpace = -2;
+                navigatingWithSpace = false;
+            }
+
+            if(nOfSpace >= 0) {
+                if(nOfSpace == 1 && suggestionsView.getChildCount() == 1) {
+                    nOfSpace = -1;
+                    originalText = null;
+                    navigatingWithSpace = false;
+                } else {
+                    for(int count = 0; count < suggestionsView.getChildCount(); count++) {
+                        SuggestionsManager.Suggestion suggestion = (SuggestionsManager.Suggestion) suggestionsView.getChildAt(count).getTag(R.id.suggestion_id);
+                        if(originalText.trim().endsWith(suggestion.text)) {
+                            nOfSpace = -1;
+                            originalText = null;
+                            navigatingWithSpace = false;
+                            break;
+                        }
+                        if(count == suggestionsView.getChildCount() - 1) return;
+                    }
+                }
+            }
+
             String text = s.toString();
             int lastSpace = text.lastIndexOf(Tuils.SPACE);
 
@@ -116,24 +155,71 @@ public class UIManager implements OnTouchListener {
         }
 
         @Override
-        public void afterTextChanged(Editable s) {}
+        public void afterTextChanged(Editable s) {
+            if(nOfSpace == -2) {
+                s.replace(0,s.length(),originalText);
+                originalText = null;
+                return;
+            }
+
+            if(nOfSpace > 0 && s.length() > 0 && call) {
+
+                if(nOfSpace == 1) {
+                    call = false;
+                    s.replace(s.length() - 1, s.length(), Tuils.EMPTYSTRING);
+                    call = true;
+                }
+
+                navigatingWithSpace = true;
+
+                call = false;
+                s.replace(s.length() - 1, s.length(), Tuils.EMPTYSTRING);
+                call = true;
+
+//                int count = suggestionsView.getChildCount();
+                int index = nOfSpace - 1;
+//                if(nOfSpace <= count) {
+//                    index = nOfSpace - 1;
+//                }
+//                else {
+//                    index = nOfSpace % (count + 1) - 1;
+//                }
+
+                call = false;
+                if(index != -1) {
+                    View view = suggestionsView.getChildAt(index);
+                    SuggestionsManager.Suggestion suggestion = (SuggestionsManager.Suggestion) view.getTag(R.id.suggestion_id);
+
+                    String text = suggestion.getText() + Tuils.SPACE;
+
+                    if(originalText.length() < s.length() && suggestion.type == SuggestionsManager.Suggestion.TYPE_PERMANENT) {
+                        s.replace(originalText.length(), s.length(), text);
+                    }  else {
+                        s.replace(0, s.length(), text);
+                    }
+                } else {
+                    s.replace(0, s.length(), originalText);
+                    navigatingWithSpace = false;
+                }
+                call = true;
+            }
+        }
     };
 
-    private boolean executeOnSuggestionClick;
     private View.OnClickListener clickListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             SuggestionsManager.Suggestion suggestion = (SuggestionsManager.Suggestion) v.getTag(R.id.suggestion_id);
             boolean execOnClick = suggestion.exec;
 
-            if(suggestion.finalText == null) {
-//                this is for permanentsuggestions
-                mTerminalAdapter.setInput(mTerminalAdapter.getInput() + suggestion.text);
+            String text = suggestion.getText();
+            if(suggestion.type == SuggestionsManager.Suggestion.TYPE_PERMANENT) {
+                mTerminalAdapter.setInput(mTerminalAdapter.getInput() + text);
             } else {
-                mTerminalAdapter.setInput(suggestion.finalText);
+                mTerminalAdapter.setInput(text);
             }
 
-            if (executeOnSuggestionClick && execOnClick) {
+            if (execOnClick) {
                 mTerminalAdapter.simulateEnter();
             } else {
                 mTerminalAdapter.focusInputEnd();
@@ -172,7 +258,7 @@ public class UIManager implements OnTouchListener {
             }
         }
 
-        lastSuggestionThread = new Thread() {
+        lastSuggestionThread = new StoppableThread() {
             @Override
             public void run() {
                 super.run();
@@ -235,7 +321,7 @@ public class UIManager implements OnTouchListener {
     }
 
     protected UIManager(ExecutePack info, Context context, final ViewGroup rootView, final CommandExecuter tri, DevicePolicyManager mgr, ComponentName name,
-                        PreferencesManager prefsMgr, MainPack mainPack) {
+                        MainPack mainPack) {
 
         rootView.setOnTouchListener(this);
 
@@ -250,17 +336,19 @@ public class UIManager implements OnTouchListener {
         final Typeface lucidaConsole = Typeface.createFromAsset(context.getAssets(), "lucida_console.ttf");
 
         imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
-        skinManager = new SkinManager(prefsMgr);
+        skinManager = new SkinManager();
 
         this.info.skinManager = skinManager;
 
         if (!skinManager.useSystemWp) {
             rootView.setBackgroundColor(skinManager.bgColor);
+        } else {
+            rootView.setBackgroundColor(skinManager.overlayColor);
         }
 
         ram = (TextView) rootView.findViewById(R.id.ram_tv);
         TextView deviceInfo = (TextView) rootView.findViewById(R.id.deviceinfo_tv);
-        boolean showRam = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOWRAM));
+        boolean showRam = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_ram);
         if (showRam) {
             ram.setTextColor(skinManager.ramColor);
             ram.setTextSize(skinManager.getRamSize());
@@ -276,7 +364,7 @@ public class UIManager implements OnTouchListener {
             ram = null;
         }
 
-        boolean showDevice = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOWDEVICE));
+        boolean showDevice = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_device_name);
         if (showDevice) {
             String deviceName = skinManager.deviceName;
 
@@ -289,7 +377,7 @@ public class UIManager implements OnTouchListener {
             deviceInfo.setVisibility(View.GONE);
         }
 
-        final boolean inputBottom = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.INPUTFIELD_BOTTOM));
+        final boolean inputBottom = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.input_bottom);
         int layoutId = inputBottom ? R.layout.input_down_layout : R.layout.input_up_layout;
 
         LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -306,14 +394,14 @@ public class UIManager implements OnTouchListener {
         TextView prefixView = (TextView) inputOutputView.findViewById(R.id.prefix_view);
 
         ImageButton submitView = (ImageButton) inputOutputView.findViewById(R.id.submit_tv);
-        boolean showSubmit = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOWSUBMIT));
+        boolean showSubmit = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_enter_button);
         if (!showSubmit) {
             submitView.setVisibility(View.GONE);
             submitView = null;
         }
 
 //        toolbar
-        boolean showToolbar = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOWTOOLBAR));
+        boolean showToolbar = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Toolbar.enabled);
         ImageButton backView = null;
         ImageButton nextView = null;
         ImageButton deleteView = null;
@@ -342,13 +430,11 @@ public class UIManager implements OnTouchListener {
                 }
             });
 
-            executeOnSuggestionClick = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.EXECUTE_ON_SUGGESTION_CLICK));
-
             suggestionsView = (LinearLayout) rootView.findViewById(R.id.suggestions_group);
 
             inputView.addTextChangedListener(textWatcher);
 
-            suggestionsManager = new SuggestionsManager(prefsMgr);
+            suggestionsManager = new SuggestionsManager();
 
             this.suggestionViewDecorer = new SuggestionViewDecorer() {
                 @Override
@@ -361,7 +447,6 @@ public class UIManager implements OnTouchListener {
                     textView.setClickable(true);
 
                     textView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
-                    textView.setTextColor(skinManager.suggestionTextColor);
                     textView.setTextSize(skinManager.getSuggestionSize());
 
                     textView.setPadding(SkinManager.SUGGESTION_PADDING_HORIZONTAL, SkinManager.SUGGESTION_PADDING_VERTICAL,
@@ -379,15 +464,13 @@ public class UIManager implements OnTouchListener {
             this.clickListener = null;
         }
 
-        boolean closeOnDbTap = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.DOUBLETAP));
-        if (!closeOnDbTap) {
+        lockOnDbTap = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.double_tap_closes);
+        doubleTapCmd = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.double_tap_cmd);
+        if(!lockOnDbTap && doubleTapCmd == null) {
             policy = null;
             component = null;
             det = null;
-        } else {
-            doubleTapSU = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.DOUBLETAP_SU));
-            initDetector();
-        }
+        } else initDetector();
 
         mTerminalAdapter = new TerminalManager(terminalView, inputView, prefixView, submitView, backView, nextView, deleteView, pasteView, skinManager, context, mainPack);
         mTerminalAdapter.setInputListener(new OnNewInputListener() {
@@ -399,7 +482,7 @@ public class UIManager implements OnTouchListener {
                 trigger.exec(input, null);
             }
         });
-        if(Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOW_DONATE_MESSAGE))) {
+        if(XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.donation_message)) {
             mTerminalAdapter.addMessager(new TerminalManager.Messager(20, context.getString(R.string.rate_donate_text)));
         }
     }
@@ -427,10 +510,22 @@ public class UIManager implements OnTouchListener {
         mTerminalAdapter.focusInputEnd();
     }
 
+    public void setHint(String hint) {
+        mTerminalAdapter.setHint(hint);
+    }
+
+    public void resetHint() {
+        mTerminalAdapter.setDefaultHint();
+    }
+
     public void setOutput(String string) {
         mTerminalAdapter.setOutput(string);
     }
 
+    public void setOutput(String s, int color) {
+        mTerminalAdapter.setOutput(s, color);
+    }
+
     public void disableSuggestions() {
         if(suggestionsView != null) {
             showSuggestions = false;
@@ -468,8 +563,6 @@ public class UIManager implements OnTouchListener {
 
         det.setOnDoubleTapListener(new OnDoubleTapListener() {
 
-            boolean hadSU = false;
-
             @Override
             public boolean onSingleTapConfirmed(MotionEvent e) {
                 return false;
@@ -482,17 +575,14 @@ public class UIManager implements OnTouchListener {
 
             @Override
             public boolean onDoubleTap(MotionEvent e) {
-                if(doubleTapSU) {
-                    hadSU = Tuils.verifyRoot();
-                    doubleTapSU = hadSU;
-                }
-
-                if(hadSU) {
+                if(doubleTapCmd != null && doubleTapCmd.length() > 0) {
                     String input = mTerminalAdapter.getInput();
-                    mTerminalAdapter.setInput("su input keyevent KEYCODE_POWER");
+                    mTerminalAdapter.setInput(doubleTapCmd);
                     mTerminalAdapter.simulateEnter();
                     mTerminalAdapter.setInput(input);
-                } else {
+                }
+
+                if(lockOnDbTap) {
                     boolean admin = policy.isAdminActive(component);
 
                     if (!admin) {
@@ -557,5 +647,13 @@ public class UIManager implements OnTouchListener {
         };
     }
 
+    public interface SuggestionNavigator {
+        boolean isNavigating();
+        void onEnter();
+    }
+
+    public interface OnNewInputListener {
+        void onNewInput(String input);
+    }
 }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java b/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
index 1ea1f24..ab5acc6 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
@@ -3,23 +3,30 @@ package ohi.andre.consolelauncher.commands;
 import android.content.res.Resources;
 
 import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
+import ohi.andre.consolelauncher.tuils.Tuils;
 
 public class Command {
 
-    public static int ARG_NOTFOUND = -1;
-
     public CommandAbstraction cmd;
     public Object[] mArgs;
     public int nArgs;
 
+    public int indexNotFound = -1;
+
     public String exec(Resources resources, ExecutePack info) throws Exception {
         info.set(mArgs);
 
-        if (nArgs < cmd.minArgs() && nArgs != ARG_NOTFOUND) {
+        if (indexNotFound != -1) {
+            return cmd.onArgNotFound(info, indexNotFound);
+        }
+        if (nArgs < cmd.minArgs() || (mArgs == null && cmd.minArgs() > 0) ||
+                (cmd instanceof ParamCommand && mArgs != null && mArgs.length > 0 && ((ParamCommand) cmd).argsForParam((String) mArgs[0]) != null &&
+                        ((ParamCommand) cmd).argsForParam((String) mArgs[0]).length + 1 > nArgs)) {
             return cmd.onNotArgEnough(info, nArgs);
         }
-        if (nArgs == Command.ARG_NOTFOUND) {
-            return cmd.onArgNotFound(info);
+        if(cmd instanceof ParamCommand && ((ParamCommand) cmd).argsForParam((String) mArgs[0]) == null) {
+            return info.context.getString(R.string.output_invalid_param) + Tuils.SPACE + mArgs[0];
         }
         if (cmd.maxArgs() != CommandAbstraction.UNDEFINIED && nArgs > cmd.maxArgs()) {
             return resources.getString(R.string.output_toomanyargs);
@@ -33,14 +40,21 @@ public class Command {
     }
 
     public int nextArg() {
-        int[] args = cmd.argType();
-        if (args == null)
+        boolean useParamArgs = cmd instanceof ParamCommand && mArgs != null && mArgs.length >= 1;
+
+        int[] args;
+        if (useParamArgs) {
+            args = ((ParamCommand) cmd).argsForParam((String) mArgs[0]);
+        } else {
+            args = cmd.argType();
+        }
+
+        if (args == null) {
             return 0;
+        }
 
-        if (nArgs == -1)
-            nArgs = 0;
         try {
-            return args[nArgs];
+            return args[useParamArgs ? nArgs - 1 : nArgs];
         } catch (ArrayIndexOutOfBoundsException e) {
             nArgs -= 1;
             return nextArg();
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
index 3dc22dc..f8dfa00 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
@@ -1,7 +1,5 @@
 package ohi.andre.consolelauncher.commands;
 
-import ohi.andre.consolelauncher.commands.main.MainPack;
-
 public interface CommandAbstraction {
 
     //	undefinied n of arguments
@@ -10,8 +8,7 @@ public interface CommandAbstraction {
     //	arg type
     int PLAIN_TEXT = 10;
     int FILE = 11;
-    int PACKAGE = 12;
-    int HIDDEN_PACKAGE = 20;
+    int VISIBLE_PACKAGE = 12;
     int CONTACTNUMBER = 13;
     int TEXTLIST = 14;
     int SONG = 15;
@@ -19,6 +16,10 @@ public interface CommandAbstraction {
     int COMMAND = 17;
     int PARAM = 18;
     int BOOLEAN = 19;
+    int HIDDEN_PACKAGE = 20;
+    int COLOR = 21;
+    int CONFIG_FILE = 22;
+    int CONFIG_ENTRY = 23;
 
     String exec(ExecutePack pack) throws Exception;
 
@@ -32,9 +33,7 @@ public interface CommandAbstraction {
 
     int helpRes();
 
-    String onArgNotFound(ExecutePack pack);
+    String onArgNotFound(ExecutePack pack, int indexNotFound);
 
     String onNotArgEnough(ExecutePack pack, int nArgs);
-
-    String[] parameters();
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandGroup.java b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandGroup.java
index de2d710..36ec753 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandGroup.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandGroup.java
@@ -1,12 +1,10 @@
 package ohi.andre.consolelauncher.commands;
 
 import android.content.Context;
-import android.util.Log;
 
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
index 0e9b02d..18a2fbd 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
@@ -1,6 +1,8 @@
 package ohi.andre.consolelauncher.commands;
 
 import android.annotation.SuppressLint;
+import android.graphics.Color;
+import android.util.Log;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -8,12 +10,14 @@ import java.util.Arrays;
 import java.util.List;
 
 import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.FileManager;
 import ohi.andre.consolelauncher.managers.FileManager.DirInfo;
 import ohi.andre.consolelauncher.managers.MusicManager;
-import ohi.andre.consolelauncher.tuils.ShellUtils;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
 @SuppressLint("DefaultLocale")
@@ -25,6 +29,9 @@ public class CommandTuils {
     private static FileManager.SpecificExtensionFileFilter extensionFileFilter = new FileManager.SpecificExtensionFileFilter();
     private static FileManager.SpecificNameFileFilter nameFileFilter = new FileManager.SpecificNameFileFilter();
 
+    public static List<XMLPrefsManager.XMLPrefsSave> xmlPrefsEntrys;
+    public static List<String> xmlPrefsFiles;
+
     //	parse a command
     public static Command parse(String input, ExecutePack info, boolean suggestion) throws Exception {
         Command command = new Command();
@@ -52,32 +59,53 @@ public class CommandTuils {
         input = input.substring(name.length());
         input = input.trim();
 
-        int[] types = cmd.argType();
-        ArrayList<Object> args = new ArrayList<>(cmd.maxArgs() == CommandAbstraction.UNDEFINIED ? 0 : cmd.maxArgs());
+        ArrayList<Object> args = new ArrayList<>();
         int nArgs = 0;
+        int[] types;
 
-        if (types != null) {
-            for (int type : types) {
-                if (input.length() <= 0) {
-                    break;
-                }
+        try {
+            if(cmd instanceof ParamCommand) {
+                ArgInfo arg = param(input);
+                if(arg == null || !arg.found) return command;
 
-                ArgInfo arg = CommandTuils.getArg(info, input, type, suggestion);
-                if(arg == null) {
-                    return null;
-                }
+                input = arg.residualString;
+                String param = (String) arg.arg;
+                types = ((ParamCommand) cmd).argsForParam(param);
 
-                if (!arg.found) {
-                    command.nArgs = Command.ARG_NOTFOUND;
-                    command.mArgs = new String[] {input};
-                    return command;
-                }
+                nArgs++;
+                args.add(param);
+            } else {
+                types = cmd.argType();
+            }
 
-                nArgs += arg.n;
-                args.add(arg.arg);
-                input = arg.residualString;
+            if (types != null) {
+                for (int count = 0; count < types.length; count++) {
+                    if (input == null) break;
+
+                    input = input.trim();
+                    if(input.length() == 0) {
+                        break;
+                    }
+
+                    ArgInfo arg = CommandTuils.getArg(info, input, types[count], suggestion);
+                    if(arg == null) {
+                        return null;
+                    }
+
+                    if (!arg.found) {
+                        command.indexNotFound = cmd instanceof ParamCommand ? count + 1 : count;
+                        args.add(input);
+                        command.mArgs = args.toArray(new Object[args.size()]);
+                        command.nArgs = nArgs;
+                        return command;
+                    }
+
+                    nArgs += arg.n;
+                    args.add(arg.arg);
+                    input = arg.residualString;
+                }
             }
-        }
+        } catch (Exception e) {}
 
         command.mArgs = args.toArray(new Object[args.size()]);
         command.nArgs = nArgs;
@@ -106,18 +134,16 @@ public class CommandTuils {
             MainPack pack = (MainPack) info;
             return contactNumber(input, pack.contacts);
         }
-//        will always find a plain text
         else if (type == CommandAbstraction.PLAIN_TEXT) {
             return plainText(input);
         }
-        else if (type == CommandAbstraction.PACKAGE && info instanceof MainPack) {
+        else if (type == CommandAbstraction.VISIBLE_PACKAGE && info instanceof MainPack) {
             MainPack pack = (MainPack) info;
             return packageName(input, pack.appsManager);
         } else if (type == CommandAbstraction.HIDDEN_PACKAGE && info instanceof MainPack) {
             MainPack pack = (MainPack) info;
             return hiddenPackage(input, pack.appsManager);
         }
-//        will always find a textlist
         else if (type == CommandAbstraction.TEXTLIST) {
             return textList(input);
         }
@@ -138,6 +164,12 @@ public class CommandTuils {
             return param(input);
         } else if(type == CommandAbstraction.BOOLEAN) {
             return bln(input);
+        } else if(type == CommandAbstraction.COLOR) {
+            return color(input);
+        } else if(type == CommandAbstraction.CONFIG_ENTRY) {
+            return configEntry(input);
+        } else if(type == CommandAbstraction.CONFIG_FILE) {
+            return configFile(input);
         }
 
         return null;
@@ -146,6 +178,21 @@ public class CommandTuils {
 
 //	args extractors {
 
+    private static ArgInfo color(String input) {
+        input = input.trim();
+
+        int space = input.indexOf(Tuils.SPACE);
+        String cl = input.substring(0, space == -1 ? input.length() : space);
+        input = space == -1 ? Tuils.EMPTYSTRING : input.substring(space + 1);
+
+        try {
+            Color.parseColor(cl);
+            return new ArgInfo(cl, input, true, 1);
+        } catch (Exception e) {
+            return new ArgInfo(null, input, false, 0);
+        }
+    }
+
     private static ArgInfo bln(String input) {
         String used, notUsed;
         if(input.contains(Tuils.SPACE)) {
@@ -343,12 +390,47 @@ public class CommandTuils {
         return new ArgInfo(name, null, name != null, 1);
     }
 
+    private static ArgInfo configEntry(String input) {
+        int index = input.indexOf(Tuils.SPACE);
+        if(index == -1) return new ArgInfo(input, null, true, 1);
+
+        if(xmlPrefsEntrys == null) {
+            xmlPrefsEntrys = new ArrayList<>();
+            for(XMLPrefsManager.XMLPrefsRoot element : XMLPrefsManager.XMLPrefsRoot.values())
+                for(XMLPrefsManager.XMLPrefsSave save : element.copy)
+                    xmlPrefsEntrys.add(save);
+            for(XMLPrefsManager.XMLPrefsSave save : AppsManager.Options.values()) xmlPrefsEntrys.add(save);
+            for(XMLPrefsManager.XMLPrefsSave save : NotificationManager.Options.values()) xmlPrefsEntrys.add(save);
+        }
+
+        String candidate = input.substring(0,index);
+        for(XMLPrefsManager.XMLPrefsSave xs : xmlPrefsEntrys) {
+            if(xs.is(candidate)) return new ArgInfo(xs, input.substring(index + 1,input.length()), true, 1);
+        }
+        return new ArgInfo(null, input, false, 0);
+    }
+
+    private static ArgInfo configFile(String input) {
+        if(xmlPrefsFiles == null) {
+            xmlPrefsFiles = new ArrayList<>();
+            for(XMLPrefsManager.XMLPrefsRoot element : XMLPrefsManager.XMLPrefsRoot.values())
+                xmlPrefsFiles.add(element.path);
+            xmlPrefsFiles.add(AppsManager.PATH);
+            xmlPrefsFiles.add(NotificationManager.PATH);
+        }
+
+        for(String xs : xmlPrefsFiles) {
+            if(xs.equalsIgnoreCase(input)) return new ArgInfo(xs, null, true, 1);
+        }
+        return new ArgInfo(null, input, false, 0);
+    }
+
     public static boolean isSuRequest(String input) {
-        return input.equals(ShellUtils.COMMAND_SU);
+        return input.equals("su");
     }
 
     public static boolean isSuCommand(String input) {
-        return input.startsWith(ShellUtils.COMMAND_SU + Tuils.SPACE);
+        return input.startsWith("su ");
     }
 
     public static class ArgInfo {
@@ -357,11 +439,11 @@ public class CommandTuils {
         public int n;
         public boolean found;
 
-        public ArgInfo(Object a, String s, boolean f, int i) {
-            this.arg = a;
-            this.residualString = s;
-            this.found = f;
-            this.n = i;
+        public ArgInfo(Object arg, String residualString, boolean found, int nFound) {
+            this.arg = arg;
+            this.residualString = residualString;
+            this.found = found;
+            this.n = nFound;
         }
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandsPreferences.java b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandsPreferences.java
index 2d1d859..1e500d9 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandsPreferences.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandsPreferences.java
@@ -2,7 +2,7 @@ package ohi.andre.consolelauncher.commands;
 
 import java.util.HashMap;
 
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 
 /**
  * Created by francescoandreuzzi on 06/01/2017.
@@ -14,12 +14,12 @@ public class CommandsPreferences {
 
     private HashMap<String, Preference> preferenceHashMap;
 
-    public CommandsPreferences(PreferencesManager preferencesManager) {
+    public CommandsPreferences() {
         preferenceHashMap = new HashMap<>();
 
 //        search
         Preference searchP = new Preference();
-        searchP.add(preferencesManager.getValue(PreferencesManager.DEFAULT_SEARCH), DEFAULT_PARAM);
+        searchP.add(XMLPrefsManager.get(String.class, XMLPrefsManager.Cmd.default_search), DEFAULT_PARAM);
         preferenceHashMap.put("search", searchP);
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java b/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java
index 890189e..ba92eae 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java
@@ -1,10 +1,14 @@
 package ohi.andre.consolelauncher.commands;
 
+import android.content.Context;
+
 @SuppressWarnings("deprecation")
 public abstract class ExecutePack {
 
     public Object[] args;
 
+    public Context context;
+
     public CommandGroup commandGroup;
 
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/MainPack.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/MainPack.java
index 99104a2..10fde12 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/MainPack.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/MainPack.java
@@ -1,22 +1,19 @@
 package ohi.andre.consolelauncher.commands.main;
 
-import android.annotation.TargetApi;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.hardware.Camera;
+import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
 import android.os.Build;
-import android.os.Parcel;
-import android.util.Size;
 
 import java.io.File;
 import java.lang.reflect.Method;
 import java.util.List;
-import java.util.Objects;
 
 import ohi.andre.consolelauncher.commands.CommandGroup;
 import ohi.andre.consolelauncher.commands.CommandsPreferences;
@@ -26,7 +23,8 @@ import ohi.andre.consolelauncher.managers.AliasManager;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.MusicManager;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
@@ -45,9 +43,6 @@ public class MainPack extends ExecutePack {
     //	current directory
     public File currentDirectory;
 
-    //	context for accessing methods
-    public Context context;
-
     public SkinManager skinManager;
 
     //	resources references
@@ -62,7 +57,7 @@ public class MainPack extends ExecutePack {
     public WifiManager wifi;
 
     //	prefs
-    public PreferencesManager preferencesManager;
+    public XMLPrefsManager preferencesManager;
 
     //	3g/data
     public Method setMobileDataEnabledMethod;
@@ -93,11 +88,13 @@ public class MainPack extends ExecutePack {
     //	uses su
     private boolean canUseSu = false;
 
+    public LocationManager locationManager;
+
     public String lastCommand;
 
     public Redirectator redirectator;
 
-    public MainPack(Context context, PreferencesManager prefsMgr, CommandGroup commandGroup, AliasManager alMgr, AppsManager appmgr, MusicManager p,
+    public MainPack(Context context, CommandGroup commandGroup, AliasManager alMgr, AppsManager appmgr, MusicManager p,
                     ContactManager c, DevicePolicyManager devicePolicyManager, ComponentName componentName,
                     Reloadable r, CommandExecuter executeCommand, Outputable outputable, Redirectator redirectator) {
         super(commandGroup);
@@ -108,8 +105,6 @@ public class MainPack extends ExecutePack {
 
         this.executer = executeCommand;
 
-        this.preferencesManager = prefsMgr;
-
         this.context = context;
 
         this.currentDirectory = new File(Tuils.getInternalDirectoryPath());
@@ -118,7 +113,7 @@ public class MainPack extends ExecutePack {
 
         this.canUseFlash = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
 
-        this.cmdPrefs = new CommandsPreferences(prefsMgr);
+        this.cmdPrefs = new CommandsPreferences();
 
         this.player = p;
         this.contacts = c;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/Param.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/Param.java
new file mode 100644
index 0000000..c7c4cfe
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/Param.java
@@ -0,0 +1,14 @@
+package ohi.andre.consolelauncher.commands.main;
+
+import ohi.andre.consolelauncher.commands.ExecutePack;
+
+/**
+ * Created by francescoandreuzzi on 10/06/2017.
+ */
+
+public interface Param {
+
+    int[] args();
+    String exec(ExecutePack pack);
+    String label();
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/about.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/about.java
deleted file mode 100755
index c968826..0000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/about.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import ohi.andre.consolelauncher.BuildConfig;
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.tuils.Tuils;
-
-public class about implements CommandAbstraction {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        return info.res.getString(R.string.version_label) + Tuils.SPACE + BuildConfig.VERSION_NAME + Tuils.NEWLINE + Tuils.NEWLINE +
-                info.res.getString(R.string.output_about);
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_about;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return null;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info) {
-        return null;
-    }
-
-    @Override
-    public int priority() {
-        return 1;
-    }
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/airplane.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/airplane.java
index f53b05d..4842eb2 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/airplane.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/airplane.java
@@ -52,12 +52,7 @@ public class airplane implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
-    }
-
-    @Override
-    public String[] parameters() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -66,7 +61,7 @@ public class airplane implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/alias.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/alias.java
index 0ec91e4..db4e64e 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/alias.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/alias.java
@@ -36,7 +36,7 @@ public class alias implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -44,18 +44,13 @@ public class alias implements CommandAbstraction {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/aliasfile.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/aliasfile.java
deleted file mode 100644
index d5464ef..0000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/aliasfile.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;/*Copyright Francesco Andreuzzi
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.*/
-
-import android.app.Activity;
-import android.content.Intent;
-
-import java.io.File;
-
-import ohi.andre.consolelauncher.LauncherActivity;
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.commands.tuixt.TuixtActivity;
-import ohi.andre.consolelauncher.managers.FileManager;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
-import ohi.andre.consolelauncher.tuils.Tuils;
-
-public class aliasfile implements CommandAbstraction {
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        File tuiFolder = Tuils.getTuiFolder();
-        final File aliasFile = new File(tuiFolder, PreferencesManager.ALIAS_FILENAME);
-
-        Intent intent = Tuils.openFile(aliasFile);
-        info.context.startActivity(intent);
-
-        return Tuils.EMPTYSTRING;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return null;
-    }
-
-    @Override
-    public int priority() {
-        return 1;
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_aliasfile;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info) {
-        return null;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java
index ac3ba63..91e62f6 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java
@@ -1,57 +1,137 @@
 package ohi.andre.consolelauncher.commands.main.raw;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.net.Uri;
 
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.main.Param;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
-public class apps implements CommandAbstraction {
+public class apps extends ParamCommand {
+
+    private enum Param implements ohi.andre.consolelauncher.commands.main.Param {
+
+        lshidden {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                return ((MainPack) pack).appsManager.printApps(AppsManager.HIDDEN_APPS);
+            }
+        },
+        show {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.HIDDEN_PACKAGE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                ((MainPack) pack).appsManager.hideApp(pack.get(String.class, 1));
+                return null;
+            }
+        },
+        hide {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                ((MainPack) pack).appsManager.hideApp(pack.get(String.class, 1));
+                return null;
+            }
+        },
+        ps {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                openPlaystore(pack.context, pack.get(String.class, 1));
+                return null;
+            }
+        },
+        st {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                openSettings(pack.context, pack.get(String.class, 1));
+                return null;
+            }
+        },
+        frc {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                Intent intent = ((MainPack) pack).appsManager.getIntent(pack.get(String.class, 1));
+                pack.context.startActivity(intent);
+
+                return null;
+            }
+        };
 
-    private final String SHOWHIDDEN_PARAM = "-sh";
-    private final String PLAYSTORE_PARAM = "-ps";
-    private final String SETTINGS_PARAM = "-st";
-    private final String FORCE_PARAM = "-f";
+        static Param get(String p) {
+            p = p.toLowerCase();
+            Param[] ps = values();
+            for (Param p1 : ps)
+                if (p.endsWith(p1.label()))
+                    return p1;
+            return null;
+        }
 
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        String param = info.get(String.class, 0);
-        String app = info.get(String.class, 1);
-        if (app == null) {
-            return info.res.getString(helpRes());
+        static String[] labels() {
+            Param[] ps = values();
+            String[] ss = new String[ps.length];
+
+            for (int count = 0; count < ps.length; count++) {
+                ss[count] = ps[count].label();
+            }
+
+            return ss;
         }
 
-        if (param.equals(PLAYSTORE_PARAM)) {
-            openPlaystore(info.context, app);
-        } else if (param.equals(SETTINGS_PARAM)) {
-            openSettings(info.context, app);
-        } else if (param.equals(FORCE_PARAM)) {
-            Intent intent = info.appsManager.getIntent(app);
-            info.context.startActivity(intent);
-        } else {
-            return info.res.getString(helpRes());
+        @Override
+        public String label() {
+            return Tuils.MINUS + name();
         }
+    }
 
-        return Tuils.EMPTYSTRING;
+    @Override
+    protected ohi.andre.consolelauncher.commands.main.Param paramForString(String param) {
+        return Param.get(param);
     }
 
-    private String showHiddenApps(MainPack info) {
-        return info.appsManager.printApps(AppsManager.HIDDEN_APPS);
+    @Override
+    protected String doThings(ExecutePack pack) {
+        return null;
     }
 
-    private void openSettings(Context context, String packageName) {
+    private static void openSettings(Context context, String packageName) {
         Tuils.openSettingsPage(context, packageName);
     }
 
-    private void openPlaystore(Context context, String packageName) {
+    private static void openPlaystore(Context context, String packageName) {
         try {
             context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageName)));
         } catch (Exception e) {
@@ -66,7 +146,7 @@ public class apps implements CommandAbstraction {
 
     @Override
     public int minArgs() {
-        return 2;
+        return 1;
     }
 
     @Override
@@ -74,42 +154,26 @@ public class apps implements CommandAbstraction {
         return 2;
     }
 
-    @Override
-    public int[] argType() {
-        return new int[]{CommandAbstraction.PARAM, CommandAbstraction.PACKAGE};
-    }
-
     @Override
     public int priority() {
-        return 2;
-    }
-
-    @Override
-    public String[] parameters() {
-        return new String[]{
-                SHOWHIDDEN_PARAM,
-                SETTINGS_PARAM,
-                PLAYSTORE_PARAM,
-                FORCE_PARAM
-        };
+        return 4;
     }
 
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         MainPack pack = (MainPack) info;
-        if (nArgs > 0) {
-            if (pack.get(String.class, 0).equals(SHOWHIDDEN_PARAM))
-                return showHiddenApps(pack);
-            else
-                return pack.res.getString(helpRes());
-        } else
-            return pack.appsManager.printApps(AppsManager.SHOWN_APPS);
+        if (nArgs > 0) return pack.res.getString(helpRes());
+        return pack.appsManager.printApps(AppsManager.SHOWN_APPS);
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         MainPack pack = (MainPack) info;
         return pack.res.getString(R.string.output_appnotfound);
     }
 
+    @Override
+    public String[] params() {
+        return Param.labels();
+    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/beep.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/beep.java
new file mode 100644
index 0000000..c2f3852
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/beep.java
@@ -0,0 +1,63 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.MainPack;
+
+/**
+ * Created by francescoandreuzzi on 29/04/2017.
+ */
+
+public class beep implements CommandAbstraction {
+
+    @Override
+    public String exec(ExecutePack pack) throws Exception {
+        try {
+            ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 50);
+            toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 1000);
+        } catch (Exception e) {
+            return e.toString();
+        }
+
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 0;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 0;
+    }
+
+    @Override
+    public int[] argType() {
+        return new int[0];
+    }
+
+    @Override
+    public int priority() {
+        return 2;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_beep;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int index) {
+        return null;
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return ((MainPack) pack).context.getString(helpRes());
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/bluetooth.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/bluetooth.java
index 39b051c..e0d78c9 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/bluetooth.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/bluetooth.java
@@ -40,7 +40,7 @@ public class bluetooth implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -48,18 +48,13 @@ public class bluetooth implements CommandAbstraction {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java
index a6ab77f..8cf5756 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java
@@ -48,7 +48,7 @@ public class calc extends PermanentSuggestionCommand {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         return null;
     }
 
@@ -58,11 +58,6 @@ public class calc extends PermanentSuggestionCommand {
         return info.res.getString(helpRes());
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String[] permanentSuggestions() {
         return new String[] {"(", ")", "+", "-", "*", "/", "%", "^", "sqrt"};
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/call.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/call.java
index 992eec2..e7bb2cc 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/call.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/call.java
@@ -8,29 +8,21 @@ import android.net.Uri;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.content.ContextCompat;
 
-import java.util.List;
-
 import ohi.andre.consolelauncher.LauncherActivity;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.tuils.Tuils;
 
 public class call implements CommandAbstraction {
 
     @Override
     public String exec(ExecutePack pack) {
         MainPack info = (MainPack) pack;
-        if (ContextCompat.checkSelfPermission(info.context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
-
-            ActivityCompat.requestPermissions((Activity) info.context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
-            return info.context.getString(R.string.output_waitingpermission);
-        }
-
-        if (ContextCompat.checkSelfPermission(info.context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
+        if (ContextCompat.checkSelfPermission(info.context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
+                ContextCompat.checkSelfPermission(info.context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
 
-            ActivityCompat.requestPermissions((Activity) info.context, new String[]{Manifest.permission.CALL_PHONE}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
+            ActivityCompat.requestPermissions((Activity) info.context, new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
             return info.context.getString(R.string.output_waitingpermission);
         }
 
@@ -72,27 +64,13 @@ public class call implements CommandAbstraction {
         return 5;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
-        MainPack pack = (MainPack) info;
-        if (ContextCompat.checkSelfPermission(pack.context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
-            ActivityCompat.requestPermissions((Activity) pack.context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
-            return pack.context.getString(R.string.output_waitingpermission);
-        }
-
-        List<String> contacts = pack.contacts.listNamesAndNumbers();
-        Tuils.addPrefix(contacts, Tuils.DOUBLE_SPACE);
-        Tuils.insertHeaders(contacts, false);
-        return Tuils.toPlanString(contacts);
+        return info.context.getString(helpRes());
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_numbernotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cd.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cd.java
index b311e97..3c9a944 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cd.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cd.java
@@ -50,11 +50,6 @@ public class cd implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         MainPack pack = (MainPack) info;
@@ -62,7 +57,7 @@ public class cd implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_filenotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/clear.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/clear.java
index 4913399..8d45ee4 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/clear.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/clear.java
@@ -28,7 +28,7 @@ public class clear implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -36,18 +36,13 @@ public class clear implements CommandAbstraction {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public int helpRes() {
         return R.string.help_clear;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cntcts.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cntcts.java
new file mode 100644
index 0000000..0154676
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cntcts.java
@@ -0,0 +1,185 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.ContactsContract;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+
+import java.util.List;
+
+import ohi.andre.consolelauncher.LauncherActivity;
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.main.Param;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
+import ohi.andre.consolelauncher.managers.ContactManager;
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+/**
+ * Created by francescoandreuzzi on 11/05/2017.
+ */
+
+public class cntcts extends ParamCommand {
+
+    private enum Param implements ohi.andre.consolelauncher.commands.main.Param {
+
+        ls {
+            @Override
+            public String exec(ExecutePack pack) {
+                List<String> list = ((MainPack) pack).contacts.listNamesAndNumbers();
+                Tuils.insertHeaders(list, false);
+                return Tuils.toPlanString(list);
+            }
+
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+        },
+        add {
+            @Override
+            public String exec(ExecutePack pack) {
+                Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
+                intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
+                pack.context.startActivity(intent);
+
+                return null;
+            }
+
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+        },
+        rm {
+            @Override
+            public String exec(ExecutePack pack) {
+                if (ContextCompat.checkSelfPermission(pack.context, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+                    ActivityCompat.requestPermissions((Activity) pack.context, new String[]{Manifest.permission.WRITE_CONTACTS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
+                    return pack.context.getString(R.string.output_waitingpermission);
+                }
+
+                ((MainPack) pack).contacts.delete(pack.get(String.class, 1));
+                return null;
+            }
+
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.CONTACTNUMBER};
+            }
+        },
+        edit {
+            @Override
+            public String exec(ExecutePack pack) {
+                Intent editIntent = new Intent(Intent.ACTION_EDIT);
+                editIntent.setDataAndType(((MainPack) pack).contacts.fromPhone(pack.get(String.class, 1)), ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+                pack.context.startActivity(editIntent);
+
+                return null;
+            }
+
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.CONTACTNUMBER};
+            }
+        },
+        show {
+            @Override
+            public String exec(ExecutePack pack) {
+                String[] about = ((MainPack) pack).contacts.about(pack.get(String.class, 1));
+                StringBuilder builder = new StringBuilder();
+
+                builder.append(about[ContactManager.NAME]).append(Tuils.NEWLINE);
+                builder.append("\t\t").append(about[ContactManager.NUMBERS].replaceAll(Tuils.NEWLINE, Tuils.NEWLINE + "\t\t")).append(Tuils.NEWLINE);
+                builder.append("ID: " + about[ContactManager.CONTACT_ID]).append(Tuils.NEWLINE);
+                builder.append("Contacted " + about[ContactManager.TIME_CONTACTED] + " time(s)").append(Tuils.NEWLINE);
+
+                return builder.toString();
+            }
+
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.CONTACTNUMBER};
+            }
+        };
+
+        static Param get(String p) {
+            p = p.toLowerCase();
+            Param[] ps = values();
+            for (Param p1 : ps)
+                if (p.endsWith(p1.label()))
+                    return p1;
+            return null;
+        }
+
+        static String[] labels() {
+            Param[] ps = values();
+            String[] ss = new String[ps.length];
+
+            for (int count = 0; count < ps.length; count++) {
+                ss[count] = ps[count].label();
+            }
+
+            return ss;
+        }
+
+        @Override
+        public String label() {
+            return Tuils.MINUS + name();
+        }
+    }
+
+    @Override
+    protected ohi.andre.consolelauncher.commands.main.Param paramForString(String param) {
+        return Param.get(param);
+    }
+
+    @Override
+    public String[] params() {
+        return Param.labels();
+    }
+
+    @Override
+    protected String doThings(ExecutePack pack) {
+        if (ContextCompat.checkSelfPermission(pack.context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions((Activity) pack.context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
+            return pack.context.getString(R.string.output_waitingpermission);
+        }
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 1;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 2;
+    }
+
+    @Override
+    public int priority() {
+        return 3;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_cntcts;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int indexNotFound) {
+        return pack.context.getString(R.string.output_numbernotfound);
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return pack.context.getString(helpRes());
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java
new file mode 100644
index 0000000..7250689
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java
@@ -0,0 +1,119 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import java.io.File;
+
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.Param;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+/**
+ * Created by francescoandreuzzi on 11/06/2017.
+ */
+
+public class config extends ParamCommand {
+
+    private enum Param implements ohi.andre.consolelauncher.commands.main.Param {
+
+        set {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.CONFIG_ENTRY, CommandAbstraction.PLAIN_TEXT};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                XMLPrefsManager.XMLPrefsSave save = pack.get(XMLPrefsManager.XMLPrefsSave.class, 1);
+                save.parent().write(save, pack.get(String.class, 2));
+                return null;
+            }
+        },
+        open {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.CONFIG_FILE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                File file = pack.get(File.class, 1);
+                Tuils.openFile(file);
+                return null;
+            }
+        };
+
+        static Param get(String p) {
+            p = p.toLowerCase();
+            Param[] ps = values();
+            for (Param p1 : ps)
+                if (p.endsWith(p1.label()))
+                    return p1;
+            return null;
+        }
+
+        static String[] labels() {
+            Param[] ps = values();
+            String[] ss = new String[ps.length];
+
+            for (int count = 0; count < ps.length; count++) {
+                ss[count] = ps[count].label();
+            }
+
+            return ss;
+        }
+
+        @Override
+        public String label() {
+            return Tuils.MINUS + name();
+        }
+    }
+
+    @Override
+    public String[] params() {
+        return Param.labels();
+    }
+
+    @Override
+    protected ohi.andre.consolelauncher.commands.main.Param paramForString(String param) {
+        return Param.get(param);
+    }
+
+    @Override
+    protected String doThings(ExecutePack pack) {
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 2;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 3;
+    }
+
+    @Override
+    public int priority() {
+        return 4;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_config;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int indexNotFound) {
+        if(indexNotFound == 0) return pack.context.getString(R.string.output_invalid_param);
+        return pack.context.getString(R.string.output_invalidarg);
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return pack.context.getString(helpRes());
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java
index 8435e94..470df45 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java
@@ -58,18 +58,13 @@ public class cp implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public int helpRes() {
         return R.string.help_cp;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_filenotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java
index f58a830..313f46b 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java
@@ -99,11 +99,6 @@ public class data implements CommandAbstraction {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         MainPack pack = (MainPack) info;
@@ -116,7 +111,7 @@ public class data implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return onNotArgEnough(info, 0);
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/donate.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/donate.java
index 78c1a60..daeca62 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/donate.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/donate.java
@@ -46,7 +46,7 @@ public class donate implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -60,7 +60,7 @@ public class donate implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
@@ -68,9 +68,4 @@ public class donate implements CommandAbstraction {
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/exit.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/exit.java
new file mode 100644
index 0000000..812d7b3
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/exit.java
@@ -0,0 +1,53 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+/**
+ * Created by francescoandreuzzi on 21/05/2017.
+ */
+
+public class exit implements CommandAbstraction {
+    @Override
+    public String exec(ExecutePack pack) throws Exception {
+        Tuils.resetPreferredLauncherAndOpenChooser(pack.context);
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 0;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 0;
+    }
+
+    @Override
+    public int[] argType() {
+        return new int[0];
+    }
+
+    @Override
+    public int priority() {
+        return 4;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_exit;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int indexNotFound) {
+        return null;
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return null;
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java
index 0f8195c..a782794 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java
@@ -8,8 +8,6 @@ import android.hardware.Camera.Parameters;
 import android.hardware.camera2.CameraManager;
 import android.os.Build;
 
-import java.io.IOException;
-
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
@@ -136,7 +134,7 @@ public class flash implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -144,18 +142,13 @@ public class flash implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/help.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/help.java
index f9ab79a..b0d47f0 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/help.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/help.java
@@ -48,11 +48,6 @@ public class help implements CommandAbstraction {
         return 5;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack pack, int nArgs) {
         MainPack info = (MainPack) pack;
@@ -73,7 +68,7 @@ public class help implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_commandnotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java
index a156725..b599a14 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java
@@ -34,7 +34,7 @@ public class hideapp implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return new int[] {CommandAbstraction.PACKAGE};
+        return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
     }
 
     @Override
@@ -48,7 +48,7 @@ public class hideapp implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_appnotfound);
     }
@@ -59,11 +59,6 @@ public class hideapp implements CommandAbstraction {
         return info.res.getString(helpRes());
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     private String hideApp(MainPack info, String app) {
         SharedPreferences.Editor editor = ((Activity) info.context).getPreferences(0).edit();
         String result = info.appsManager.hideApp(app);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/listen.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/listen.java
index 6d1cc7b..dd99825 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/listen.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/listen.java
@@ -47,11 +47,6 @@ public class listen extends music {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack pack, int nArgs) {
         MainPack info = (MainPack) pack;
@@ -59,7 +54,7 @@ public class listen extends music {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_nothingfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/location.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/location.java
new file mode 100644
index 0000000..f33f69a
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/location.java
@@ -0,0 +1,108 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Looper;
+import android.support.v4.app.ActivityCompat;
+
+import ohi.andre.consolelauncher.LauncherActivity;
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.MainPack;
+
+/**
+ * Created by francescoandreuzzi on 10/05/2017.
+ */
+
+public class location implements CommandAbstraction {
+
+    @Override
+    public String exec(ExecutePack pack) throws Exception {
+        Context context = ((MainPack) pack).context;
+
+        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
+                ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
+            return context.getString(R.string.output_waitingpermission);
+        }
+
+        final MainPack main = ((MainPack) pack);
+        if(main.locationManager == null) {
+            main.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+        }
+
+        LocationListener locationListener = new LocationListener() {
+            @Override
+            public void onLocationChanged(Location location) {
+                main.outputable.onOutput("Lat: " + location.getLatitude() + "; Long: " + location.getLongitude());
+            }
+
+            @Override
+            public void onStatusChanged(String provider, int status, Bundle extras) {
+            }
+
+            @Override
+            public void onProviderEnabled(String provider) {
+            }
+
+            @Override
+            public void onProviderDisabled(String provider) {
+            }
+        };
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
+            boolean gpsStatus = main.locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+            boolean networkStatus = main.locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
+
+            if (!gpsStatus && !networkStatus) {
+                return context.getString(R.string.location_off);
+            }
+
+            main.locationManager.requestSingleUpdate(gpsStatus ? LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER, locationListener, Looper.getMainLooper());
+            return null;
+        } else return context.getString(R.string.output_nofeature);
+    }
+
+    @Override
+    public int minArgs() {
+        return 0;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 0;
+    }
+
+    @Override
+    public int[] argType() {
+        return new int[0];
+    }
+
+    @Override
+    public int priority() {
+        return 3;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_location;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int indexNotFound) {
+        return null;
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return null;
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ls.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ls.java
index dff4b26..c4995c9 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ls.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ls.java
@@ -67,7 +67,7 @@ public class ls implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_filenotfound);
     }
@@ -82,9 +82,4 @@ public class ls implements CommandAbstraction {
             return e.toString();
         }
     }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java
index 0b372b8..b7c565b 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java
@@ -58,18 +58,13 @@ public class mv implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public int helpRes() {
         return R.string.help_mv;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_filenotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/next.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/next.java
index 8119da6..3abb54b 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/next.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/next.java
@@ -35,7 +35,7 @@ public class next extends music {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -43,18 +43,13 @@ public class next extends music {
         return 5;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/notifications.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/notifications.java
new file mode 100644
index 0000000..6aa0cbf
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/notifications.java
@@ -0,0 +1,134 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.main.Param;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
+import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+/**
+ * Created by francescoandreuzzi on 29/04/2017.
+ */
+
+public class notifications extends ParamCommand {
+
+    private final String INCLUDE_PARAM = "-inc";
+    private final String EXCLUDE_PARAM = "-exc";
+    private final String COLOR_PARAM = "-clr";
+
+    private enum Param implements ohi.andre.consolelauncher.commands.main.Param {
+
+        inc {
+            @Override
+            public String exec(ExecutePack pack) {
+                NotificationManager.notificationsChangeFor(new NotificationManager.NotificatedApp(pack.get(String.class, 1), -1, true));
+                return null;
+            }
+
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
+            }
+        },
+        exc{
+            @Override
+            public String exec(ExecutePack pack) {
+                NotificationManager.notificationsChangeFor(new NotificationManager.NotificatedApp(pack.get(String.class, 1), -1, false));
+                return null;
+            }
+
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
+            }
+        },
+        clr{
+            @Override
+            public String exec(ExecutePack pack) {
+                if(pack.args.length < 3) return ((MainPack) pack).context.getString(R.string.help_notifications);
+                try {
+                    NotificationManager.notificationsChangeFor(new NotificationManager.NotificatedApp(pack.get(String.class, 2), pack.get(String.class, 1), true));
+                } catch (Exception e) {}
+                return null;
+            }
+
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.COLOR, CommandAbstraction.VISIBLE_PACKAGE};
+            }
+        };
+
+        static Param get(String p) {
+            p = p.toLowerCase();
+            Param[] ps = values();
+            for (Param p1 : ps)
+                if (p.endsWith(p1.label()))
+                    return p1;
+            return null;
+        }
+
+        static String[] labels() {
+            Param[] ps = values();
+            String[] ss = new String[ps.length];
+
+            for (int count = 0; count < ps.length; count++) {
+                ss[count] = ps[count].label();
+            }
+
+            return ss;
+        }
+
+        @Override
+        public String label() {
+            return Tuils.MINUS + name();
+        }
+    }
+
+    @Override
+    protected ohi.andre.consolelauncher.commands.main.Param paramForString(String param) {
+        return Param.get(param);
+    }
+
+    @Override
+    protected String doThings(ExecutePack pack) {
+        return null;
+    }
+
+    @Override
+    public String[] params() {
+        return Param.labels();
+    }
+
+    @Override
+    public int minArgs() {
+        return 2;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 3;
+    }
+
+    @Override
+    public int priority() {
+        return 3;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_notifications;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int index) {
+        return ((MainPack) pack).context.getString(R.string.output_appnotfound);
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return ((MainPack) pack).context.getString(helpRes());
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java
index 46a5093..66fbf66 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java
@@ -51,11 +51,6 @@ public class open implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack pack, int nArgs) {
         MainPack info = (MainPack) pack;
@@ -63,7 +58,7 @@ public class open implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_filenotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/previous.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/previous.java
index 1a2ba21..629c5ce 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/previous.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/previous.java
@@ -35,7 +35,7 @@ public class previous extends music {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -43,18 +43,13 @@ public class previous extends music {
         return 3;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rate.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rate.java
index 13d3366..1483462 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rate.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rate.java
@@ -54,7 +54,7 @@ public class rate implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -62,18 +62,13 @@ public class rate implements CommandAbstraction {
         return 3;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/refresh.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/refresh.java
index 97feac6..c8ef105 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/refresh.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/refresh.java
@@ -7,15 +7,15 @@ import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.managers.ContactManager;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 
 public class refresh implements CommandAbstraction {
 
     @Override
     public String exec(ExecutePack pack) {
         MainPack info = (MainPack) pack;
-        info.appsManager.fill(((Activity) info.context).getPreferences(0));
-        info.preferencesManager.refresh(PreferencesManager.ALIAS);
+        info.appsManager.fill();
+//        info.preferencesManager.refresh(XMLPrefsManager.ALIAS);
         info.aliasManager.reload();
         info.player.refresh(info.context);
         info.contacts = new ContactManager(info.context);
@@ -40,7 +40,7 @@ public class refresh implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -48,18 +48,13 @@ public class refresh implements CommandAbstraction {
         return 3;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/remove.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/remove.java
deleted file mode 100755
index 9c1ce8e..0000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/remove.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import android.content.Intent;
-import android.net.Uri;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.tuils.Tuils;
-
-public class remove implements CommandAbstraction {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        info.policy.removeActiveAdmin(info.component);
-
-        Uri packageURI = Uri.parse("package:" + "ohi.andre.consolelauncher");
-        Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
-        info.context.startActivity(uninstallIntent);
-
-        return Tuils.EMPTYSTRING;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return null;
-    }
-
-    @Override
-    public int priority() {
-        return 2;
-    }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_remove;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info) {
-        return null;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/restart.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/restart.java
index 8571e62..5d41c71 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/restart.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/restart.java
@@ -26,7 +26,7 @@ public class restart implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -34,18 +34,13 @@ public class restart implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public int helpRes() {
         return R.string.help_restart;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java
index b077c8b..7e148e1 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java
@@ -54,18 +54,13 @@ public class rm implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public int helpRes() {
         return R.string.help_rm;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_filenotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/search.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/search.java
index 73dbe6f..996115a 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/search.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/search.java
@@ -16,49 +16,115 @@ import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.CommandsPreferences;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.main.Param;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
 import ohi.andre.consolelauncher.managers.FileManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
 
-public class search implements CommandAbstraction {
+import static ohi.andre.consolelauncher.managers.FileManager.MIN_FILE_RATE;
 
-    private final String YOUTUBE_PREFIX = "https://www.youtube.com/results?search_query=";
-    private final String GOOGLE_PREFIX = "http://www.google.com/#q=";
-    private final String PLAYSTORE_PREFIX = "market://search?q=";
-    private final String PLAYSTORE_BROWSER_PREFIX = "https://play.google.com/store/search?q=";
+public class search extends ParamCommand {
 
-    private final String PLAYSTORE_PARAM = "-p";
-    private final String FILE_PARAM = "-f";
-    private final String GOOGLE_PARAM = "-g";
-    private final String YOUTUBE_PARAM = "-y";
-    private final String URL_PARAM = "-u";
+    private static final String YOUTUBE_PREFIX = "https://www.youtube.com/results?search_query=";
+    private static final String GOOGLE_PREFIX = "http://www.google.com/#q=";
+    private static final String PLAYSTORE_PREFIX = "market://search?q=";
+    private static final String PLAYSTORE_BROWSER_PREFIX = "https://play.google.com/store/search?q=";
+    private static final String DUCKDUCKGO_PREFIX = "https://duckduckgo.com/?q=";
 
-    private final int MIN_FILE_RATE = 4;
+    private enum Param implements ohi.andre.consolelauncher.commands.main.Param {
 
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
+        ps {
+            @Override
+            public String exec(ExecutePack pack) {
+                List<String> args = pack.get(ArrayList.class, 1);
+                return playstore(args, pack.context);
+            }
+        },
+        file {
+            @Override
+            public String exec(ExecutePack pack) {
+                List<String> args = pack.get(ArrayList.class, 1);
+                MainPack p = ((MainPack) pack);
+                return file(args, p.currentDirectory, p.res, p.outputable);
+            }
+        },
+        gg {
+            @Override
+            public String exec(ExecutePack pack) {
+                List<String> args = pack.get(ArrayList.class, 1);
+                return google(args, pack.context);
+            }
+        },
+        yt {
+            @Override
+            public String exec(ExecutePack pack) {
+                List<String> args = pack.get(ArrayList.class, 1);
+                return youTube(args, pack.context);
+            }
+        },
+        u {
+            @Override
+            public String exec(ExecutePack pack) {
+                List<String> args = pack.get(ArrayList.class, 1);
+                return url(Tuils.toPlanString(args, Tuils.SPACE), pack.context);
+            }
+        },
+        dd {
+            @Override
+            public String exec(ExecutePack pack) {
+                List<String> args = pack.get(ArrayList.class, 1);
+                return duckDuck(args, pack.context);
+            }
+        };
+
+        @Override
+        public int[] args() {
+            return new int[] {CommandAbstraction.TEXTLIST};
+        }
 
-        List<String> args = info.get(ArrayList.class, 1);
-        String param = info.get(String.class, 0);
-
-        switch (param) {
-            case PLAYSTORE_PARAM:
-                return playstore(args, info.context);
-            case YOUTUBE_PARAM:
-                return youTube(args, info.context);
-            case FILE_PARAM:
-                return file(args, info.currentDirectory, info.res, info.outputable);
-            case GOOGLE_PARAM:
-                return google(args, info.context);
-            case URL_PARAM:
-                return url(args.get(0), info.context);
-            default:
-                return info.res.getString(R.string.output_invalid_param) + Tuils.SPACE + param;
+        static Param get(String p) {
+            p = p.toLowerCase();
+            Param[] ps = values();
+            for (Param p1 : ps)
+                if (p.endsWith(p1.label()))
+                    return p1;
+            return null;
+        }
+
+        static String[] labels() {
+            Param[] ps = values();
+            String[] ss = new String[ps.length];
+
+            for (int count = 0; count < ps.length; count++) {
+                ss[count] = ps[count].label();
+            }
+
+            return ss;
+        }
+
+        @Override
+        public String label() {
+            return Tuils.MINUS + name();
         }
     }
 
-    private String google(List<String> args, Context c) {
+    @Override
+    protected ohi.andre.consolelauncher.commands.main.Param paramForString(String param) {
+        return Param.get(param);
+    }
+
+    @Override
+    protected String doThings(ExecutePack pack) {
+        return null;
+    }
+
+    @Override
+    public String[] params() {
+        return Param.labels();
+    }
+
+    private static String google(List<String> args, Context c) {
         String toSearch = Tuils.toPlanString(args, "+");
 
         Uri uri = Uri.parse(GOOGLE_PREFIX + toSearch);
@@ -68,7 +134,7 @@ public class search implements CommandAbstraction {
         return Tuils.EMPTYSTRING;
     }
 
-    private String playstore(List<String> args, Context c) {
+    private static String playstore(List<String> args, Context c) {
         String toSearch = Tuils.toPlanString(args, "%20");
 
         try {
@@ -80,7 +146,7 @@ public class search implements CommandAbstraction {
         return Tuils.EMPTYSTRING;
     }
 
-    private String url(String url, Context c) {
+    private static String url(String url, Context c) {
         if (!url.startsWith("http://") && !url.startsWith("https://")) {
             url = "http://" + url;
         }
@@ -92,7 +158,17 @@ public class search implements CommandAbstraction {
         return Tuils.EMPTYSTRING;
     }
 
-    private String file(final List<String> args, final File cd, final Resources res, final Outputable outputable) {
+    private static String duckDuck(List<String> args, Context c) {
+        String toSearch = Tuils.toPlanString(args, "+");
+
+        Uri uri = Uri.parse(DUCKDUCKGO_PREFIX + toSearch);
+        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+        c.startActivity(intent);
+
+        return Tuils.EMPTYSTRING;
+    }
+
+    private static String file(final List<String> args, final File cd, final Resources res, final Outputable outputable) {
         new Thread() {
             @Override
             public void run() {
@@ -111,7 +187,7 @@ public class search implements CommandAbstraction {
         return Tuils.EMPTYSTRING;
     }
 
-    private List<String> rightPaths(File dir, String name, boolean scrollCompare) {
+    private static List<String> rightPaths(File dir, String name, boolean scrollCompare) {
         File[] files = dir.listFiles();
         List<String> rightPaths = new ArrayList<>(files.length);
 
@@ -130,7 +206,7 @@ public class search implements CommandAbstraction {
         return rightPaths;
     }
 
-    private boolean fileMatch(File f, String name, boolean scrollCompare) {
+    private static boolean fileMatch(File f, String name, boolean scrollCompare) {
         if (scrollCompare) {
             return Compare.scrollComparison(f.getName(), name) >= MIN_FILE_RATE;
         } else {
@@ -138,7 +214,7 @@ public class search implements CommandAbstraction {
         }
     }
 
-    private String youTube(List<String> args, Context c) {
+    private static String youTube(List<String> args, Context c) {
         String toSearch = Tuils.toPlanString(args, "+");
         Uri uri = Uri.parse(YOUTUBE_PREFIX + toSearch);
         Intent intent = new Intent(Intent.ACTION_VIEW, uri);
@@ -162,27 +238,11 @@ public class search implements CommandAbstraction {
         return CommandAbstraction.UNDEFINIED;
     }
 
-    @Override
-    public int[] argType() {
-        return new int[] {CommandAbstraction.PARAM, CommandAbstraction.TEXTLIST};
-    }
-
     @Override
     public int priority() {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return new String[]{
-                PLAYSTORE_PARAM,
-                FILE_PARAM,
-                GOOGLE_PARAM,
-                YOUTUBE_PARAM,
-                URL_PARAM
-        };
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack pack, int nArgs) {
         MainPack info = (MainPack) pack;
@@ -190,25 +250,16 @@ public class search implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
+//        use default param
+
         MainPack info = (MainPack) pack;
         List<String> toSearch = Arrays.asList((String[]) info.args);
         String param = info.cmdPrefs.forCommand(getClass().getSimpleName()).get(CommandsPreferences.DEFAULT_PARAM);
-
-        switch (param) {
-            case PLAYSTORE_PARAM:
-                return playstore(toSearch, info.context);
-            case YOUTUBE_PARAM:
-                return youTube(toSearch, info.context);
-            case FILE_PARAM:
-                return file(toSearch, info.currentDirectory, info.res, info.outputable);
-            case GOOGLE_PARAM:
-                return google(toSearch, info.context);
-            case URL_PARAM:
-                return url(toSearch.get(0), info.context);
-            default:
-                return info.res.getString(R.string.output_invalid_param) + Tuils.SPACE + param;
+        Param p = Param.get(param);
+        if(p != null) {
+            return p.exec(pack);
         }
+        return pack.context.getString(helpRes());
     }
-
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/share.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/share.java
index 166b571..11fa366 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/share.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/share.java
@@ -50,11 +50,6 @@ public class share implements CommandAbstraction {
         return 3;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack pack, int nArgs) {
         MainPack info = (MainPack) pack;
@@ -62,7 +57,7 @@ public class share implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_filenotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/shellcommands.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/shellcommands.java
index a681e5e..250fb4d 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/shellcommands.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/shellcommands.java
@@ -14,7 +14,6 @@ import ohi.andre.comparestring.Compare;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
 /**
@@ -82,7 +81,7 @@ public class shellcommands implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
@@ -90,9 +89,4 @@ public class shellcommands implements CommandAbstraction {
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
-
-    @Override
-    public String[] parameters() {
-        return new String[0];
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java
index e2a0a4f..06640bd 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java
@@ -7,15 +7,12 @@ import android.support.v4.app.ActivityCompat;
 import android.support.v4.content.ContextCompat;
 import android.telephony.SmsManager;
 
-import java.util.List;
-
 import ohi.andre.consolelauncher.LauncherActivity;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.specific.RedirectCommand;
-import ohi.andre.consolelauncher.tuils.Tuils;
 
 /**
  * Created by francescoandreuzzi on 02/03/2017.
@@ -70,29 +67,15 @@ public class sms extends RedirectCommand {
 
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
-        MainPack pack = (MainPack) info;
-        if (ContextCompat.checkSelfPermission(pack.context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
-            ActivityCompat.requestPermissions((Activity) pack.context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
-            return pack.context.getString(R.string.output_waitingpermission);
-        }
-
-        List<String> contacts = pack.contacts.listNamesAndNumbers();
-        Tuils.addPrefix(contacts, Tuils.DOUBLE_SPACE);
-        Tuils.insertHeaders(contacts, false);
-        return Tuils.toPlanString(contacts);
+        return info.context.getString(helpRes());
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_numbernotfound);
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onRedirect(ExecutePack pack) {
         MainPack info = (MainPack) pack;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/status.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/status.java
index a4aa482..d0f47f7 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/status.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/status.java
@@ -65,7 +65,7 @@ public class status implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -79,7 +79,7 @@ public class status implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
@@ -87,9 +87,4 @@ public class status implements CommandAbstraction {
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/stop.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/stop.java
index 2d15727..4bc2abb 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/stop.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/stop.java
@@ -35,7 +35,7 @@ public class stop implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -43,18 +43,13 @@ public class stop implements CommandAbstraction {
         return 3;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/time.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/time.java
index 3ae1fce..314810f 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/time.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/time.java
@@ -5,7 +5,6 @@ import java.util.Calendar;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
 
 /**
  * Created by andre on 03/12/15.
@@ -37,12 +36,7 @@ public class time implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
-    }
-
-    @Override
-    public String[] parameters() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -51,7 +45,7 @@ public class time implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/track.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/track.java
index 83eb8e9..20eac16 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/track.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/track.java
@@ -33,7 +33,7 @@ public class track extends music {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -41,18 +41,13 @@ public class track extends music {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tracks.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tracks.java
index e4f7fdb..160fb29 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tracks.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tracks.java
@@ -44,7 +44,7 @@ public class tracks implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -52,18 +52,13 @@ public class tracks implements CommandAbstraction {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tui.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tui.java
new file mode 100644
index 0000000..93e2289
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tui.java
@@ -0,0 +1,119 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.content.Intent;
+import android.net.Uri;
+
+import ohi.andre.consolelauncher.BuildConfig;
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.main.Param;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+/**
+ * Created by francescoandreuzzi on 10/06/2017.
+ */
+
+public class tui extends ParamCommand {
+
+    private enum Param implements ohi.andre.consolelauncher.commands.main.Param {
+
+        rm {
+            @Override
+            public String exec(ExecutePack pack) {
+                MainPack info = (MainPack) pack;
+                info.policy.removeActiveAdmin(info.component);
+
+                Uri packageURI = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
+                Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
+                info.context.startActivity(uninstallIntent);
+
+                return Tuils.EMPTYSTRING;
+            }
+        },
+        about {
+            @Override
+            public String exec(ExecutePack pack) {
+                MainPack info = (MainPack) pack;
+                return info.res.getString(R.string.version_label) + Tuils.SPACE + BuildConfig.VERSION_NAME + Tuils.NEWLINE + Tuils.NEWLINE + info.res.getString(R.string.output_about);
+            }
+        };
+
+        @Override
+        public int[] args() {
+            return new int[0];
+        }
+
+        static Param get(String p) {
+            p = p.toLowerCase();
+            Param[] ps = values();
+            for (Param p1 : ps)
+                if (p.endsWith(p1.label()))
+                    return p1;
+            return null;
+        }
+
+        static String[] labels() {
+            Param[] ps = values();
+            String[] ss = new String[ps.length];
+
+            for(int count = 0; count < ps.length; count++) {
+                ss[count] = ps[count].label();
+            }
+
+            return ss;
+        }
+
+        @Override
+        public String label() {
+            return Tuils.MINUS + name();
+        }
+    }
+
+    @Override
+    protected ohi.andre.consolelauncher.commands.main.Param paramForString(String param) {
+        return Param.get(param);
+    }
+
+    @Override
+    protected String doThings(ExecutePack pack) {
+        return null;
+    }
+
+    @Override
+    public String[] params() {
+        return Param.labels();
+    }
+
+    @Override
+    public int minArgs() {
+        return 1;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 1;
+    }
+
+    @Override
+    public int priority() {
+        return 4;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_tui;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int indexNotFound) {
+        return null;
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return ((MainPack) pack).context.getString(helpRes());
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuisettings.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuisettings.java
deleted file mode 100644
index 3a776b8..0000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuisettings.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;/*Copyright Francesco Andreuzzi
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.*/
-
-import android.app.Activity;
-import android.content.Intent;
-
-import java.io.File;
-
-import ohi.andre.consolelauncher.LauncherActivity;
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.commands.tuixt.TuixtActivity;
-import ohi.andre.consolelauncher.managers.FileManager;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
-import ohi.andre.consolelauncher.tuils.Tuils;
-
-public class tuisettings implements CommandAbstraction {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-
-        File tuiFolder = Tuils.getTuiFolder();
-        final File settingsFile = new File(tuiFolder, PreferencesManager.SETTINGS_FILENAME);
-
-        Intent intent = Tuils.openFile(settingsFile);
-        info.context.startActivity(intent);
-
-        return Tuils.EMPTYSTRING;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return null;
-    }
-
-    @Override
-    public int priority() {
-        return 3;
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_tuisettings;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info) {
-        return null;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java
index d3fa775..8ec7bb8 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java
@@ -30,6 +30,7 @@ public class tuixt implements CommandAbstraction {
         }
 
         Intent intent = new Intent(info.context, TuixtActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.putExtra(TuixtActivity.PATH, file.getAbsolutePath());
         intent.putExtra(TuixtActivity.SKIN, info.skinManager);
         ((Activity) info.context).startActivityForResult(intent, LauncherActivity.TUIXT_REQUEST);
@@ -63,7 +64,7 @@ public class tuixt implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
 
         String path = info.get(String.class, 0);
@@ -97,9 +98,4 @@ public class tuixt implements CommandAbstraction {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.help_tuixt);
     }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tutorial.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tutorial.java
index 9e87210..14fea49 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tutorial.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tutorial.java
@@ -27,7 +27,7 @@ public class tutorial implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -35,18 +35,13 @@ public class tutorial implements CommandAbstraction {
         return 4;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public int helpRes() {
         return R.string.help_tutorial;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java
index a3eb3e6..b82ec5a 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java
@@ -47,7 +47,7 @@ public class unhideapp implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_appnotfound);
     }
@@ -58,11 +58,6 @@ public class unhideapp implements CommandAbstraction {
         return info.res.getString(helpRes());
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     private String unHideApp(MainPack info, String app) {
         SharedPreferences.Editor editor = ((Activity) info.context).getPreferences(0).edit();
         String result = info.appsManager.unhideApp(app);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/uninstall.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/uninstall.java
index 889c05d..a22bc47 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/uninstall.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/uninstall.java
@@ -3,8 +3,6 @@ package ohi.andre.consolelauncher.commands.main.raw;
 import android.content.Intent;
 import android.net.Uri;
 
-import java.io.IOException;
-
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
@@ -49,7 +47,7 @@ public class uninstall implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return new int[]{CommandAbstraction.PACKAGE};
+        return new int[]{CommandAbstraction.VISIBLE_PACKAGE};
     }
 
     @Override
@@ -57,11 +55,6 @@ public class uninstall implements CommandAbstraction {
         return 3;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack pack, int nArgs) {
         MainPack info = (MainPack) pack;
@@ -69,7 +62,7 @@ public class uninstall implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack pack) {
+    public String onArgNotFound(ExecutePack pack, int index) {
         MainPack info = (MainPack) pack;
         return info.res.getString(R.string.output_appnotfound);
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/vibrate.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/vibrate.java
new file mode 100644
index 0000000..6bb0393
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/vibrate.java
@@ -0,0 +1,72 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.content.Context;
+import android.os.Vibrator;
+
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.MainPack;
+
+/**
+ * Created by francescoandreuzzi on 29/04/2017.
+ */
+
+public class vibrate implements CommandAbstraction {
+
+
+    @Override
+    public String exec(ExecutePack pack) throws Exception {
+        String text = (String) pack.args[0];
+
+        Context context = ((MainPack) pack).context;
+
+        int ms;
+        try {
+            ms = Integer.parseInt(text);
+
+            ((Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(ms);
+        } catch (NumberFormatException e) {
+            return context.getString(R.string.output_numberformat);
+        } catch (Exception e) {
+            return e.toString();
+        }
+
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 1;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 1;
+    }
+
+    @Override
+    public int[] argType() {
+        return new int[] {CommandAbstraction.PLAIN_TEXT};
+    }
+
+    @Override
+    public int priority() {
+        return 2;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_vibrate;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack, int index) {
+        return null;
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        return ((MainPack) pack).context.getString(helpRes());
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/wifi.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/wifi.java
index 7ba9098..9a0fe0f 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/wifi.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/wifi.java
@@ -37,7 +37,7 @@ public class wifi implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -45,18 +45,13 @@ public class wifi implements CommandAbstraction {
         return 2;
     }
 
-    @Override
-    public String[] parameters() {
-        return null;
-    }
-
     @Override
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/specific/ParamCommand.java b/app/src/main/java/ohi/andre/consolelauncher/commands/specific/ParamCommand.java
new file mode 100644
index 0000000..833ee60
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/specific/ParamCommand.java
@@ -0,0 +1,44 @@
+package ohi.andre.consolelauncher.commands.specific;
+
+import android.util.Log;
+
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.Param;
+
+/**
+ * Created by francescoandreuzzi on 01/05/2017.
+ */
+
+public abstract class ParamCommand implements CommandAbstraction {
+
+    @Override
+    public final int[] argType() {
+        return new int[] {CommandAbstraction.PARAM};
+    }
+
+    @Override
+    public final String exec(ExecutePack pack) throws Exception {
+        String o = doThings(pack);
+        if(o != null) return o;
+
+        try {
+            return paramForString(pack.get(String.class, 0)).exec(pack);
+        } catch (NullPointerException e) {
+            return pack.context.getString(R.string.output_invalid_param);
+        }
+    }
+
+    public final int[] argsForParam(String param) {
+        try {
+            return paramForString(param).args();
+        } catch (NullPointerException e) {
+            return null;
+        }
+    }
+
+    public abstract String[] params();
+    protected abstract Param paramForString(String param);
+    protected abstract String doThings(ExecutePack pack);
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java
index 9de3caf..dc125a2 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java
@@ -25,12 +25,12 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 
-import ohi.andre.consolelauncher.LauncherActivity;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.Command;
 import ohi.andre.consolelauncher.commands.CommandGroup;
 import ohi.andre.consolelauncher.commands.CommandTuils;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.FileManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
@@ -81,9 +81,8 @@ public class TuixtActivity extends Activity {
         if(skinManager == null) {
             try {
                 Resources res = getResources();
-                PreferencesManager preferencesManager = new PreferencesManager(res.openRawResource(R.raw.settings), res.openRawResource(R.raw.alias), Tuils.getFolder());
-                skinManager = new SkinManager(preferencesManager);
-            } catch (IOException e) {
+                skinManager = new SkinManager();
+            } catch (Exception e) {
                 return;
             }
         }
@@ -246,6 +245,14 @@ public class TuixtActivity extends Activity {
         finish();
     }
 
+    @Override
+    protected void onStop() {
+        super.onStop();
+
+        FileManager.writeOn(pack.editFile, fileView.getText().toString());
+        this.finish();
+    }
+
     private void onNewInput() {
         try {
             String input = inputView.getText().toString();
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtPack.java b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtPack.java
index 8ea190a..705e35a 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtPack.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtPack.java
@@ -5,7 +5,6 @@ import android.content.res.Resources;
 import android.widget.EditText;
 
 import java.io.File;
-import java.util.Objects;
 
 import ohi.andre.consolelauncher.commands.CommandGroup;
 import ohi.andre.consolelauncher.commands.ExecutePack;
@@ -19,7 +18,6 @@ public class TuixtPack extends ExecutePack {
     public File editFile;
     public EditText editText;
 
-    public Context context;
     public Resources resources;
 
     public TuixtPack(CommandGroup group, File file, Context context, EditText editText) {
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/exit.java b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/exit.java
index 9af4018..9f8a5d0 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/exit.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/exit.java
@@ -33,7 +33,7 @@ public class exit implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -47,7 +47,7 @@ public class exit implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
@@ -55,9 +55,4 @@ public class exit implements CommandAbstraction {
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/help.java b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/help.java
index a0a3e2e..fd90d4d 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/help.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/help.java
@@ -10,7 +10,6 @@ import ohi.andre.comparestring.Compare;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.tuixt.TuixtPack;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
@@ -55,7 +54,7 @@ public class help implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return onNotArgEnough(info, 0);
     }
 
@@ -77,9 +76,4 @@ public class help implements CommandAbstraction {
 
         return Tuils.toPlanString(toPrint, Tuils.EMPTYSTRING);
     }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/save.java b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/save.java
index 0687904..1887458 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/save.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/raw/save.java
@@ -38,7 +38,7 @@ public class save implements CommandAbstraction {
 
     @Override
     public int[] argType() {
-        return null;
+        return new int[0];
     }
 
     @Override
@@ -52,7 +52,7 @@ public class save implements CommandAbstraction {
     }
 
     @Override
-    public String onArgNotFound(ExecutePack info) {
+    public String onArgNotFound(ExecutePack info, int index) {
         return null;
     }
 
@@ -60,9 +60,4 @@ public class save implements CommandAbstraction {
     public String onNotArgEnough(ExecutePack info, int nArgs) {
         return null;
     }
-
-    @Override
-    public String[] parameters() {
-        return null;
-    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
index aad0aab..9dbb311 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
@@ -1,34 +1,44 @@
 package ohi.andre.consolelauncher.managers;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.File;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.Reloadable;
 
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.resetFile;
+
 public class AliasManager implements Reloadable {
 
-    private Map<String, String> alias;
-    private PreferencesManager preferences;
+    private final String NAME = "ALIAS";
+    private final String PATH = "alias.xml";
+
+    private final String VALUE_ATTRIBUTE = "value";
+
+    private XMLPrefsManager.XMLPrefsList alias;
 
-    public AliasManager(PreferencesManager prefs) {
-        this.preferences = prefs;
+    public AliasManager() {
         reload();
     }
 
     public String printAliases() {
-        Iterator<Entry<String, String>> iterator = alias.entrySet().iterator();
+        List<XMLPrefsManager.XMLPrefsEntry> list = alias.list;
 
         String output = Tuils.EMPTYSTRING;
-        Entry<String, String> entry;
-        while (iterator.hasNext()) {
-            entry = iterator.next();
-            output = output.concat(entry.getKey() + " = " + entry.getValue() + Tuils.NEWLINE);
+        for (XMLPrefsManager.XMLPrefsEntry entry : list) {
+            output = output.concat(entry.key + " --> " + entry.value + Tuils.NEWLINE);
         }
 
-        return output;
+        return output.trim();
     }
 
     public int getNum() {
@@ -36,19 +46,56 @@ public class AliasManager implements Reloadable {
     }
 
     public String getAlias(String s) {
-        return alias.get(s);
+        XMLPrefsManager.XMLPrefsEntry entry = alias.get(s);
+        if(entry != null) return entry.value;
+        return null;
     }
 
     @Override
     public void reload() {
-        alias = new HashMap<>();
-        preferences.refresh(PreferencesManager.ALIAS);
-        for (int count = 0; count < preferences.getLength(PreferencesManager.ALIAS); count++) {
-            String line = preferences.getLine(PreferencesManager.ALIAS, count);
-            String name = preferences.obtainKey(line);
-            String value = preferences.obtainValue(line);
-
-            alias.put(name, value);
+        if(alias != null) alias.list.clear();
+        alias = new XMLPrefsManager.XMLPrefsList();
+
+        File file = new File(Tuils.getFolder(), PATH);
+
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder = null;
+        try {
+            builder = factory.newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            return;
+        }
+
+        Document d;
+        try {
+            d = builder.parse(file);
+        } catch (Exception e) {
+            resetFile(file, NAME);
+
+            try {
+                d = builder.parse(file);
+            } catch (Exception e1) {return;}
+        }
+
+        Element root = (Element) d.getElementsByTagName(NAME).item(0);
+        if(root == null) {
+            resetFile(file, NAME);
+
+            try {
+                d = builder.parse(file);
+            } catch (Exception e) {
+                return;
+            }
+
+            root = (Element) d.getElementsByTagName(NAME).item(0);
+        }
+        NodeList nodes = root.getElementsByTagName("*");
+
+        for(int count = 0; count < nodes.getLength(); count++) {
+            Node node = nodes.item(count);
+
+            String nn = node.getNodeName();
+            alias.add(nn, node.getAttributes().getNamedItem(VALUE_ATTRIBUTE).getNodeValue());
         }
     }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
index c4069e0..c3bbd95 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
@@ -1,52 +1,132 @@
 package ohi.andre.consolelauncher.managers;
 
-import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.os.Build;
 import android.os.Handler;
-import android.util.Log;
+import android.support.annotation.NonNull;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
 import ohi.andre.comparestring.Compare;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
 
-public class AppsManager {
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.VALUE_ATTRIBUTE;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.resetFile;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.set;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.writeTo;
+
+public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
 
     public static final int SHOWN_APPS = 10;
     public static final int HIDDEN_APPS = 11;
 
-    public static final int MIN_RATE = 5;
-    public static final boolean USE_SCROLL_COMPARE = true;
+    public static final boolean USE_SCROLL_COMPARE = false;
 
-    private final int SUGGESTED_APPS_LENGTH = 5;
+    public static final String PATH = "apps.xml";
+    private final String NAME = "APPS";
 
-    private final String APPS_PREFERENCES = "appsPreferences";
+    private final String SHOW_ATTRIBUTE = "show";
 
     private Context context;
-    private SharedPreferences.Editor prefsEditor;
+    private File folder;
 
     private AppsHolder appsHolder;
     private List<AppInfo> hiddenApps;
 
     private Outputable outputable;
 
-    private boolean useCompareString;
+    private final String PREFS = "apps";
+    private SharedPreferences preferences;
+    private SharedPreferences.Editor editor;
+
+    public enum Options implements XMLPrefsManager.XMLPrefsSave {
+
+        default_app_n1 {
+            @Override
+            public String defaultValue() {
+                return MOST_USED;
+            }
+        },
+        default_app_n2 {
+            @Override
+            public String defaultValue() {
+                return MOST_USED;
+            }
+        },
+        default_app_n3 {
+            @Override
+            public String defaultValue() {
+                return "com.android.vending";
+            }
+        },
+        default_app_n4 {
+            @Override
+            public String defaultValue() {
+                return NULL;
+            }
+        },
+        default_app_n5 {
+            @Override
+            public String defaultValue() {
+                return NULL;
+            }
+        };
+
+        static final String MOST_USED = "most_used";
+        static final String NULL = "null";
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public XMLPrefsManager.XMLPrefsRoot parent() {
+            return null;
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    @Override
+    public void write(XMLPrefsManager.XMLPrefsSave save, String value) {
+        set(new File(Tuils.getFolder(), PATH), NAME, save.label(), new String[] {VALUE_ATTRIBUTE}, new String[] {value});
+    }
+
+    @Override
+    public XMLPrefsManager.XMLPrefsList getValues() {
+        return null;
+    }
 
     private BroadcastReceiver appsBroadcast = new BroadcastReceiver() {
         @Override
@@ -60,15 +140,16 @@ public class AppsManager {
         }
     };
 
-    public AppsManager(Context context, boolean useCompareString, Outputable outputable) {
+    public AppsManager(Context context, Outputable outputable) {
         this.context = context;
-        this.useCompareString = useCompareString;
-
         this.outputable = outputable;
 
-        SharedPreferences preferences = context.getSharedPreferences(APPS_PREFERENCES, Context.MODE_PRIVATE);
-        prefsEditor = preferences.edit();
-        fill(preferences);
+        this.preferences = context.getSharedPreferences(PREFS, 0);
+        this.editor = preferences.edit();
+
+        this.folder = Tuils.getFolder();
+
+        fill();
 
         initAppListener(context);
     }
@@ -82,37 +163,79 @@ public class AppsManager {
         c.registerReceiver(appsBroadcast, intentFilter);
     }
 
-    public void fill(SharedPreferences preferences) {
+    public void fill() {
         Map<String, AppInfo> map = createAppMap(context.getPackageManager());
         List<AppInfo> shownApps = new ArrayList<>();
         hiddenApps = new ArrayList<>();
 
-        Map<String, ?> values;
+        XMLPrefsManager.XMLPrefsList values = new XMLPrefsManager.XMLPrefsList();
+
         try {
-            values = preferences.getAll();
-        } catch (Exception e) {
-            for(Map.Entry<String, AppInfo> entry : map.entrySet()) {
-                shownApps.add(entry.getValue());
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            File file = new File(folder, PATH);
+            if(!file.exists() && !file.createNewFile()) return;
+
+            Document d;
+            try {
+                d = builder.parse(file);
+            } catch (Exception e) {
+                resetFile(file, NAME);
+                d = builder.parse(file);
             }
-            appsHolder = new AppsHolder(shownApps);
-            return;
-        }
 
-        for(Map.Entry<String, ?> entry : values.entrySet()) {
-            if(entry.getValue() instanceof Boolean) {
-                if((Boolean) entry.getValue()) {
-                    AppInfo info = map.get(entry.getKey());
-                    hiddenApps.add(info);
-                    map.remove(entry.getKey());
-                }
-            } else {
-                AppInfo info = map.get(entry.getKey());
-                if(info == null) {
-                    continue;
+            List<AppsManager.Options> enums = new ArrayList<>(Arrays.asList(AppsManager.Options.values()));
+
+            Element root = (Element) d.getElementsByTagName(NAME).item(0);
+            if(root == null) {
+                resetFile(file, NAME);
+
+                d = builder.parse(file);
+                root = (Element) d.getElementsByTagName(NAME).item(0);
+            }
+
+            NodeList nodes = root.getElementsByTagName("*");
+            for(int count = 0; count < nodes.getLength(); count++) {
+                Node node = nodes.item(count);
+
+                String nn = node.getNodeName();
+                int nodeIndex = Tuils.find(nn, (List) enums);
+                if(nodeIndex != -1) {
+                    values.add(nn, node.getAttributes().getNamedItem(VALUE_ATTRIBUTE).getNodeValue());
+
+                    for(int en = 0; en < enums.size(); en++) {
+                        if(enums.get(en).label().equals(nn)) {
+                            enums.remove(en);
+                            break;
+                        }
+                    }
                 } else {
-                    info.launchedTimes = (Integer) entry.getValue();
+                    if(node.getNodeType() == Node.ELEMENT_NODE) {
+                        Element e = (Element) node;
+
+                        boolean shown = !e.hasAttribute(SHOW_ATTRIBUTE) || Boolean.parseBoolean(e.getAttribute(SHOW_ATTRIBUTE));
+                        if(!shown) {
+                            hiddenApps.add(map.remove(nn));
+                        }
+                    }
                 }
             }
+
+            if(enums.size() > 0) {
+                for(XMLPrefsManager.XMLPrefsSave s : enums) {
+                    Element em = d.createElement(s.label());
+                    em.setAttribute(VALUE_ATTRIBUTE, s.defaultValue());
+                    root.appendChild(em);
+
+                    values.add(s.label(), s.defaultValue());
+                }
+                writeTo(d, file);
+            }
+        } catch (Exception e) {}
+
+        for(Map.Entry<String, ?> entry : this.preferences.getAll().entrySet()) {
+            if (entry.getValue() instanceof Integer) map.get(entry.getKey()).launchedTimes = (Integer) entry.getValue();
         }
 
         for (Map.Entry<String, AppInfo> stringAppInfoEntry : map.entrySet()) {
@@ -120,20 +243,46 @@ public class AppsManager {
             shownApps.add(app);
         }
 
-        appsHolder = new AppsHolder(shownApps);
+        appsHolder = new AppsHolder(shownApps, values);
         AppUtils.checkEquality(hiddenApps);
     }
 
     private Map<String, AppInfo> createAppMap(PackageManager mgr) {
         Map<String, AppInfo> map = new HashMap<>();
 
-        Intent i = new Intent(Intent.ACTION_MAIN, null);
-        i.addCategory(Intent.CATEGORY_LAUNCHER);
-        List<ResolveInfo> infos = mgr.queryIntentActivities(i, 0);
-
-        for (ResolveInfo info : infos) {
-            AppInfo app = new AppInfo(info.activityInfo.packageName, info.loadLabel(mgr).toString());
-            map.put(info.activityInfo.packageName, app);
+//        Intent i = new Intent(Intent.ACTION_MAIN, null);
+//        i.addCategory(Intent.CATEGORY_LAUNCHER);
+//        List<ResolveInfo> infos = mgr.queryIntentActivities(i, 0);
+//
+//        for (ResolveInfo info : infos) {
+//            AppInfo app = new AppInfo(info.activityInfo.packageName, info.loadLabel(mgr).toString());
+//            map.put(info.activityInfo.packageName, app);
+//        }
+//
+//        return map;
+
+        for(ApplicationInfo info : mgr.getInstalledApplications(0)){
+            Intent intent = new Intent();
+            intent.addCategory(Intent.CATEGORY_LAUNCHER);
+            intent.setAction(Intent.ACTION_MAIN);
+            intent.setPackage(info.packageName);
+            List<ResolveInfo> list = mgr.queryIntentActivities(intent, 0);
+
+            for(ResolveInfo rInfo:list) {
+                ActivityInfo activity = rInfo.activityInfo;
+
+                Intent i = new Intent();
+                i.addCategory(Intent.CATEGORY_LAUNCHER);
+                i.setAction(Intent.ACTION_MAIN);
+                i.setPackage(activity.packageName);
+                i.setComponent(new ComponentName(activity.packageName, activity.name));
+                ResolveInfo in = mgr.resolveActivity(i, 0);
+
+                ActivityInfo aInfo = in.activityInfo;
+
+                AppInfo app = new AppInfo(aInfo.packageName, aInfo.loadLabel(mgr).toString());
+                map.put(aInfo.packageName, app);
+            }
         }
 
         return map;
@@ -182,29 +331,29 @@ public class AppsManager {
     }
 
     public String findPackage(List<AppInfo> appList, List<String> labels, String name) {
-        name = Compare.removeSpaces(name).toLowerCase();
-        if(labels == null) {
-            labels = AppUtils.labelList(appList);
-        }
-
-        if(useCompareString) {
-            String label = Compare.similarString(labels, name, MIN_RATE, USE_SCROLL_COMPARE);
-            if (label == null) {
-                return null;
-            }
+        name = Compare.removeSpaces(name);
+//        if(labels == null) {
+//            labels = AppUtils.labelList(appList);
+//        }
 
+//        if(useCompareString) {
+//            String label = Compare.similarString(labels, name, MIN_RATE, USE_SCROLL_COMPARE);
+//            if (label == null) {
+//                return null;
+//            }
+//
+//            for(AppInfo info : appList) {
+//                if (info.publicLabel.equals(name)) {
+//                    return info.packageName;
+//                }
+//            }
+//        } else {
             for(AppInfo info : appList) {
-                if (info.publicLabel.equals(name)) {
+                if(name.equalsIgnoreCase(Compare.removeSpaces(Compare.removeSpaces(info.publicLabel)))) {
                     return info.packageName;
                 }
             }
-        } else {
-            for(AppInfo info : appList) {
-                if(name.equals(Compare.removeSpaces(info.publicLabel.toLowerCase()))) {
-                    return info.packageName;
-                }
-            }
-        }
+//        }
 
         return null;
     }
@@ -216,13 +365,13 @@ public class AppsManager {
         }
 
         info.launchedTimes++;
-        appsHolder.updateSuggestion(info);
+        appsHolder.requestSuggestionUpdate(info);
 
-        prefsEditor.putInt(packageName, info.launchedTimes);
+        editor.putInt(packageName, info.launchedTimes);
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
-            applyPrefs();
+            editor.apply();
         } else {
-            prefsEditor.commit();
+            editor.commit();
         }
 
         return context.getPackageManager().getLaunchIntentForPackage(packageName);
@@ -234,18 +383,13 @@ public class AppsManager {
             return null;
         }
 
+        set(new File(folder, PATH), NAME, info.packageName, new String[] {SHOW_ATTRIBUTE}, new String[] {false + Tuils.EMPTYSTRING});
+
         appsHolder.remove(info);
         appsHolder.update(true);
         hiddenApps.add(info);
         AppUtils.checkEquality(hiddenApps);
 
-        prefsEditor.putBoolean(packageName, true);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
-            applyPrefs();
-        } else {
-            prefsEditor.commit();
-        }
-
         return info.publicLabel;
     }
 
@@ -255,17 +399,12 @@ public class AppsManager {
             return null;
         }
 
+        set(new File(folder, PATH), NAME, info.packageName, new String[] {SHOW_ATTRIBUTE}, new String[] {true + Tuils.EMPTYSTRING});
+
         hiddenApps.remove(info);
         appsHolder.add(info);
         appsHolder.update(false);
 
-        prefsEditor.putBoolean(packageName, false);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
-            applyPrefs();
-        } else {
-            prefsEditor.commit();
-        }
-
         return info.publicLabel;
     }
 
@@ -278,6 +417,7 @@ public class AppsManager {
     }
 
     public String[] getSuggestedApps() {
+        if(appsHolder == null) return new String[0];
         return appsHolder.getSuggestedApps();
     }
 
@@ -294,11 +434,6 @@ public class AppsManager {
         unregisterReceiver(context);
     }
 
-    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
-    private void applyPrefs() {
-        prefsEditor.apply();
-    }
-
     public static class AppInfo {
 
         public String packageName;
@@ -324,10 +459,8 @@ public class AppsManager {
 
             if(o instanceof AppInfo) {
                 AppInfo i = (AppInfo) o;
-                return this.packageName.equals(i.packageName);
-            } else if(o instanceof String) {
-                return this.packageName.equals(o);
-            }
+                return (this.packageName == null && i.packageName == null) || (this.packageName != null && i.packageName != null && this.packageName.equals(i.packageName));
+            } else if(o instanceof String) return this.packageName != null && this.packageName.equals(o);
             return false;
         }
 
@@ -344,44 +477,204 @@ public class AppsManager {
 
     private class AppsHolder {
 
+        int MOST_USED = 10, NULL = 11, USER_DEFINIED = 12;
+
         private List<AppInfo> infos;
         private List<String> appLabels;
-        private AppInfo[] suggestedApps = new AppInfo[SUGGESTED_APPS_LENGTH];
+        private XMLPrefsManager.XMLPrefsList values;
 
-        Comparator<AppInfo> mostUsedComparator = new Comparator<AppInfo>() {
-            @Override
-            public int compare(AppInfo lhs, AppInfo rhs) {
-                return rhs.launchedTimes > lhs.launchedTimes ? -1 : rhs.launchedTimes == lhs.launchedTimes ? 0 : 1;
+        private SuggestedAppMgr suggestedAppMgr;
+
+        private class SuggestedAppMgr {
+            private List<SuggestedApp> suggested;
+            private int lastWriteable = -1;
+
+            public SuggestedAppMgr(XMLPrefsManager.XMLPrefsList values) {
+                suggested = new ArrayList<>();
+
+                final String PREFIX = "default_app_n";
+                for(int count = 0; count < Options.values().length; count++) {
+                    String vl = values.get(Options.valueOf(PREFIX + (count + 1))).value;
+
+                    if(vl.equals(Options.NULL)) suggested.add(new SuggestedApp(NULL));
+                    if(vl.equals(Options.MOST_USED)) suggested.add(new SuggestedApp(MOST_USED));
+                    else {
+                        AppInfo info = AppUtils.findAppInfo(vl, infos);
+                        if(info == null) suggested.add(new SuggestedApp(NULL));
+                        else suggested.add(new SuggestedApp(info, USER_DEFINIED));
+                    }
+                }
+
+                sort();
+
+                handler.postDelayed(runnable, 1000 * 60 * 5);
             }
-        };
 
-//        workaround to check if in suggested apps there are duplicates
-        private Handler handler = new Handler();
-        private Runnable runnable = new Runnable() {
-            @Override
-            public void run() {
-                if(suggestedApps != null) {
+            public int size() {
+                return suggested.size();
+            }
+
+            private void sort() {
+                Collections.sort(suggested);
+                for(int count = 0; count < suggested.size(); count++) {
+                    if(suggested.get(count).type != MOST_USED) {
+                        lastWriteable = count - 1;
+                        return;
+                    }
+                }
+            }
+
+            public SuggestedApp get(int index) {
+                return suggested.get(index);
+            }
+
+            public void set(int index, AppInfo info) {
+                suggested.get(index).change(info);
+            }
+
+            public int indexOf(AppInfo info) {
+                return suggested.indexOf(info);
+            }
+
+            private void remove(int index) {
+                suggested.remove(index);
+            }
+
+            public void attemptInsertSuggestion(AppInfo info) {
+                if (info.launchedTimes == 0) {
+                    return;
+                }
+
+                if(lastWriteable == -1) return;
+
+                int index = indexOf(info);
+                if (index == -1) {
+                    for (int count = 0; count <= lastWriteable; count++) {
+                        SuggestedApp app = get(count);
+                        if (app.app == null || info.launchedTimes > app.app.launchedTimes) {
+                            this.remove(lastWriteable);
+                            SuggestedApp s = suggested.remove(0);
+                            s.change(info);
+                            suggested.add(0, s);
+                        }
+                    }
+                }
+                sort();
+            }
+
+//            public void updateSuggestion(AppInfo info) {
+//                int index = indexOf(info);
+//
+//                if(index == -1) {
+//                    attemptInsertSuggestion(info);
+//                } else if(index == 0) {
+//                    return;
+//                } else {
+//                    for(int count = 0; count < index; count++) {
+//                        if(get(count).type == NULL ) {
+//                            if(count == lastNull()) {
+//                                suggestedApps[count] = info;
+//                                return;
+//                            }
+//                        } else if(suggestedApps[count].launchedTimes < info.launchedTimes) {
+//
+//                            System.arraycopy(suggestedApps, count, suggestedApps, count + 1, index - count);
+//                            suggestedApps[count] = info;
+//
+//                            return;
+//                        }
+//                    }
+//                }
+//            }
+
+            public List<String> labels() {
+                List<AppInfo> list = new ArrayList<>();
+                for(int count = 0; count < suggested.size(); count++) {
+                    SuggestedApp app = suggested.get(count);
+                    if(app.type != NULL && app.app != null) list.add(app.app);
+                }
+                return AppUtils.labelList(list);
+            }
+
+            private Handler handler = new Handler();
+            private Runnable runnable = new Runnable() {
+                @Override
+                public void run() {
                     if(duplicates()) {
                         fillSuggestions();
                     }
+                    handler.postDelayed(runnable, 1000 * 60 * 2);
+                }
+
+                private boolean duplicates() {
+                    for (int count =0; count < size(); count++)
+                        for (int count2 = count+1 ; count2 < size(); count2++)
+                            if (count != count2 && get(count) == get(count2))
+                                return true;
+                    return false;
+                }
+            };
+
+            private class SuggestedApp implements Comparable {
+                int type;
+                AppInfo app;
+
+                public SuggestedApp(int type) {
+                    this(null, type);
+                }
+
+                public SuggestedApp(AppInfo info, int type) {
+                    this.app = info;
+                    this.type = type;
+                }
+
+                public SuggestedApp change(AppInfo info) {
+                    this.app = info;
+                    return this;
+                }
+
+                @Override
+                public boolean equals(Object o) {
+                    return this.app != null && o instanceof SuggestedApp && ((SuggestedApp) o).app != null && this.app.equals(((SuggestedApp) o).app);
+                }
+
+                @Override
+                public int compareTo(@NonNull Object o) {
+                    SuggestedApp other = (SuggestedApp) o;
+                    if(this.type == NULL || other.type == NULL) {
+                        if(this.type == NULL && other.type == NULL) return 0;
+                        if(this.type == NULL) return 1;
+                        return -1;
+                    }
+
+                    if(this.type == USER_DEFINIED || other.type == USER_DEFINIED) {
+                        if(this.type == USER_DEFINIED && other.type == USER_DEFINIED) return other.app.launchedTimes - this.app.launchedTimes;
+                        if(this.type == USER_DEFINIED) return 1;
+                        return -1;
+                    }
+
+//                    most_used
+                    if(this.app == null || other.app == null) {
+                        if(this.app == null && other.app == null) return 0;
+                        if(this.app == null) return -1;
+                        return 1;
+                    }
+                    return other.app.launchedTimes - this.app.launchedTimes;
                 }
-                handler.postDelayed(runnable, 1000 * 60 * 2);
             }
+        }
 
-            private boolean duplicates() {
-                for (int count =0; count < suggestedApps.length; count++)
-                    for (int count2 = count+1 ; count2 < suggestedApps.length; count2++)
-                        if (count != count2 && suggestedApps[count] == suggestedApps[count2])
-                            return true;
-                return false;
+        Comparator<AppInfo> mostUsedComparator = new Comparator<AppInfo>() {
+            @Override
+            public int compare(AppInfo lhs, AppInfo rhs) {
+                return rhs.launchedTimes > lhs.launchedTimes ? -1 : rhs.launchedTimes == lhs.launchedTimes ? 0 : 1;
             }
         };
 
-        public AppsHolder(List<AppInfo> infos) {
+        public AppsHolder(List<AppInfo> infos, XMLPrefsManager.XMLPrefsList values) {
             this.infos = infos;
+            this.values = values;
             update(true);
-
-            handler.postDelayed(runnable, 1000 * 60 * 5);
         }
 
         public void add(AppInfo info) {
@@ -396,40 +689,6 @@ public class AppsManager {
             update(true);
         }
 
-        public void updateSuggestion(AppInfo info) {
-            int index = suggestionIndex(info);
-
-            if(index == -1) {
-                attemptInsertSuggestion(info);
-            } else if(index == 0) {
-                return;
-            } else {
-                for(int count = 0; count < index; count++) {
-                    if(suggestedApps[count] == null) {
-                        if(count == lastNull()) {
-                            suggestedApps[count] = info;
-                            return;
-                        }
-                    } else if(suggestedApps[count].launchedTimes < info.launchedTimes) {
-
-                        System.arraycopy(suggestedApps, count, suggestedApps, count + 1, index - count);
-                        suggestedApps[count] = info;
-
-                        return;
-                    }
-                }
-            }
-        }
-
-        private int suggestionIndex(AppInfo app) {
-            for(int count = 0; count < suggestedApps.length; count++) {
-                if(app.equals(suggestedApps[count])) {
-                    return count;
-                }
-            }
-            return -1;
-        }
-
         private void sort() {
             try {
                 Collections.sort(infos, mostUsedComparator);
@@ -441,38 +700,24 @@ public class AppsManager {
         }
 
         private void fillSuggestions() {
-            suggestedApps = new AppInfo[SUGGESTED_APPS_LENGTH];
+            suggestedAppMgr = new SuggestedAppMgr(values);
             for(AppInfo info : infos) {
-                attemptInsertSuggestion(info);
+                suggestedAppMgr.attemptInsertSuggestion(info);
             }
         }
 
-        private void attemptInsertSuggestion(AppInfo info) {
-            if(info.launchedTimes == 0){
-                return;
-            }
-            for(int count = 0; count < suggestedApps.length; count++) {
-                if(suggestedApps[count] == null) {
-                    suggestedApps[count] = info;
-                    return;
-                } else {
-                    if(info.launchedTimes > suggestedApps[count].launchedTimes) {
-                        System.arraycopy(suggestedApps, count, suggestedApps, count + 1, suggestedApps.length - (count + 1));
-                        suggestedApps[count] = info;
-                        return;
-                    }
-                }
-            }
+        public void requestSuggestionUpdate(AppInfo info) {
+            suggestedAppMgr.attemptInsertSuggestion(info);
         }
 
-        private int lastNull() {
-            for(int count = suggestedApps.length - 1; count >= 0; count--) {
-                if(suggestedApps[count] == null) {
-                    return count;
-                }
-            }
-            return -1;
-        }
+//        private int lastNull() {
+//            for(int count = suggestedApps.length - 1; count >= 0; count--) {
+//                if(suggestedApps[count] == null) {
+//                    return count;
+//                }
+//            }
+//            return -1;
+//        }
 
         private void update(boolean refreshSuggestions) {
             AppUtils.checkEquality(infos);
@@ -492,9 +737,9 @@ public class AppsManager {
         }
 
         public String[] getSuggestedApps() {
-            return AppUtils.labelList(suggestedApps);
+            List<String> ls = suggestedAppMgr.labels();
+            return ls.toArray(new String[ls.size()]);
         }
-
     }
 
     private static class AppUtils {
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/ContactManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/ContactManager.java
index bbb6e96..b08b737 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/ContactManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/ContactManager.java
@@ -5,20 +5,20 @@ import android.app.Activity;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
+import android.net.Uri;
 import android.provider.ContactsContract;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.content.ContextCompat;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
 
 import ohi.andre.comparestring.Compare;
 import ohi.andre.consolelauncher.LauncherActivity;
+import ohi.andre.consolelauncher.tuils.Tuils;
 
 public class ContactManager {
 
@@ -41,6 +41,37 @@ public class ContactManager {
         Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
         if (phones != null) {
             while (phones.moveToNext()) {
+//                if(!phones.getString(phones.getColumnIndex("sort_key")).equals("Numero Fittizio")) continue;
+//
+//                for(int count = 0; count < phones.getColumnCount(); count++) {
+//
+//                    Log.e("andre", phones.getColumnName(count));
+//                    int type = phones.getType(count);
+//                    switch (type) {
+//                        case Cursor.FIELD_TYPE_STRING:
+//                            Log.e("andre", "string");
+//                            Log.e("andre", phones.getString(count));
+//                            break;
+//                        case Cursor.FIELD_TYPE_FLOAT:
+//                            Log.e("andre", "float");
+//                            Log.e("andre", String.valueOf(phones.getFloat(count)));
+//                            break;
+//                        case Cursor.FIELD_TYPE_BLOB:
+//                            Log.e("andre", "blob");
+//                            Log.e("andre", Arrays.toString(phones.getBlob(count)));
+//                            break;
+//                        case Cursor.FIELD_TYPE_INTEGER:
+//                            Log.e("andre", "int");
+//                            Log.e("andre", String.valueOf(phones.getInt(count)));
+//                            break;
+//                        case Cursor.FIELD_TYPE_NULL:
+//                            Log.e("andre", "null");
+//                            break;
+//                    }
+////                    Log.e("andre", phones.getColumnName(count) + ", " + phones.getString(count));
+//                }
+//                Log.e("andre", "#######");
+//
                 String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                 String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
 
@@ -52,21 +83,209 @@ public class ContactManager {
         return contacts;
     }
 
-    public List<String> names() {
-        Set<String> strings = getContacts().keySet();
-        List<String> list = new ArrayList<>(strings);
-        Collections.sort(list);
-        return list;
+    public List<String> listNames() {
+        List<String> contacts = new ArrayList<>();
+
+        if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_SUGGESTION_REQUEST_PERMISSION);
+            return contacts;
+        }
+
+        Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME}, null, null,
+                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
+
+        if (phones != null) {
+            while (phones.moveToNext()) {
+                String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
+                contacts.add(name);
+            }
+            phones.close();
+        }
+
+        return contacts;
     }
 
-    public ArrayList<String> listNamesAndNumbers() {
-        ArrayList<String> values = new ArrayList<>();
+    public List<Contact> listContacts() {
+        List<Contact> contacts = new ArrayList<>();
+
+        if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_SUGGESTION_REQUEST_PERMISSION);
+            return contacts;
+        }
+
+        Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                new String[] {ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Data.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Data.IS_SUPER_PRIMARY,}, null, null,
+                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
+
+        if (phones != null) {
+
+            int lastId = -1;
+            List<String> lastNumbers = new ArrayList<>();
+            List<String> nrml = new ArrayList<>();
+            int defaultNumber = 0;
+            String name = null, number;
+            int id, prim;
+
+            while (phones.moveToNext()) {
+                id = phones.getInt(phones.getColumnIndex(ContactsContract.Data.CONTACT_ID));
+                number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
+
+                prim = phones.getInt(phones.getColumnIndex(ContactsContract.Data.IS_SUPER_PRIMARY));
+                if(prim > 0) {
+                    defaultNumber = lastNumbers.size() - 1;
+                }
+
+                if(number == null || number.length() == 0) continue;
+
+                if(phones.isFirst()) {
+                    lastId = id;
+                    name = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+                } else if(id != lastId || phones.isLast()) {
+                    lastId = id;
 
-        Set<Entry<String, String>> set = getContacts().entrySet();
-        for (Entry<String, String> entry : set)
-            values.add(entry.getKey() + "\t:\t" + entry.getValue());
+                    contacts.add(new Contact(name, lastNumbers, defaultNumber));
+
+                    lastNumbers = new ArrayList<>();
+                    nrml = new ArrayList<>();
+
+                    name = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+                }
+
+                String normalized = number.replaceAll(Tuils.SPACE, Tuils.EMPTYSTRING);
+                if(!nrml.contains(normalized)) {
+                    nrml.add(normalized);
+                    lastNumbers.add(number);
+                }
+            }
+            phones.close();
+        }
 
-        return values;
+        return contacts;
+    }
+
+    public List<String> listNamesAndNumbers() {
+
+        List<String> contacts = new ArrayList<>();
+
+        Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                new String[] {ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Data.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null,
+                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
+
+        if (phones != null) {
+
+            int lastId = -1;
+            List<String> lastNumbers = new ArrayList<>();
+            List<String> nrml = new ArrayList<>();
+            String name = null;
+
+            while (phones.moveToNext()) {
+                int id = phones.getInt(phones.getColumnIndex(ContactsContract.Data.CONTACT_ID));
+                String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
+
+                if(number == null || number.length() == 0) continue;
+
+                if(phones.isFirst()) {
+                    lastId = id;
+                    name = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+                } else if(id != lastId || phones.isLast()) {
+                    lastId = id;
+
+                    for(String n : lastNumbers) {
+                        name = name + Tuils.NEWLINE + "\t\t\t" + n;
+                    }
+                    contacts.add(name);
+
+                    lastNumbers = new ArrayList<>();
+                    nrml = new ArrayList<>();
+
+                    name = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
+                }
+
+                String normalized = number.replaceAll(Tuils.SPACE, Tuils.EMPTYSTRING);
+                if(!nrml.contains(normalized)) {
+                    nrml.add(normalized);
+                    lastNumbers.add(number);
+                }
+            }
+            phones.close();
+        }
+
+        return contacts;
+    }
+
+    public static final int NAME = 0;
+    public static final int NUMBERS = 1;
+    public static final int TIME_CONTACTED = 2;
+    public static final int LAST_CONTACTED = 3;
+    public static final int CONTACT_ID = 4;
+    public static final int SIZE = CONTACT_ID + 1;
+
+    public String[] about(String phone) {
+        Cursor mCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                new String[] {ContactsContract.CommonDataKinds.Phone.CONTACT_ID},
+                ContactsContract.CommonDataKinds.Phone.NUMBER + " = ?", new String[] {phone},
+                null);
+
+        if(mCursor == null || mCursor.getCount() == 0) return null;
+        String[] about = new String[SIZE];
+
+        mCursor.moveToNext();
+
+        String id = mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
+        about[CONTACT_ID] = id;
+
+        mCursor.close();
+        mCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.TIMES_CONTACTED, ContactsContract.CommonDataKinds.Phone.LAST_TIME_CONTACTED,
+                        ContactsContract.CommonDataKinds.Phone.NUMBER},
+                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] {id},
+                null);
+
+        if(mCursor == null || mCursor.getCount() == 0) return null;
+        mCursor.moveToNext();
+
+        about[NAME] = mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
+        about[NUMBERS] = new String(Tuils.EMPTYSTRING);
+
+        int timesContacted = -1;
+        long lastContacted = Long.MAX_VALUE;
+        do {
+            int tempT = mCursor.getInt(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TIMES_CONTACTED));
+            long tempL = mCursor.getLong(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LAST_TIME_CONTACTED));
+
+            timesContacted = tempT > timesContacted ? tempT : timesContacted;
+            if(tempL > 0) lastContacted = tempL < lastContacted ? tempL : lastContacted;
+
+            String n = mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
+            about[NUMBERS] = (about[NUMBERS].length() > 0 ? about[NUMBERS] + Tuils.NEWLINE : Tuils.EMPTYSTRING) + n;
+        } while (mCursor.moveToNext());
+
+        about[TIME_CONTACTED] = String.valueOf(timesContacted);
+        if(lastContacted != Long.MAX_VALUE) {
+            long difference = System.currentTimeMillis() - lastContacted;
+            long sc = difference / 1000;
+            if(sc < 60) {
+                about[LAST_CONTACTED] = "sec: " + String.valueOf(lastContacted);
+            } else {
+                int ms = (int) (sc / 60);
+                sc = ms % 60;
+                if(ms < 60) {
+                    about[LAST_CONTACTED] = "min: " + ms + ", sec: " + sc;
+                } else {
+                    int h = ms / 60;
+                    ms = h % 60;
+                    if(h < 24) {
+                        about[LAST_CONTACTED] = "h: " + h + ", min: " + ms + ", sec: " + sc;
+                    } else {
+                        int days = h / 24;
+                        h = days % 24;
+                        about[LAST_CONTACTED] = "d: " + days + ", h: " + h + ", min: " + ms + ", sec: " + sc;
+                    }
+                }
+            }
+        }
+
+        return about;
     }
 
     public String findNumber(String name, int minRate) {
@@ -76,4 +295,70 @@ public class ContactManager {
         String mostSuitable = Compare.similarString(names, name, minRate, USE_SCROLL_COMPARE);
         return mostSuitable == null ? null : contacts.get(mostSuitable);
     }
+
+//    public void delete(String phone) {
+//        Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+//                new String[] {ContactsContract.Data.CONTACT_ID},
+//                ContactsContract.CommonDataKinds.Phone.NUMBER + " = ?", new String[]{phone},
+//                null);
+//
+//        if(cursor != null && cursor.getCount() > 0) {
+//            cursor.moveToNext();
+//            String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID));
+//            cursor.close();
+//            context.getContentResolver().delete(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+//                    ContactsContract.Data.CONTACT_ID + " = ?", new String[] {id});
+//        }
+//
+//    }
+
+    public boolean delete(String phone) {
+        return context.getContentResolver().delete(fromPhone(phone), null, null) > 0;
+    }
+
+    public Uri fromPhone(String phone) {
+        Cursor mCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
+                new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME},
+                ContactsContract.CommonDataKinds.Phone.NUMBER + " = ?", new String[] {phone},
+                null);
+
+        if(mCursor == null || mCursor.getCount() == 0) return null;
+        mCursor.moveToNext();
+
+        String name = mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
+        mCursor.close();
+
+        mCursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
+                new String[] {ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME},
+                ContactsContract.Contacts.DISPLAY_NAME + " = ?", new String[] {name},
+                null);
+
+        if(mCursor == null || mCursor.getCount() == 0) return null;
+        mCursor.moveToNext();
+
+        String mCurrentLookupKey = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
+        long mCurrentId = mCursor.getLong(mCursor.getColumnIndex(ContactsContract.Contacts._ID));
+
+        mCursor.close();
+
+        return ContactsContract.Contacts.getLookupUri(mCurrentId, mCurrentLookupKey);
+    }
+
+    public static class Contact {
+        public String name;
+        public List<String> numbers = new ArrayList<>();
+
+        public int selectedNumber;
+
+        public Contact(String name, List<String> numbers, int defNumber) {
+            this.name = name;
+            this.numbers = numbers;
+            this.selectedNumber = defNumber;
+        }
+
+        @Override
+        public String toString() {
+            return name + " : " + numbers.toString();
+        }
+    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java
index 4d2e0d6..a85bdb4 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/FileManager.java
@@ -4,6 +4,8 @@ import android.content.Context;
 import android.content.Intent;
 
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -24,25 +26,38 @@ public class FileManager {
     public static final int NOT_WRITEABLE = 14;
     public static final int NOT_READABLE = 15;
 
+    public static final int MIN_FILE_RATE = 4;
+
     public static final boolean USE_SCROLL_COMPARE = true;
 
     private static final String ASTERISK = "*";
     private static final String DOT = Tuils.DOT;
 
     public static String writeOn(File file, String text) {
+//        try {
+//            ShellUtils.CommandResult result = ShellUtils.execCommand("echo " + "\"" + text + "\"" + " > " + file.getAbsolutePath(), false, null);
+//            if(result.result == 0) {
+//                return null;
+//            } else {
+//                result = ShellUtils.execCommand("echo " + "\"" + text + "\"" + " > " + file.getAbsolutePath(), true, null);
+//                if(result.result == 0) {
+//                    return null;
+//                }
+//                return result.toString();
+//            }
+//        } catch (Exception e) {
+//            return e.toString();
+//        }
+
         try {
-            ShellUtils.CommandResult result = ShellUtils.execCommand("echo " + "\"" + text + "\"" + " > " + file.getAbsolutePath(), false, null);
-            if(result.result == 0) {
-                return null;
-            } else {
-//                  try again with su
-                result = ShellUtils.execCommand("echo " + "\"" + text + "\"" + " > " + file.getAbsolutePath(), true, null);
-                if(result.result == 0) {
-                    return null;
-                }
-                return result.toString();
-            }
-        } catch (Exception e) {
+            FileOutputStream stream = new FileOutputStream(file);
+            stream.write(text.getBytes());
+            stream.flush();
+            stream.close();
+            return null;
+        } catch (FileNotFoundException e) {
+            return e.toString();
+        } catch (IOException e) {
             return e.toString();
         }
     }
@@ -147,19 +162,19 @@ public class FileManager {
     }
 
     public static List<File> lsFile(File f, boolean showHidden) {
-        ShellUtils.CommandResult r = ShellUtils.execCommand("test -w \"" + f.getAbsolutePath()+ "\"", false, null);
-        if(r.result != 0) {
-            return null;
-        }
+//        ShellUtils.CommandResult r = ShellUtils.execCommand("test -w \"" + f.getAbsolutePath()+ "\"", false, null);
+//        if(r.result != 0) {
+//            return null;
+//        }
 
         if(!f.isDirectory()) {
             return null;
         }
 
-        ShellUtils.CommandResult rr = ShellUtils.execCommand("test -r \"" + f.getAbsolutePath()+ "\"", false, null);
-        if(rr.result != 0) {
-            return null;
-        }
+//        ShellUtils.CommandResult rr = ShellUtils.execCommand("test -r \"" + f.getAbsolutePath()+ "\"", false, null);
+//        if(rr.result != 0) {
+//            return null;
+//        }
 
         File[] content = f.listFiles();
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java
index 5d83448..1739717 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java
@@ -11,7 +11,6 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Random;
 
 import ohi.andre.comparestring.Compare;
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -44,27 +43,33 @@ public class MusicManager implements OnCompletionListener {
     });
 
     //	constructor
-    public MusicManager(Context c, PreferencesManager preferencesManager, Outputable outputable) {
-        this.mp = new MediaPlayer();
-        this.mp.setOnCompletionListener(this);
-
-        this.outputable = outputable;
-
-        c.registerReceiver(headsetReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
-
-        boolean randomActive = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.PLAY_RANDOM));
-        fromMediastore = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.FROM_MEDIASTORE));
-        if(fromMediastore) {
-            songsFolder = null;
-        } else {
-            songsFolder = new File(preferencesManager.getValue(PreferencesManager.SONGSFOLDER));
-        }
+    public MusicManager(Context c, Outputable outputable) {
+        try {
+            this.mp = new MediaPlayer();
+            this.mp.setOnCompletionListener(this);
+
+            this.outputable = outputable;
+
+            c.registerReceiver(headsetReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
+
+            boolean randomActive = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.random_play);
+            fromMediastore = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.songs_from_mediastore);
+            if (fromMediastore) {
+                songsFolder = null;
+            } else {
+                String path = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.songs_folder);
+                if (path == null || path.length() == 0 || path.equals("null")) {
+                    return;
+                }
+                songsFolder = new File(path);
+            }
 
-        refresh(c);
+            refresh(c);
 
-        if(randomActive && files != null) {
-            Collections.shuffle(files);
-        }
+            if (randomActive && files != null) {
+                Collections.shuffle(files);
+            }
+        } catch (Exception e) {}
     }
 
     public boolean initPlayer() {
@@ -89,7 +94,7 @@ public class MusicManager implements OnCompletionListener {
         return file.getAbsolutePath();
     }
 
-    //	return names
+    //	return listNames
     public List<String> getNames() {
         if(files == null) {
             return new ArrayList<>(0);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java
deleted file mode 100755
index 35e4608..0000000
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java
+++ /dev/null
@@ -1,322 +0,0 @@
-package ohi.andre.consolelauncher.managers;
-
-import android.annotation.SuppressLint;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-
-import ohi.andre.consolelauncher.tuils.ShellUtils;
-import ohi.andre.consolelauncher.tuils.Tuils;
-
-public class PreferencesManager {
-
-    public static final String SETTINGS_FILENAME = "settings.txt";
-    public static final int SETTINGS = 10;
-
-    public static final String DEVICE = "deviceColor";
-    public static final String INPUT = "inputColor";
-    public static final String OUTPUT = "outputColor";
-    public static final String BG = "backgroundColor";
-    public static final String USE_SYSTEMFONT = "useSystemFont";
-    public static final String FONTSIZE = "fontSize";
-    public static final String RAM = "ramColor";
-    public static final String INPUTFIELD_BOTTOM = "inputFieldBottom";
-    public static final String USERNAME = "username";
-    public static final String SHOWUSERNAME = "showUsername";
-    public static final String SHOWSUBMIT = "showSubmit";
-    public static final String DEVICENAME = "deviceName";
-    public static final String SHOWRAM = "showRam";
-    public static final String SHOWDEVICE = "showDevice";
-    public static final String SHOWTOOLBAR = "showToolbar";
-    public static final String SHOWUSERNAMEWHENINPUTEMPTY = "showSessionInfoWhenInputEmpty";
-    public static final String LINUXAPPERARENCE = "linuxAppearance";
-    public static final String SHOWPATH_SESSIONINFO = "showPathInSessionInfo";
-    public static final String SHOWDEVICENAMEINSESSIONINFO = "showDeviceNameInSessionInfo";
-
-    public static final String SUGGESTIONTEXT_COLOR = "suggestionTextColor";
-    public static final String TRANSPARENT_SUGGESTIONS = "transparentSuggestions";
-    public static final String USE_MULTICOLOR_SUGGESTIONS = "multicolorSuggestions";
-    public static final String DEFAULT_SUGGESTION_BG = "defaultSuggestionBg";
-    public static final String ALIAS_SIGGESTION_BG = "aliasSuggestionBg";
-    public static final String APP_SUGGESTION_BG = "appSuggestionBg";
-    public static final String COMMAND_SUGGESTION_BG = "commandSuggestionsBg";
-    public static final String SONG_SUGGESTION_BG = "songSuggestionBg";
-    public static final String CONTACT_SUGGESTION_BG = "contactSuggestionBg";
-    public static final String FILE_SUGGESTION_BG = "fileSuggestionBg";
-
-    public static final String MINAPPSRATE = "minAppsRate";
-    public static final String MINFILESRATE = "minFilesRate";
-    public static final String MINSONGSRATE = "minSongsRate";
-    public static final String MINCONTACTSRATE = "minContactsRate";
-    public static final String MINCOMMANDSRATE = "minCommandsRate";
-
-    public static final String DOUBLETAP = "closeOnDbTap";
-    public static final String DOUBLETAP_SU = "doubleTapSU";
-    public static final String SHOWSUGGESTIONS = "showSuggestions";
-    public static final String EXECUTE_ON_SUGGESTION_CLICK = "executeOnSuggestionClick";
-
-    public static final String PLAY_RANDOM = "playRandom";
-    public static final String SONGSFOLDER = "songsFolder";
-    public static final String FROM_MEDIASTORE = "fromMediastore";
-
-    public static final String USE_SYSTEMWP = "useSystemWallpaper";
-    public static final String FULLSCREEN = "fullscreen";
-    public static final String NOTIFICATION = "keepAliveWithNotification";
-    public static final String OPEN_KEYBOARD = "openKeyboardOnStart";
-    public static final String COMPARESTRING_APPS = "compareStringForApps";
-    public static final String SHOW_DONATE_MESSAGE = "showDonationMessage";
-    public static final String SHOW_ALIAS_VALUE = "showAliasValue";
-
-    public static final String DEFAULT_SEARCH = "defaultSearch";
-
-    public static final String ALIAS_FILENAME = "alias.txt";
-    public static final int ALIAS = 11;
-
-    private static final String SETTINGS_VERSION = "settingsVersion";
-    private List<String> settings;
-    private List<String> aliases;
-    private File folder;
-    private InputStream rawSettingsFile;
-    private InputStream rawAliasFile;
-
-    public PreferencesManager(InputStream rawSettings, InputStream rawAlias, File folder) throws IOException {
-        this.folder = folder;
-        this.rawAliasFile = rawAlias;
-        this.rawSettingsFile = rawSettings;
-
-        refresh(SETTINGS);
-        refresh(ALIAS);
-    }
-
-    @SuppressLint("DefaultLocale")
-    private List<String> read(int n) throws IOException {
-
-        List<String> list = new ArrayList<>();
-
-        File f = open(n);
-        if(f == null) {
-            return new ArrayList<>();
-        }
-        FileInputStream fis = new FileInputStream(f);
-        BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
-
-        String line = reader.readLine();
-        while (line != null) {
-            if (!line.startsWith("//") && !line.startsWith(Tuils.NEWLINE) && line.length() > 0) {
-                list.add(line);
-            }
-
-            line = reader.readLine();
-        }
-
-        fis.close();
-        reader.close();
-
-        return list;
-    }
-
-    private File open(final int n) throws IOException {
-        String name;
-        switch (n) {
-            case PreferencesManager.SETTINGS:
-                name = SETTINGS_FILENAME;
-                break;
-            case PreferencesManager.ALIAS:
-                name = ALIAS_FILENAME;
-                break;
-            default:
-                return null;
-        }
-
-        File file = new File(folder, name);
-        if (createOrUpdateFile(file, n)) {
-            return file;
-        }
-        return null;
-    }
-
-    private boolean createOrUpdateFile(File file, int type) throws IOException {
-        List<String> newValues;
-//        transfer alias from an old version of assoc.txt
-        if (type == ALIAS) {
-//            return true if alias.txt exists
-            if (file.exists())
-                return true;
-
-//            if doesn't exist, use the template, and check if there are alias in alias.txt
-            newValues = readAllInput(rawAliasFile);
-//        verify if the file already exists, and get old values
-        } else if (type == SETTINGS) {
-            List<String> oldValues = null;
-            if (file.exists()) {
-                InputStream old = new FileInputStream(file);
-                oldValues = readAllInput(old);
-            }
-
-            newValues = readAllInput(rawSettingsFile);
-
-            if (oldValues != null) { //=> settings.txt exists
-                String oldVersionString = getValue(oldValues, SETTINGS_VERSION);
-                String versionString = getValue(newValues, SETTINGS_VERSION);
-
-                float oldVersion = oldVersionString == null ? 0.0f : Float.parseFloat(oldVersionString);
-                float currentVersion = Float.parseFloat(versionString);
-
-                if (oldVersion < currentVersion) {
-                    file.delete();
-                    file.createNewFile();
-
-                    transferValues(newValues, oldValues);
-                } else
-                    return true;
-            } else { // settings.txt doesn't exist
-                file.createNewFile();
-            }
-            ShellUtils.execCommand("chmod 666 " + file.getAbsolutePath(), false, null);
-        } else
-            return false;
-
-//        FROM HERE: write values to the file
-        FileOutputStream stream;
-        try {
-            stream = new FileOutputStream(file);
-        } catch (Exception e) {
-            return false;
-        }
-
-        try {
-            stream.write(Tuils.toPlanString(newValues, Tuils.NEWLINE).getBytes());
-            stream.flush();
-            stream.close();
-
-            ShellUtils.execCommand("chmod 666 " + file.getAbsolutePath(), false, null);
-
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    private void transferValues(List<String> newValues, List<String> oldValues) {
-        String key;
-        for (String s : oldValues) {
-            key = obtainKey(s);
-            if (key == null || key.equals(SETTINGS_VERSION))
-                continue;
-
-            int indexOfKey = Tuils.findPrefix(newValues, key);
-            if (indexOfKey == -1)
-                continue;
-
-            newValues.set(indexOfKey, setValue(newValues.get(indexOfKey), getValue(oldValues, key)));
-        }
-    }
-
-    public String getLine(int n, int index) {
-        if (n == PreferencesManager.ALIAS && index < aliases.size())
-            return aliases.get(index);
-        if (n == PreferencesManager.SETTINGS && index < settings.size())
-            return settings.get(index);
-        return null;
-    }
-
-    private String setValue(String line, String value) {
-        int equalsIndex = line.indexOf("=");
-        if (equalsIndex == -1)
-            return null;
-
-        return line.substring(0, equalsIndex + 1).concat(value);
-    }
-
-    //    default method for settings
-    public String getValue(String key) {
-        return getValue(PreferencesManager.SETTINGS, key);
-    }
-
-    public String getValue(int n, String key) {
-        return getValue(n == PreferencesManager.SETTINGS ? settings : aliases, key);
-    }
-
-    @SuppressLint("DefaultLocale")
-    private String getValue(List<String> values, String key) {
-        if(values == null) {
-            return null;
-        }
-
-        for (String s : values) {
-            String k = obtainKey(s);
-            if (k != null && k.equals(key))
-                return obtainValue(s);
-        }
-
-        return null;
-    }
-
-    private List<String> readAllInput(InputStream i) {
-        BufferedReader br = null;
-
-        List<String> list = new ArrayList<>();
-        String line;
-        try {
-            br = new BufferedReader(new InputStreamReader(i));
-            while ((line = br.readLine()) != null) {
-                list.add(line);
-            }
-
-        }
-        catch (IOException e) {}
-        finally {
-            if (br != null)
-                try {
-                    br.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-        }
-
-        return list;
-    }
-
-    private String obtainKey(String line, int equalsIndex) {
-        if (equalsIndex == -1)
-            return null;
-        return line.substring(0, equalsIndex);
-    }
-
-    public String obtainKey(String line) {
-        return obtainKey(line, line.indexOf("="));
-    }
-
-    @SuppressLint("DefaultLocale")
-    private String obtainValue(String line, int equalsIndex) {
-        if (equalsIndex == -1)
-            return null;
-        return line.substring(equalsIndex + 1);
-    }
-
-    public String obtainValue(String line) {
-        return obtainValue(line, line.indexOf("="));
-    }
-
-    public int getLength(int n) {
-        return n == PreferencesManager.SETTINGS ? settings.size() : aliases.size();
-    }
-
-    public void refresh(int n) {
-        try {
-            if (n == ALIAS)
-                aliases = read(ALIAS);
-            else if (n == SETTINGS)
-                settings = read(SETTINGS);
-        } catch (IOException e) {
-        }
-    }
-
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
index 4b2bb37..95cfc8f 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
@@ -15,23 +15,7 @@ public class SkinManager implements Parcelable {
     public static final int SUGGESTION_PADDING_VERTICAL = 15;
     public static final int SUGGESTION_PADDING_HORIZONTAL = 15;
     public static final int SUGGESTION_MARGIN = 20;
-    //	default
-    public static final int deviceDefault = 0xffff9800;
-    public static final int inputDefault = 0xff00ff00;
-    public static final int outputDefault = 0xffffffff;
-    public static final int ramDefault = 0xfff44336;
-    public static final int bgDefault = 0xff000000;
-
-    public static final int suggestionTextColorDefault = 0xff000000;
-    public static final int aliasSuggestionBgDefault = 0xffFF5722;
-    public static final int appSuggestionBgDefault = 0xff00897B;
-    public static final int commandSuggestionsBgDefault = 0xff76FF03;
-    public static final int songSuggestionBgDefault = 0xffEEFF41;
-    public static final int contactSuggestionBgDefault = 0xff64FFDA;
-    public static final int fileSuggestionBgDeafult = 0xff03A9F4;
-    public static final int defaultSuggestionBgDefault = 0xffFFFFFF;
-
-    private static final int defaultSize = 15;
+
     private static final int deviceScale = 3;
     private static final int textScale = 2;
     private static final int ramScale = 3;
@@ -40,196 +24,130 @@ public class SkinManager implements Parcelable {
     public int globalFontSize;
 
     public String deviceName;
-    public int deviceColor, inputColor, outputColor, ramColor, bgColor;
+    public int deviceColor, inputColor, outputColor, ramColor, bgColor, overlayColor;
 
     public boolean useSystemWp, showSuggestions, systemFont, inputBottom, showSubmit;
 
     public String username = null;
     public boolean showUsernameAndDeviceWhenEmpty = true, showUsername = false, showDeviceInSessionInfo = false, linuxAppearence = true, showPath = true;
 
-    public int suggestionTextColor, defaulSuggestionColor, appSuggestionColor, aliasSuggestionColor, musicSuggestionColor, contactsSuggestionColor, commandSuggestionColor, fileSuggestionColor;
-    public boolean multicolorSuggestions, transparentSuggestions;
-
-    public SkinManager(PreferencesManager prefs) {
-        systemFont = Boolean.parseBoolean(prefs.getValue(PreferencesManager.USE_SYSTEMFONT));
-        inputBottom = Boolean.parseBoolean(prefs.getValue(PreferencesManager.INPUTFIELD_BOTTOM));
-        showSubmit = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWSUBMIT));
-
-        try {
-            globalFontSize = Integer.parseInt(prefs.getValue(PreferencesManager.FONTSIZE));
-        } catch (Exception e) {
-            globalFontSize = SkinManager.defaultSize;
-        }
+    private int suggDefaultText, suggDefaultBg, suggAliasText, suggAliasBg, suggSongText, suggSongBg, suggContactText, suggContactBg, suggAppText, suggAppBg, suggCmdText, suggCmdBg, suggFileText, suggFileBg;
+    private boolean transparentSuggestions;
 
-        try {
-            useSystemWp = Boolean.parseBoolean(prefs.getValue(PreferencesManager.USE_SYSTEMWP));
-            if (useSystemWp)
-                bgColor = SYSTEM_WALLPAPER;
-            else
-                bgColor = Color.parseColor(prefs.getValue(PreferencesManager.BG));
-        } catch (Exception e) {
-            bgColor = bgDefault;
-        }
+    public SkinManager() {
+        systemFont = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.system_font);
+        inputBottom = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.input_bottom);
+        showSubmit = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_enter_button);
 
-        try {
-            deviceColor = Color.parseColor(prefs.getValue(PreferencesManager.DEVICE));
-        } catch (Exception e) {
-            deviceColor = deviceDefault;
-        }
+        globalFontSize = XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.font_size);
 
-        try {
-            inputColor = Color.parseColor(prefs.getValue(PreferencesManager.INPUT));
-        } catch (Exception e) {
-            inputColor = inputDefault;
+        useSystemWp = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.system_wallpaper);
+        if (useSystemWp) {
+            bgColor = SYSTEM_WALLPAPER;
+            overlayColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.overlay_color);
         }
+        else bgColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.bg_color);
 
-        try {
-            outputColor = Color.parseColor(prefs.getValue(PreferencesManager.OUTPUT));
-        } catch (Exception e) {
-            outputColor = outputDefault;
-        }
+        deviceColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.device_color);
+        ramColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.ram_color);
+        inputColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.input_color);
+        outputColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.output_color);
 
-        try {
-            ramColor = Color.parseColor(prefs.getValue(PreferencesManager.RAM));
-        } catch (Exception e) {
-            ramColor = ramDefault;
-        }
-
-        try {
-            deviceName = prefs.getValue(PreferencesManager.DEVICENAME);
-            if (deviceName == null || deviceName.length() == 0 || deviceName.equals("null")) {
-                deviceName = Build.DEVICE;
-            }
-        } catch (Exception e) {
+        deviceName = XMLPrefsManager.get(String.class, XMLPrefsManager.Ui.deviceName);
+        if (deviceName.length() == 0 || deviceName.equals("null")) {
             deviceName = Build.DEVICE;
         }
 
-        try {
-            showUsernameAndDeviceWhenEmpty = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWUSERNAMEWHENINPUTEMPTY));
-            if(showUsernameAndDeviceWhenEmpty) {
-                showUsername = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWUSERNAME));
-                if(showUsername) {
-                    username = prefs.getValue(PreferencesManager.USERNAME);
-                }
-
-                showDeviceInSessionInfo = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWDEVICENAMEINSESSIONINFO));
-
-                showPath = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWPATH_SESSIONINFO));
+        showUsernameAndDeviceWhenEmpty = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_ssninfo);
+        if(showUsernameAndDeviceWhenEmpty) {
+            showUsername = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_username_ssninfo);
+            if(showUsername) {
+                username = XMLPrefsManager.get(String.class, XMLPrefsManager.Ui.username);
             }
-        } catch (Exception e) {
-            showUsernameAndDeviceWhenEmpty = false;
-        }
 
-        try {
-            linuxAppearence = Boolean.parseBoolean(prefs.getValue(PreferencesManager.LINUXAPPERARENCE));
-        } catch (Exception e) {
-            linuxAppearence = true;
+            showDeviceInSessionInfo = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_devicename_ssninfo);
+            showPath = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_path_ssninfo);
         }
 
-        showSuggestions = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWSUGGESTIONS));
+        linuxAppearence = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.linux_like);
+
+        showSuggestions = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Suggestions.enabled);
         if (showSuggestions) {
 
-            try {
-                suggestionTextColor = Color.parseColor(prefs.getValue(PreferencesManager.SUGGESTIONTEXT_COLOR));
-            } catch (Exception e) {
-                suggestionTextColor = suggestionTextColorDefault;
-            }
+            suggDefaultText = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.default_text_color);
+            suggDefaultBg = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.default_bg_color);
+            transparentSuggestions = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Suggestions.transparent);
 
-            try {
-                transparentSuggestions = Boolean.parseBoolean(prefs.getValue(PreferencesManager.TRANSPARENT_SUGGESTIONS));
-            } catch (Exception e) {
-                transparentSuggestions = false;
-            }
+            if(transparentSuggestions && suggDefaultText == bgColor) {
+                suggDefaultText = Color.GREEN;
+            } else {
+                suggAppText = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.apps_text_color);
+                suggAppBg = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.apps_bg_color);
 
-            try {
-                multicolorSuggestions = Boolean.parseBoolean(prefs.getValue(PreferencesManager.USE_MULTICOLOR_SUGGESTIONS));
-            } catch (Exception e) {
-                multicolorSuggestions = false;
-            }
+                suggAliasText = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.alias_text_color);
+                suggAliasBg = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.alias_bg_color);
 
-            if(multicolorSuggestions) {
-                transparentSuggestions = false;
-            }
+                suggCmdText = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.cmd_text_color);
+                suggCmdBg = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.cmd_bg_color);
 
-            if(transparentSuggestions && suggestionTextColor == bgColor) {
-                suggestionTextColor = Color.GREEN;
-            } else {
-                try {
-                    defaulSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.DEFAULT_SUGGESTION_BG));
-                } catch (Exception e) {
-                    defaulSuggestionColor = defaultSuggestionBgDefault;
-                }
-
-                if(multicolorSuggestions) {
-                    try {
-                        appSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.APP_SUGGESTION_BG));
-                    } catch (Exception e) {
-                        appSuggestionColor = appSuggestionBgDefault;
-                    }
-
-                    try {
-                        contactsSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.CONTACT_SUGGESTION_BG));
-                    } catch (Exception e) {
-                        contactsSuggestionColor = contactSuggestionBgDefault;
-                    }
-
-                    try {
-                        commandSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.COMMAND_SUGGESTION_BG));
-                    } catch (Exception e) {
-                        commandSuggestionColor = commandSuggestionsBgDefault;
-                    }
-
-                    try {
-                        musicSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.SONG_SUGGESTION_BG));
-                    } catch (Exception e) {
-                        musicSuggestionColor = songSuggestionBgDefault;
-                    }
-
-                    try {
-                        fileSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.FILE_SUGGESTION_BG));
-                    } catch (Exception e) {
-                        fileSuggestionColor = fileSuggestionBgDeafult;
-                    }
-
-                    try {
-                        aliasSuggestionColor = Color.parseColor(prefs.getValue(PreferencesManager.ALIAS_SIGGESTION_BG));
-                    } catch (Exception e) {
-                        aliasSuggestionColor = aliasSuggestionBgDefault;
-                    }
-                }
+                suggContactText = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.contact_text_color);
+                suggContactBg = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.contact_bg_color);
+
+                suggFileText = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.file_text_color);
+                suggFileBg = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.file_bg_color);
+
+                suggSongText = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.song_text_color);
+                suggSongBg = XMLPrefsManager.getColor(XMLPrefsManager.Suggestions.song_bg_color);
             }
         }
     }
 
     public ColorDrawable getSuggestionBg(Integer type) {
-        if(transparentSuggestions) {
-            type = 0;
-        }
-
         if(transparentSuggestions) {
             return new ColorDrawable(Color.TRANSPARENT);
-        } else if(!multicolorSuggestions) {
-            return new ColorDrawable(defaulSuggestionColor);
         } else {
             switch (type) {
                 case SuggestionsManager.Suggestion.TYPE_APP:
-                    return new ColorDrawable(appSuggestionColor);
+                    return new ColorDrawable(suggAppBg);
                 case SuggestionsManager.Suggestion.TYPE_ALIAS:
-                    return new ColorDrawable(aliasSuggestionColor);
+                    return new ColorDrawable(suggAliasBg);
                 case SuggestionsManager.Suggestion.TYPE_COMMAND:
-                    return new ColorDrawable(commandSuggestionColor);
+                    return new ColorDrawable(suggCmdBg);
                 case SuggestionsManager.Suggestion.TYPE_CONTACT:
-                    return new ColorDrawable(contactsSuggestionColor);
+                    return new ColorDrawable(suggContactBg);
                 case SuggestionsManager.Suggestion.TYPE_FILE:
-                    return new ColorDrawable(fileSuggestionColor);
+                    return new ColorDrawable(suggFileBg);
                 case SuggestionsManager.Suggestion.TYPE_SONG:
-                    return new ColorDrawable(musicSuggestionColor);
+                    return new ColorDrawable(suggSongBg);
                 default:
-                    return new ColorDrawable(defaulSuggestionColor);
+                    return new ColorDrawable(suggDefaultBg);
             }
         }
     }
 
+    public int getSuggestionTextColor(Integer type) {
+        int choosen;
+        switch (type) {
+            case SuggestionsManager.Suggestion.TYPE_APP:
+                choosen = suggAppText;
+            case SuggestionsManager.Suggestion.TYPE_ALIAS:
+                choosen = suggAliasText;
+            case SuggestionsManager.Suggestion.TYPE_COMMAND:
+                choosen = suggCmdText;
+            case SuggestionsManager.Suggestion.TYPE_CONTACT:
+                choosen = suggContactText;
+            case SuggestionsManager.Suggestion.TYPE_FILE:
+                choosen = suggFileText;
+            case SuggestionsManager.Suggestion.TYPE_SONG:
+                choosen = suggSongText;
+            default:
+                choosen = suggDefaultText;
+        }
+
+        if(choosen == -1) choosen = suggDefaultText;
+        return choosen;
+    }
+
     public int getDeviceSize() {
         return globalFontSize - deviceScale;
     }
@@ -254,6 +172,7 @@ public class SkinManager implements Parcelable {
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(this.globalFontSize);
+        dest.writeString(this.deviceName);
         dest.writeInt(this.deviceColor);
         dest.writeInt(this.inputColor);
         dest.writeInt(this.outputColor);
@@ -267,22 +186,29 @@ public class SkinManager implements Parcelable {
         dest.writeString(this.username);
         dest.writeByte(this.showUsernameAndDeviceWhenEmpty ? (byte) 1 : (byte) 0);
         dest.writeByte(this.showUsername ? (byte) 1 : (byte) 0);
+        dest.writeByte(this.showDeviceInSessionInfo ? (byte) 1 : (byte) 0);
         dest.writeByte(this.linuxAppearence ? (byte) 1 : (byte) 0);
         dest.writeByte(this.showPath ? (byte) 1 : (byte) 0);
-        dest.writeInt(this.suggestionTextColor);
-        dest.writeInt(this.defaulSuggestionColor);
-        dest.writeInt(this.appSuggestionColor);
-        dest.writeInt(this.aliasSuggestionColor);
-        dest.writeInt(this.musicSuggestionColor);
-        dest.writeInt(this.contactsSuggestionColor);
-        dest.writeInt(this.commandSuggestionColor);
-        dest.writeInt(this.fileSuggestionColor);
-        dest.writeByte(this.multicolorSuggestions ? (byte) 1 : (byte) 0);
+        dest.writeInt(this.suggDefaultText);
+        dest.writeInt(this.suggDefaultBg);
+        dest.writeInt(this.suggAliasText);
+        dest.writeInt(this.suggAliasBg);
+        dest.writeInt(this.suggSongText);
+        dest.writeInt(this.suggSongBg);
+        dest.writeInt(this.suggContactText);
+        dest.writeInt(this.suggContactBg);
+        dest.writeInt(this.suggAppText);
+        dest.writeInt(this.suggAppBg);
+        dest.writeInt(this.suggCmdText);
+        dest.writeInt(this.suggCmdBg);
+        dest.writeInt(this.suggFileText);
+        dest.writeInt(this.suggFileBg);
         dest.writeByte(this.transparentSuggestions ? (byte) 1 : (byte) 0);
     }
 
     protected SkinManager(Parcel in) {
         this.globalFontSize = in.readInt();
+        this.deviceName = in.readString();
         this.deviceColor = in.readInt();
         this.inputColor = in.readInt();
         this.outputColor = in.readInt();
@@ -296,17 +222,23 @@ public class SkinManager implements Parcelable {
         this.username = in.readString();
         this.showUsernameAndDeviceWhenEmpty = in.readByte() != 0;
         this.showUsername = in.readByte() != 0;
+        this.showDeviceInSessionInfo = in.readByte() != 0;
         this.linuxAppearence = in.readByte() != 0;
         this.showPath = in.readByte() != 0;
-        this.suggestionTextColor = in.readInt();
-        this.defaulSuggestionColor = in.readInt();
-        this.appSuggestionColor = in.readInt();
-        this.aliasSuggestionColor = in.readInt();
-        this.musicSuggestionColor = in.readInt();
-        this.contactsSuggestionColor = in.readInt();
-        this.commandSuggestionColor = in.readInt();
-        this.fileSuggestionColor = in.readInt();
-        this.multicolorSuggestions = in.readByte() != 0;
+        this.suggDefaultText = in.readInt();
+        this.suggDefaultBg = in.readInt();
+        this.suggAliasText = in.readInt();
+        this.suggAliasBg = in.readInt();
+        this.suggSongText = in.readInt();
+        this.suggSongBg = in.readInt();
+        this.suggContactText = in.readInt();
+        this.suggContactBg = in.readInt();
+        this.suggAppText = in.readInt();
+        this.suggAppBg = in.readInt();
+        this.suggCmdText = in.readInt();
+        this.suggCmdBg = in.readInt();
+        this.suggFileText = in.readInt();
+        this.suggFileBg = in.readInt();
         this.transparentSuggestions = in.readByte() != 0;
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
index b986aa0..0778589 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
@@ -8,7 +8,6 @@ import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.method.ScrollingMovementMethod;
 import android.text.style.ForegroundColorSpan;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.inputmethod.EditorInfo;
@@ -20,10 +19,10 @@ import android.widget.TextView;
 import java.util.ArrayList;
 import java.util.List;
 
+import ohi.andre.consolelauncher.UIManager;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.main.raw.clear;
 import ohi.andre.consolelauncher.tuils.Tuils;
-import ohi.andre.consolelauncher.tuils.interfaces.OnNewInputListener;
 
 /*Copyright Francesco Andreuzzi
 
@@ -70,7 +69,8 @@ public class TerminalManager {
 
     private SkinManager mSkinManager;
 
-    private OnNewInputListener mInputListener;
+    private UIManager.OnNewInputListener mInputListener;
+    private UIManager.SuggestionNavigator mSuggestionNavigator;
 
     private List<Messager> messagers = new ArrayList<>();
 
@@ -88,7 +88,6 @@ public class TerminalManager {
         this.mSkinManager = skinManager;
         this.mainPack = mainPack;
 
-
         if(skinManager.linuxAppearence) {
             prefix = "$ ";
         } else {
@@ -158,7 +157,11 @@ public class TerminalManager {
         this.mTerminalView.setFocusable(false);
         setupScroller();
 
-        this.mScrollView = (ScrollView) this.mTerminalView.getParent();
+        View v = mTerminalView;
+        do {
+            v = (View) v.getParent();
+        } while (!(v instanceof ScrollView));
+        this.mScrollView = (ScrollView) v;
 
         this.mInputView = inputView;
         this.mInputView.setTextSize(mSkinManager.getTextSize());
@@ -167,8 +170,11 @@ public class TerminalManager {
         this.mInputView.setHint(Tuils.getHint(skinManager, mainPack.currentDirectory.getAbsolutePath()));
         this.mInputView.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
         this.mInputView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+
             @Override
             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+                if(!mInputView.hasFocus()) mInputView.requestFocus();
+
 //                physical enter
                 if(actionId == KeyEvent.ACTION_DOWN) {
                     if(lastEnter == 0) {
@@ -185,6 +191,10 @@ public class TerminalManager {
                 if (actionId == EditorInfo.IME_ACTION_GO || actionId == EditorInfo.IME_ACTION_DONE || actionId == KeyEvent.ACTION_DOWN) {
                     onNewInput();
                 }
+
+//                if(event == null && actionId == EditorInfo.IME_NULL) onNewInput();
+//                if (event != null && event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) onNewInput();
+
                 return true;
             }
         });
@@ -256,6 +266,30 @@ public class TerminalManager {
         }
     }
 
+    public void setOutput(String output, int color) {
+        if (output == null) {
+            return;
+        }
+
+        output = output.trim();
+        if(output.equals(Tuils.EMPTYSTRING)) {
+            return;
+        }
+
+        if(output.equals(clear.CLEAR)) {
+            clear();
+            return;
+        }
+
+        writeToView(color, output);
+
+        for(Messager messager : messagers) {
+            if(cmds != 0 && cmds % messager.n == 0) {
+                writeToView(messager.message, OUTPUT);
+            }
+        }
+    }
+
     public void onBackPressed() {
         if(cmdList.size() > 0) {
 
@@ -300,6 +334,21 @@ public class TerminalManager {
         });
     }
 
+    private void writeToView(final int color, final String text) {
+        mTerminalView.post(new Runnable() {
+            @Override
+            public void run() {
+                String txt = text;
+                txt = Tuils.NEWLINE.concat(txt);
+
+                SpannableString string = getSpannable(color, txt);
+                mTerminalView.append(string);
+
+                scrollToEnd();
+            }
+        });
+    }
+
     public void simulateEnter() {
         onNewInput();
     }
@@ -309,7 +358,6 @@ public class TerminalManager {
     }
 
     private SpannableString getSpannable(String text, int type) {
-        SpannableString spannableString = new SpannableString(text);
         int color;
         if(type == INPUT) {
             color = mSkinManager.inputColor;
@@ -318,6 +366,11 @@ public class TerminalManager {
         } else {
             return null;
         }
+        return getSpannable(color, text);
+    }
+
+    private SpannableString getSpannable(int color, String text) {
+        SpannableString spannableString = new SpannableString(text);
         spannableString.setSpan(new ForegroundColorSpan(color), 0, spannableString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
         return spannableString;
     }
@@ -347,10 +400,14 @@ public class TerminalManager {
         }
     }
 
-    public void setInputListener(OnNewInputListener listener) {
+    public void setInputListener(UIManager.OnNewInputListener listener) {
         this.mInputListener = listener;
     }
 
+    public void setSuggestionNavigator(UIManager.SuggestionNavigator navigator) {
+        this.mSuggestionNavigator = navigator;
+    }
+
     public void focusInputEnd() {
         mInputView.setSelection(getInput().length());
     }
@@ -384,6 +441,7 @@ public class TerminalManager {
                 mInputView.setText(Tuils.EMPTYSTRING);
             }
         });
+        cmdList.clear();
     }
 
     public static class Messager {
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
new file mode 100755
index 0000000..ed5f731
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
@@ -0,0 +1,774 @@
+package ohi.andre.consolelauncher.managers;
+
+import android.graphics.Color;
+import android.util.Log;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+public class XMLPrefsManager {
+
+    public static final String XML_DEFAULT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+
+    public static final String VALUE_ATTRIBUTE = "value";
+
+    public interface XMLPrefsSave {
+        String defaultValue();
+        String label();
+        XmlPrefsElement parent();
+        boolean is(String s);
+    }
+
+    public enum Theme implements XMLPrefsSave {
+
+        input_color {
+            @Override
+            public String defaultValue() {
+                return "#ff00ff00";
+            }
+        },
+        output_color {
+            @Override
+            public String defaultValue() {
+                return "#ffffffff";
+            }
+        },
+        bg_color {
+            @Override
+            public String defaultValue() {
+                return "#ff000000";
+            }
+        },
+        device_color {
+            @Override
+            public String defaultValue() {
+                return "#ffff9800";
+            }
+        },
+        ram_color {
+            @Override
+            public String defaultValue() {
+                return "#fff44336";
+            }
+        },
+        overlay_color {
+            @Override
+            public String defaultValue() {
+                return "#80000000";
+            }
+        };
+
+        @Override
+        public XmlPrefsElement parent() {
+            return XMLPrefsRoot.THEME;
+        }
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    public enum Ui implements XMLPrefsSave {
+
+        show_username_ssninfo {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_ssninfo {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        linux_like {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_path_ssninfo {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_devicename_ssninfo {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_enter_button {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        system_font {
+            @Override
+            public String defaultValue() {
+                return "false";
+            }
+        },
+        font_size {
+            @Override
+            public String defaultValue() {
+                return "15";
+            }
+        },
+        input_bottom {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_ram {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_device_name {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        username {
+            @Override
+            public String defaultValue() {
+                return "user";
+            }
+        },
+        deviceName {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        system_wallpaper {
+            @Override
+            public String defaultValue() {
+                return "false";
+            }
+        },
+        fullscreen {
+            @Override
+            public String defaultValue() {
+                return "false";
+            }
+        };
+
+        @Override
+        public XmlPrefsElement parent() {
+            return XMLPrefsRoot.UI;
+        }
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    public enum Toolbar implements XMLPrefsSave {
+
+        enabled {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        };
+
+        @Override
+        public XmlPrefsElement parent() {
+            return XMLPrefsRoot.TOOLBAR;
+        }
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    public enum Suggestions implements XMLPrefsSave {
+
+        enabled {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        transparent {
+            @Override
+            public String defaultValue() {
+                return "false";
+            }
+        },
+        default_text_color {
+            @Override
+            public String defaultValue() {
+                return "#000000";
+            }
+        },
+        default_bg_color {
+            @Override
+            public String defaultValue() {
+                return "#ffffff";
+            }
+        },
+        apps_text_color {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        apps_bg_color {
+            @Override
+            public String defaultValue() {
+                return "#00897B";
+            }
+        },
+        alias_text_color {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        alias_bg_color {
+            @Override
+            public String defaultValue() {
+                return "#FF5722";
+            }
+        },
+        cmd_text_color {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        cmd_bg_color {
+            @Override
+            public String defaultValue() {
+                return "#76FF03";
+            }
+        },
+        song_text_color {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        song_bg_color {
+            @Override
+            public String defaultValue() {
+                return "#EEFF41";
+            }
+        },
+        contact_text_color {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        contact_bg_color {
+            @Override
+            public String defaultValue() {
+                return "#64FFDA";
+            }
+        },
+        file_text_color {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        file_bg_color {
+            @Override
+            public String defaultValue() {
+                return "#03A9F4";
+            }
+        };
+
+        @Override
+        public XmlPrefsElement parent() {
+            return XMLPrefsRoot.SUGGESTIONS;
+        }
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    public enum Behavior implements XMLPrefsSave {
+
+        double_tap_closes {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        double_tap_cmd {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        random_play {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        songs_folder {
+            @Override
+            public String defaultValue() {
+                return "";
+            }
+        },
+        songs_from_mediastore {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        tui_notification {
+            @Override
+            public String defaultValue() {
+                return "false";
+            }
+        },
+        auto_show_keyboard {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        donation_message {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_alias_content {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_launch_history {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        };
+
+        @Override
+        public XmlPrefsElement parent() {
+            return XMLPrefsRoot.BEHAVIOR;
+        }
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    public enum Cmd implements XMLPrefsSave {
+
+        default_search {
+            @Override
+            public String defaultValue() {
+                return "-gg";
+            }
+        };
+
+        @Override
+        public XmlPrefsElement parent() {
+            return XMLPrefsRoot.CMD;
+        }
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    public enum XMLPrefsRoot implements XmlPrefsElement {
+
+        THEME("theme.xml", Theme.values()),
+        CMD("cmd.xml", Cmd.values()),
+        TOOLBAR("toolbar.xml", Toolbar.values()),
+        UI("ui.xml", Ui.values()),
+        BEHAVIOR("behavior.xml", Behavior.values()),
+        SUGGESTIONS("suggestions.xml", Suggestions.values());
+
+//        notifications
+//        apps
+//        alias
+
+        public String path;
+        XMLPrefsList values;
+        List<XMLPrefsSave> enums;
+        public List<XMLPrefsSave> copy;
+
+        XMLPrefsRoot(String path, XMLPrefsSave[] en) {
+            Log.e("andre", Arrays.toString(en));
+
+            this.path = path;
+            this.values = new XMLPrefsList();
+
+            if(en == null) return;
+            this.enums = new ArrayList<>(Arrays.asList(en));
+            this.copy = new ArrayList<>(enums);
+        }
+
+        @Override
+        public void write(XMLPrefsSave save, String value) {
+            set(new File(Tuils.getFolder(), path), name(), save.label(), new String[] {VALUE_ATTRIBUTE}, new String[] {value});
+        }
+
+        public XMLPrefsList getValues() {
+            return values;
+        }
+    }
+
+    public interface XmlPrefsElement {
+        XMLPrefsList getValues();
+        void write(XMLPrefsSave save, String value);
+    }
+
+    public static class XMLPrefsEntry {
+
+        public String key, value;
+
+        public XMLPrefsEntry(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if(obj instanceof XMLPrefsEntry) return this == obj;
+            else if(obj instanceof XMLPrefsSave) return this.key.equals(((XMLPrefsSave) obj).label());
+            return obj.equals(key);
+        }
+    }
+
+    public static class XMLPrefsList {
+
+        List<XMLPrefsEntry> list = new ArrayList<>();
+
+        public void add(XMLPrefsEntry entry) {
+            list.add(entry);
+        }
+
+        public void add(String key, String value) {
+            list.add(new XMLPrefsEntry(key, value));
+        }
+
+        public XMLPrefsEntry get(Object o) {
+            for(XMLPrefsEntry e : list) if(e.equals(o)) return e;
+            return null;
+        }
+
+        public int size() {
+            return list.size();
+        }
+
+        public List<String> values() {
+            List<String> vs = new ArrayList<>();
+            for(XMLPrefsEntry entry : list) vs.add(entry.value);
+            return vs;
+        }
+    }
+
+    private XMLPrefsManager() {}
+
+    public static void create() throws Exception {
+        File folder = Tuils.getFolder();
+
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder = factory.newDocumentBuilder();
+
+        for(XMLPrefsRoot element : XMLPrefsRoot.values()) {
+            File file = new File(folder, element.path);
+            if(!file.exists() && !file.createNewFile()) continue;
+
+            Document d;
+            try {
+                d = builder.parse(file);
+            } catch (Exception e) {
+                resetFile(file, element.name());
+
+                d = builder.parse(file);
+            }
+
+            List<XMLPrefsSave> enums = element.enums;
+            if(enums == null) continue;
+
+            Element root = (Element) d.getElementsByTagName(element.name()).item(0);
+            if(root == null) {
+                resetFile(file, element.name());
+                d = builder.parse(file);
+                root = (Element) d.getElementsByTagName(element.name()).item(0);
+            }
+            NodeList nodes = root.getElementsByTagName("*");
+
+//            List<Node> customNodes = null;
+//            if(element.flag == FLAG_HAS_CUSTOM_TAGS || element.flag == FLAG_CUSTOM_TAGS_ONLY) customNodes = new ArrayList<>();
+
+            for(int count = 0; count < nodes.getLength(); count++) {
+                Node node = nodes.item(count);
+
+                String nn = node.getNodeName();
+//                if(customNodes == null) {
+                element.values.add(nn, node.getAttributes().getNamedItem(VALUE_ATTRIBUTE).getNodeValue());
+//                } else {
+//                    if(element.flag != FLAG_CUSTOM_TAGS_ONLY && element.contains(nn)) element.values.add(nn, node.getAttributes().getNamedItem("value").getNodeValue());
+//                    else {
+//                        customNodes.add(node);
+//                        continue;
+//                    }
+//                }
+
+                for(int en = 0; en < enums.size(); en++) {
+                    if(enums.get(en).label().equals(nn)) {
+                        enums.remove(en);
+                        break;
+                    }
+                }
+            }
+
+            if(enums.size() == 0) continue;
+
+            for(XMLPrefsSave s : enums) {
+                Element em = d.createElement(s.label());
+                em.setAttribute(VALUE_ATTRIBUTE, s.defaultValue());
+                root.appendChild(em);
+
+                element.values.add(s.label(), s.defaultValue());
+            }
+
+            writeTo(d, file);
+        }
+    }
+
+    public static Object transform(String s, Class<?> c) {
+        if(s == null) return null;
+
+        try {
+            if(c == int.class) return Integer.parseInt(s);
+            if(c == Color.class) return Color.parseColor(s);
+            if(c == boolean.class) return Boolean.parseBoolean(s);
+            if(c == String.class) return s;
+        } catch (Exception e) {
+            return null;
+        }
+
+        return null;
+    }
+
+    static final Pattern p1 = Pattern.compile(">");
+//    static final Pattern p2 = Pattern.compile("</");
+    static final Pattern p3 = Pattern.compile("\n\n");
+    static final String p1s = ">\n";
+//    static final String p2s = "\n</";
+    static final String p3s = Tuils.NEWLINE;
+
+    public static String fixNewlines(String s) {
+        s = p1.matcher(s).replaceAll(p1s);
+//        s = p2.matcher(s).replaceAll(p2s);
+        s = p3.matcher(s).replaceAll(p3s);
+        return s;
+    }
+
+    public static void writeTo(Document d, File f) {
+        try {
+            TransformerFactory transformerFactory = TransformerFactory.newInstance();
+            Transformer transformer = transformerFactory.newTransformer();
+
+            DOMSource source = new DOMSource(d);
+            StringWriter writer = new StringWriter();
+            StreamResult result = new StreamResult(writer);
+            transformer.transform(source, result);
+
+            String s = fixNewlines(writer.toString());
+
+            FileOutputStream stream = new FileOutputStream(f);
+            stream.write(s.getBytes());
+
+            stream.flush();
+            stream.close();
+        } catch (Exception e) {}
+    }
+
+    public static void set(File file, String rootName, String elementName, String[] attributeNames, String[] attributeValues) {
+        String[][] values = new String[1][attributeValues.length];
+        values[0] = attributeValues;
+
+        setMany(file, rootName, new String[] {elementName}, attributeNames, values);
+    }
+
+    public static void setMany(File file, String rootName, String elementNames[], String[] attributeNames, String[][] attributeValues) {
+        try {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            Document d;
+            try {
+                d = builder.parse(file);
+            } catch (Exception e) {
+                return;
+            }
+
+            Element root = (Element) d.getElementsByTagName(rootName).item(0);
+            NodeList nodes = root.getElementsByTagName("*");
+
+            for(int count = 0; count < nodes.getLength(); count++) {
+                Node node = nodes.item(count);
+
+                int index = Tuils.find(node.getNodeName(), elementNames);
+                if(index != -1) {
+                    Element e = (Element) node;
+
+                    for(int c = 0; c < attributeNames.length; c++) e.setAttribute(attributeNames[c], attributeValues[index][c]);
+
+                    writeTo(d, file);
+                    return;
+                }
+            }
+
+//            it wasn't found
+            for(int count = 0; count < elementNames.length; count++) {
+                Element element = d.createElement(elementNames[count]);
+                for(int c = 0; c < attributeNames.length; c++) element.setAttribute(attributeNames[c], attributeValues[count][c]);
+                root.appendChild(element);
+            }
+
+            writeTo(d, file);
+        } catch (Exception e) {}
+    }
+
+    public static String[] getAttrValues(File file, String rootName, String elementName, String[] attrNames) {
+        try {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            Document d;
+            try {
+                d = builder.parse(file);
+            } catch (Exception e) {
+                return null;
+            }
+
+            Element root = (Element) d.getElementsByTagName(rootName).item(0);
+            NodeList nodes = root.getElementsByTagName("*");
+
+            for(int count = 0; count < nodes.getLength(); count++) {
+                Node node = nodes.item(count);
+
+                if(node.getNodeName().equals(elementName)) {
+                    Element e = (Element) node;
+
+                    String[] values = new String[attrNames.length];
+                    for(int c = 0; c < attrNames.length; c++) values[count] = e.getAttribute(attrNames[c]);
+
+                    return values;
+                }
+            }
+        } catch (Exception e) {}
+
+        return null;
+    }
+
+    public static <T> T get(Class<T> c, XMLPrefsManager.XMLPrefsSave prefsSave) {
+        if(prefsSave != null) {
+            try {
+                return (T) transform(prefsSave.parent().getValues().get(prefsSave).value, c);
+            } catch (Exception e) {
+                return (T) transform(prefsSave.defaultValue(), c);
+            }
+        }
+        return null;
+    }
+
+    public static int getColor(XMLPrefsManager.XMLPrefsSave prefsSave) {
+
+        try {
+            return (int) transform(prefsSave.parent().getValues().get(prefsSave).value, Color.class);
+        } catch (Exception e) {
+            String def = prefsSave.defaultValue();
+            if(def == null || def.length() == 0) {
+                return -1;
+            }
+            return (int) transform(def, Color.class);
+        }
+    }
+
+    public static boolean resetFile(File f, String name) {
+        try {
+            FileOutputStream stream = new FileOutputStream(f);
+            stream.write(XML_DEFAULT.getBytes());
+            stream.write(("<" + name + ">\n").getBytes());
+            stream.write(("</" + name + ">\n").getBytes());
+            stream.flush();
+            stream.close();
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationManager.java
new file mode 100644
index 0000000..3e14721
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationManager.java
@@ -0,0 +1,282 @@
+package ohi.andre.consolelauncher.managers.notifications;
+
+import android.annotation.TargetApi;
+import android.graphics.Color;
+import android.os.Build;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.VALUE_ATTRIBUTE;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.XML_DEFAULT;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.resetFile;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.set;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.setMany;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.transform;
+import static ohi.andre.consolelauncher.managers.XMLPrefsManager.writeTo;
+
+/**
+ * Created by francescoandreuzzi on 29/04/2017.
+ */
+
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
+public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
+
+    private static final String COLOR_ATTRIBUTE = "color";
+    private static final String ENABLED_ATTRIBUTE = "enabled";
+
+    public static final String PATH = "notifications.xml";
+    private static final String NAME = "NOTIFICATIONS";
+
+    public enum Options implements XMLPrefsManager.XMLPrefsSave {
+
+        enabled {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        default_color {
+            @Override
+            public String defaultValue() {
+                return "#FF0000";
+            }
+        };
+
+        @Override
+        public XMLPrefsManager.XMLPrefsRoot parent() {
+            return null;
+        }
+
+        @Override
+        public String label() {
+            return name();
+        }
+
+        @Override
+        public boolean is(String s) {
+            return name().equals(s);
+        }
+    }
+
+    @Override
+    public XMLPrefsManager.XMLPrefsList getValues() {
+        return null;
+    }
+
+    @Override
+    public void write(XMLPrefsManager.XMLPrefsSave save, String value) {
+        set(new File(Tuils.getFolder(), PATH), NAME, save.label(), new String[] {VALUE_ATTRIBUTE}, new String[] {value});
+    }
+
+    private static File folder;
+    private static XMLPrefsManager.XMLPrefsList values;
+    private static Map<String, Integer> colors;
+    private static boolean created = false;
+
+    private NotificationManager() {}
+
+    public static void create() {
+        if(created) return;
+        created = true;
+
+        folder = Tuils.getFolder();
+
+        colors = new HashMap<>();
+        values = new XMLPrefsManager.XMLPrefsList();
+
+        try {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            File file = new File(folder, PATH);
+            if(!file.exists() && !file.createNewFile()) return;
+
+            Document d;
+            try {
+                d = builder.parse(file);
+            } catch (Exception e) {
+                resetFile(file, NAME);
+
+                d = builder.parse(file);
+            }
+
+            List<Options> enums = new ArrayList<>(Arrays.asList(Options.values()));
+
+            Element root = (Element) d.getElementsByTagName(NAME).item(0);
+            if(root == null) {
+                resetFile(file, NAME);
+                d = builder.parse(file);
+                root = (Element) d.getElementsByTagName(NAME).item(0);
+            }
+            NodeList nodes = root.getElementsByTagName("*");
+
+            for(int count = 0; count < nodes.getLength(); count++) {
+                Node node = nodes.item(count);
+
+                String nn = node.getNodeName();
+                if(Tuils.find(nn, (List) enums) != -1) {
+                    values.add(nn, node.getAttributes().getNamedItem(VALUE_ATTRIBUTE).getNodeValue());
+
+                    for(int en = 0; en < enums.size(); en++) {
+                        if(enums.get(en).label().equals(nn)) {
+                            enums.remove(en);
+                            break;
+                        }
+                    }
+                } else {
+                    if(node.getNodeType() == Node.ELEMENT_NODE) {
+                        Element e = (Element) node;
+
+                        boolean enabled = !e.hasAttribute(ENABLED_ATTRIBUTE) || Boolean.parseBoolean(e.getAttribute(ENABLED_ATTRIBUTE));
+                        if(enabled) {
+                            int color = e.hasAttribute(COLOR_ATTRIBUTE) ? Color.parseColor(e.getAttribute(COLOR_ATTRIBUTE)) : getColor(Options.default_color);
+                            colors.put(nn, color);
+                        }
+                    }
+                }
+            }
+
+            if(enums.size() == 0) return;
+
+            for(XMLPrefsManager.XMLPrefsSave s : enums) {
+                Element em = d.createElement(s.label());
+                em.setAttribute(VALUE_ATTRIBUTE, s.defaultValue());
+                root.appendChild(em);
+
+                values.add(s.label(), s.defaultValue());
+            }
+
+            writeTo(d, file);
+        } catch (Exception e) {}
+    }
+
+    public static void notificationsChangeFor(NotificatedApp app) {
+        notificationsChangeFor(new ArrayList<>(Collections.singletonList(app)));
+    }
+
+    public static void notificationsChangeFor(List<NotificatedApp> apps) {
+        String[] names = new String[apps.size()];
+        final String[] attrNames = {ENABLED_ATTRIBUTE, COLOR_ATTRIBUTE};
+        String[][] values = new String[names.length][attrNames.length];
+
+        for(int count = 0; count < apps.size(); count++) {
+            NotificatedApp app = apps.get(count);
+            names[count] = app.pkg;
+            values[count][0] = app.enabled + Tuils.EMPTYSTRING;
+            values[count][1] = app.color + Tuils.EMPTYSTRING;
+        }
+
+        setMany(new File(folder, PATH), NAME, names, attrNames, values);
+    }
+
+    public static NotificatedApp getAppState(String pkg) {
+        try {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+
+            File file = new File(folder, PATH);
+
+            Document d;
+            try {
+                d = builder.parse(file);
+            } catch (Exception e) {
+                FileOutputStream stream = new FileOutputStream(file);
+                stream.write(XML_DEFAULT.getBytes());
+                stream.flush();
+                stream.close();
+
+                d = builder.parse(file);
+            }
+
+            Element root = (Element) d.getElementsByTagName(NAME).item(0);
+            NodeList nodes = root.getElementsByTagName("*");
+
+            for (int count = 0; count < nodes.getLength(); count++) {
+                Node node = nodes.item(count);
+
+                if(!pkg.equals(node.getNodeName())) continue;
+
+                Element e = (Element) node;
+                boolean enabled = !e.hasAttribute(ENABLED_ATTRIBUTE) || Boolean.parseBoolean(e.getAttribute(ENABLED_ATTRIBUTE));
+                int color = e.hasAttribute(COLOR_ATTRIBUTE) ? Color.parseColor(e.getAttribute(COLOR_ATTRIBUTE)) : getColor(Options.default_color);
+
+                return new NotificatedApp(pkg, color, enabled);
+            }
+        } catch (Exception e) {
+            return null;
+        }
+
+//        default!!!
+        return new NotificatedApp(pkg, getColor(Options.default_color), true);
+    }
+
+    public static <T> T get(Class<T> c, XMLPrefsManager.XMLPrefsSave prefsSave) {
+        if(prefsSave != null) {
+            try {
+                return (T) transform(values.get(prefsSave).value, c);
+            } catch (Exception e) {
+                return (T) transform(prefsSave.defaultValue(), c);
+            }
+        }
+        return null;
+    }
+
+    public static int getColor(XMLPrefsManager.XMLPrefsSave prefsSave) {
+        if(prefsSave != null) {
+            try {
+                return (int) transform(values.get(prefsSave).value, Color.class);
+            } catch (Exception e) {
+                String def = prefsSave.defaultValue();
+                if(def == null || def.length() == 0) {
+                    return -1;
+                }
+                return (int) transform(def, Color.class);
+            }
+        }
+        return 0;
+    }
+
+    public static int colorsLength() {
+        return colors.size();
+    }
+
+    public static class NotificatedApp {
+        String pkg;
+        int color;
+        boolean enabled;
+
+        public NotificatedApp(String pkg, String color, boolean enabled) throws Exception {
+            this(pkg, Color.parseColor(color), enabled);
+        }
+
+        public NotificatedApp(String pkg, int color, boolean enabled) {
+            this.pkg = pkg;
+            this.color = color;
+            this.enabled = enabled;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if(obj instanceof NotificatedApp) return pkg.equals(((NotificatedApp) obj).pkg);
+            return this == obj;
+        }
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationService.java b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationService.java
new file mode 100644
index 0000000..7a0bb59
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationService.java
@@ -0,0 +1,131 @@
+package ohi.andre.consolelauncher.managers.notifications;
+
+/**
+ * Created by francescoandreuzzi on 27/04/2017.
+ */
+
+import android.annotation.TargetApi;
+import android.app.Notification;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.os.Build;
+import android.os.Handler;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.support.annotation.IntDef;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import ohi.andre.consolelauncher.BuildConfig;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+
+import static ohi.andre.consolelauncher.managers.notifications.NotificationManager.*;
+
+
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
+public class NotificationService extends NotificationListenerService {
+
+    private final int UPDATE_TIME = 200;
+
+    Map<String, Long> recentNotifications = new HashMap<>();
+    Handler handler = new Handler();
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        NotificationManager.create();
+
+        if(NotificationManager.colorsLength() == 0) {
+//            some nice apps
+            NotificationManager.notificationsChangeFor(new ArrayList<>(Arrays.asList(
+                    new NotificatedApp("com.whatsapp", Color.parseColor("#25D366"), true),
+                    new NotificatedApp("com.google.android.apps.inbox", Color.parseColor("#03A9F4"), true),
+                    new NotificatedApp("com.paypal.android.p2pmobile", Color.parseColor("#003087"), true),
+                    new NotificatedApp("com.google.android.apps.plus", Color.parseColor("#dd4b39"), true),
+                    new NotificatedApp("com.facebook.katana", Color.parseColor("#3b5998"), true),
+                    new NotificatedApp("com.twitter.android", Color.parseColor("#1da1f2"), true),
+                    new NotificatedApp("com.android.vending", Color.parseColor("#34a853"), true)
+            )));
+        }
+
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                Map<String, Long> copy = new HashMap<>(recentNotifications);
+                long time = System.currentTimeMillis();
+                for(Map.Entry<String, Long> entry : copy.entrySet()) {
+                    if(time - entry.getValue() > 300) {
+                        recentNotifications.remove(entry.getKey());
+                    }
+                }
+
+                handler.postDelayed(this, UPDATE_TIME);
+            }
+        });
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        return START_STICKY;
+    }
+
+    @Override
+    public void onNotificationPosted(StatusBarNotification sbn) {
+
+        if(recentNotifications.containsKey(sbn.getPackageName())) return;
+        recentNotifications.put(sbn.getPackageName(), System.currentTimeMillis());
+
+        Notification notification = sbn.getNotification();
+        if (notification == null) {
+            return;
+        }
+
+        String pack = sbn.getPackageName();
+        NotificatedApp nApp = NotificationManager.getAppState(pack);
+        if(nApp == null || !nApp.enabled) {
+            return;
+        }
+
+        CharSequence textSequence = null, titleSequence = null;
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            textSequence = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
+            titleSequence = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
+        } else {
+            textSequence = notification.tickerText;
+        }
+
+        String text = null, title = null;
+        if(textSequence != null) {
+            text = textSequence.toString();
+        }
+
+        if(titleSequence != null) {
+            title = titleSequence.toString();
+        }
+
+        Intent msgrcv = new Intent("Msg");
+        msgrcv.putExtra("package", pack);
+        msgrcv.putExtra("title", title);
+        msgrcv.putExtra("text", text);
+        msgrcv.putExtra("color", nApp.color);
+
+        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(msgrcv);
+    }
+
+    @Override
+    public void onNotificationRemoved(StatusBarNotification sbn) {}
+}
\ No newline at end of file
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionRunnable.java b/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionRunnable.java
index 702082b..bccaba7 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionRunnable.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionRunnable.java
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.*/
 
+import android.app.Activity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.HorizontalScrollView;
@@ -95,6 +96,14 @@ public class SuggestionRunnable implements Runnable {
 
                 toRecycle[count].setText(s);
                 toRecycle[count].setBackgroundDrawable(skinManager.getSuggestionBg(suggestions[count].type));
+                toRecycle[count].setTextColor(skinManager.getSuggestionTextColor(suggestions[count].type));
+
+                if(suggestions[count].type == SuggestionsManager.Suggestion.TYPE_CONTACT) {
+                    toRecycle[count].setLongClickable(true);
+                    ((Activity) toRecycle[count].getContext()).registerForContextMenu(toRecycle[count]);
+                } else {
+                    ((Activity) toRecycle[count].getContext()).unregisterForContextMenu(toRecycle[count]);
+                }
 
             } else {
                 int space = suggestions.length - (count + 1);
@@ -103,10 +112,18 @@ public class SuggestionRunnable implements Runnable {
 
                     toAdd[space].setText(s);
                     toAdd[space].setBackgroundDrawable(skinManager.getSuggestionBg(suggestions[count].type));
+                    toAdd[space].setTextColor(skinManager.getSuggestionTextColor(suggestions[count].type));
 
                     if(toAdd[space].getParent() == null) {
                         suggestionsView.addView(toAdd[space], suggestionViewParams);
                     }
+
+                    if(suggestions[count].type == SuggestionsManager.Suggestion.TYPE_CONTACT) {
+                        toAdd[space].setLongClickable(true);
+                        ((Activity) toAdd[space].getContext()).registerForContextMenu(toAdd[space]);
+                    } else {
+                        ((Activity) toAdd[space].getContext()).unregisterForContextMenu(toAdd[space]);
+                    }
                 } else {
                     throw new UnsupportedOperationException("no views enough");
                 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java
index 55d471c..6500560 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java
@@ -1,5 +1,7 @@
 package ohi.andre.consolelauncher.managers.suggestions;
 
+import android.util.Log;
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -10,15 +12,20 @@ import ohi.andre.comparestring.Compare;
 import ohi.andre.consolelauncher.commands.Command;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.CommandTuils;
+import ohi.andre.consolelauncher.commands.specific.ParamCommand;
 import ohi.andre.consolelauncher.commands.specific.PermanentSuggestionCommand;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.FileManager;
 import ohi.andre.consolelauncher.managers.MusicManager;
-import ohi.andre.consolelauncher.managers.PreferencesManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
+import static ohi.andre.consolelauncher.commands.CommandTuils.xmlPrefsEntrys;
+import static ohi.andre.consolelauncher.commands.CommandTuils.xmlPrefsFiles;
+
 /**
  * Created by francescoandreuzzi on 25/12/15.
  */
@@ -38,33 +45,6 @@ public class SuggestionsManager {
 
     private final int FIRST_INTERVAL = 3;
 
-    public SuggestionsManager(PreferencesManager preferencesManager) {
-        try {
-            int temp = Integer.parseInt(preferencesManager.getValue(PreferencesManager.MINCOMMANDSRATE));
-            min_command_rate = temp;
-        } catch (Exception e) {}
-
-        try {
-            int temp = Integer.parseInt(preferencesManager.getValue(PreferencesManager.MINAPPSRATE));
-            min_apps_rate = temp;
-        } catch (Exception e) {}
-
-        try {
-            int temp = Integer.parseInt(preferencesManager.getValue(PreferencesManager.MINCONTACTSRATE));
-            min_contacts_rate = temp;
-        } catch (Exception e) {}
-
-        try {
-            int temp = Integer.parseInt(preferencesManager.getValue(PreferencesManager.MINFILESRATE));
-            min_file_rate = temp;
-        } catch (Exception e) {}
-
-        try {
-            int temp = Integer.parseInt(preferencesManager.getValue(PreferencesManager.MINSONGSRATE));
-            min_songs_rate = temp;
-        } catch (Exception e) {}
-    }
-
     public Suggestion[] getSuggestions(MainPack info, String before, String lastWord) {
 
         List<Suggestion> suggestionList = new ArrayList<>();
@@ -100,21 +80,27 @@ public class SuggestionsManager {
                 } catch (Exception e) {}
 
                 if (cmd != null) {
+
                     if(cmd.cmd instanceof PermanentSuggestionCommand) {
                         suggestPermanentSuggestions(suggestionList, (PermanentSuggestionCommand) cmd.cmd);
                     }
 
-                    if (cmd.nArgs == cmd.cmd.maxArgs()) {
+                    if (cmd.nArgs == cmd.cmd.maxArgs() ||
+                            (cmd.mArgs != null && cmd.mArgs.length > 0 && cmd.cmd instanceof ParamCommand && cmd.nArgs >= 1 &&
+                                    ((ParamCommand) cmd.cmd).argsForParam((String) cmd.mArgs[0]) != null && ((ParamCommand) cmd.cmd).argsForParam((String) cmd.mArgs[0]).length + 1 == cmd.nArgs)) {
                         return new Suggestion[0];
                     }
 
-                    int nextArg = cmd.nextArg();
-                    if (nextArg == CommandAbstraction.PARAM) {
-                        suggestParams(suggestionList, cmd.cmd, before);
-                    }
-                    else {
-                        suggestArgs(info, cmd.nextArg(), suggestionList, before);
-                    }
+//                    if( ( !(cmd.cmd instanceof ParamCommand) && cmd.nArgs == cmd.cmd.maxArgs() - 1 && cmd.indexNotFound == cmd.cmd.maxArgs() - 1) ||
+//                            (cmd.mArgs != null && cmd.mArgs.length > 0 && cmd.cmd instanceof ParamCommand && cmd.nArgs >= 1 && ((ParamCommand) cmd.cmd).argsForParam((String) cmd.mArgs[0]).length == cmd.nArgs
+//                                    && cmd.indexNotFound == ((ParamCommand) cmd.cmd).argsForParam((String) cmd.mArgs[0]).length)) {
+////                        the last arg wasnt found
+//                        suggestArgs(info, cmd.cmd instanceof ParamCommand ? ((ParamCommand) cmd.cmd).argsForParam((String) cmd.mArgs[0])[cmd.nArgs - 1] : cmd.cmd.argType()[cmd.nArgs], suggestionList, lastWord, before);
+//                    }
+
+                    if(cmd.cmd instanceof ParamCommand && (cmd.mArgs == null || cmd.mArgs.length == 0)) suggestParams(suggestionList, (ParamCommand) cmd.cmd, before);
+                    else suggestArgs(info, cmd.nextArg(), suggestionList, before);
+
                 } else {
 //                    >>word
 //                    not a command
@@ -163,21 +149,19 @@ public class SuggestionsManager {
 
     private void suggestPermanentSuggestions(List<Suggestion> suggestions, PermanentSuggestionCommand cmd) {
         for(String s : cmd.permanentSuggestions()) {
-            Suggestion sugg = new Suggestion(null, s, false, NO_RATE, 0);
-            sugg.finalText = null;
+            Suggestion sugg = new Suggestion(null, s, false, NO_RATE, Suggestion.TYPE_PERMANENT);
             suggestions.add(sugg);
         }
     }
 
-    private void suggestParams(List<Suggestion> suggestions, CommandAbstraction cmd, String before) {
-        String[] params = cmd.parameters();
+    private void suggestParams(List<Suggestion> suggestions, ParamCommand cmd, String before) {
+        String[] params = cmd.params();
         if (params == null) {
             return;
         }
 
-        int[] args = cmd.argType();
-        boolean exec = args == null || (args[args.length - 1] == CommandAbstraction.PARAM);
-        for (String s : cmd.parameters()) {
+        boolean exec = false;
+        for (String s : cmd.params()) {
             suggestions.add(new Suggestion(before, s, exec, NO_RATE, 0));
         }
     }
@@ -188,7 +172,7 @@ public class SuggestionsManager {
             case CommandAbstraction.FILE_LIST:
                 suggestFile(info, suggestions, prev, before);
                 break;
-            case CommandAbstraction.PACKAGE:
+            case CommandAbstraction.VISIBLE_PACKAGE:
                 suggestApp(info, suggestions, prev, before);
                 break;
             case CommandAbstraction.COMMAND:
@@ -206,6 +190,14 @@ public class SuggestionsManager {
             case CommandAbstraction.HIDDEN_PACKAGE:
                 suggestHiddenApp(info, suggestions, prev, before);
                 break;
+            case CommandAbstraction.COLOR:
+                suggestColor(suggestions, prev, before);
+                break;
+            case CommandAbstraction.CONFIG_ENTRY:
+                suggestConfigEntry(suggestions, prev, before);
+                break;
+            case CommandAbstraction.CONFIG_FILE:
+                suggestConfigFile(suggestions, prev, before);
         }
     }
 
@@ -292,21 +284,25 @@ public class SuggestionsManager {
 
     private void suggestContact(MainPack info, List<Suggestion> suggestions, String prev, String before) {
         if (prev == null || prev.length() == 0) {
-            for (String s : info.contacts.names())
-                suggestions.add(new Suggestion(before, s, true, NO_RATE, Suggestion.TYPE_CONTACT));
-        } else if(prev.length() <= FIRST_INTERVAL) {
+            for (ContactManager.Contact contact : info.contacts.listContacts())
+                suggestions.add(new Suggestion(before, contact.name, true, NO_RATE, Suggestion.TYPE_CONTACT, contact));
+        }
+
+        else if(prev.length() <= FIRST_INTERVAL) {
             prev = prev.trim().toLowerCase();
-            List<String> names = info.contacts.names();
-            for (String n : names) {
-                if(n.toLowerCase().trim().startsWith(prev)) {
-                    suggestions.add(new Suggestion(before, n, true, MAX_RATE, Suggestion.TYPE_CONTACT));
+
+            for (ContactManager.Contact contact : info.contacts.listContacts())
+                if(contact.name.toLowerCase().trim().startsWith(prev)) {
+                    suggestions.add(new Suggestion(before, contact.name, true, NO_RATE, Suggestion.TYPE_CONTACT, contact));
+                }
+        }
+
+        else {
+            for(ContactManager.Contact contact : info.contacts.listContacts()) {
+                int rate = ContactManager.USE_SCROLL_COMPARE ? Compare.scrollComparison(contact.name, prev) : Compare.linearComparison(contact.name, prev);
+                if(rate >= min_contacts_rate) {
+                    suggestions.add(new Suggestion(before, contact.name, true, NO_RATE, Suggestion.TYPE_CONTACT, contact));
                 }
-            }
-        } else {
-            List<Compare.CompareInfo> infos = Compare.compareInfo(info.contacts.names(), prev, min_contacts_rate,
-                    ContactManager.USE_SCROLL_COMPARE);
-            for(Compare.CompareInfo i : infos) {
-                suggestions.add(new Suggestion(before, i.s, true, i.rate, Suggestion.TYPE_CONTACT));
             }
         }
     }
@@ -361,6 +357,12 @@ public class SuggestionsManager {
         }
     }
 
+    private void suggestColor(List<Suggestion> suggestions, String prev, String before) {
+        if(prev == null || prev.length() == 0 || (prev.length() == 1 && prev.charAt(0) != '#')) {
+            suggestions.add(new Suggestion(before, "#", false, MAX_RATE, Suggestion.TYPE_COLOR));
+        }
+    }
+
     private void suggestCommand(MainPack info, List<Suggestion> suggestions) {
         for (String s : info.commandGroup.getCommandNames()) {
             CommandAbstraction cmd = info.commandGroup.getCommandByName(s);
@@ -416,6 +418,58 @@ public class SuggestionsManager {
         }
     }
 
+    private void suggestConfigEntry(List<Suggestion> suggestions, String prev, String before) {
+        if(xmlPrefsEntrys == null) {
+            xmlPrefsEntrys = new ArrayList<>();
+            for(XMLPrefsManager.XMLPrefsRoot element : XMLPrefsManager.XMLPrefsRoot.values()) {
+                for(XMLPrefsManager.XMLPrefsSave save : element.copy)
+                    xmlPrefsEntrys.add(save);
+            }
+            for(XMLPrefsManager.XMLPrefsSave save : AppsManager.Options.values()) xmlPrefsEntrys.add(save);
+            for(XMLPrefsManager.XMLPrefsSave save : NotificationManager.Options.values()) xmlPrefsEntrys.add(save);
+        }
+
+        if(prev == null || prev.length() == 0) {
+            for(XMLPrefsManager.XMLPrefsSave s : xmlPrefsEntrys) {
+                Suggestion sg = new Suggestion(before, s.label(), false, NO_RATE, Suggestion.TYPE_COMMAND);
+                suggestions.add(sg);
+            }
+        } else if(prev.length() <= FIRST_INTERVAL) {
+            prev = prev.trim().toLowerCase();
+            for (XMLPrefsManager.XMLPrefsSave s : xmlPrefsEntrys) {
+                String label = s.label();
+                if(label.startsWith(prev)) {
+                    suggestions.add(new Suggestion(before, label, false, MAX_RATE, Suggestion.TYPE_COMMAND));
+                }
+            }
+        }
+    }
+
+    private void suggestConfigFile(List<Suggestion> suggestions, String prev, String before) {
+        if(xmlPrefsFiles == null) {
+            xmlPrefsFiles = new ArrayList<>();
+            for(XMLPrefsManager.XMLPrefsRoot element : XMLPrefsManager.XMLPrefsRoot.values())
+                xmlPrefsFiles.add(element.path);
+            xmlPrefsFiles.add(AppsManager.PATH);
+            xmlPrefsFiles.add(NotificationManager.PATH);
+        }
+        Log.e("andre", xmlPrefsFiles.toString());
+
+        if(prev == null || prev.length() == 0) {
+            for(String s : xmlPrefsFiles) {
+                Suggestion sg = new Suggestion(before, s, false, NO_RATE, Suggestion.TYPE_FILE);
+                suggestions.add(sg);
+            }
+        } else if(prev.length() <= FIRST_INTERVAL) {
+            prev = prev.trim().toLowerCase();
+            for (String s : xmlPrefsFiles) {
+                if(s.startsWith(prev)) {
+                    suggestions.add(new Suggestion(before, s, false, MAX_RATE, Suggestion.TYPE_FILE));
+                }
+            }
+        }
+    }
+
     public class Suggestion implements Comparable<Suggestion> {
 
         public static final int TYPE_APP = 10;
@@ -425,30 +479,49 @@ public class SuggestionsManager {
         public static final int TYPE_SONG = 14;
         public static final int TYPE_CONTACT = 15;
         public static final int TYPE_BOOLEAN = 16;
+        public static final int TYPE_COLOR = 17;
+        public static final int TYPE_PERMANENT = 18;
 
         public String text;
         public String textBefore;
-        public String finalText;
+
         public boolean exec;
         public int rate;
         public int type;
 
+        public Object object;
+
         public Suggestion(String before, String text, boolean exec, int rate, int type) {
+            this(before, text, exec, rate, type, null);
+        }
+
+        public Suggestion(String before, String text, boolean exec, int rate, int type, Object tag) {
             this.textBefore = before;
             this.text = text;
 
-            if(before == null || before.length() == 0) {
-                this.finalText = text;
-            } else if((text.startsWith(File.separator) || before.endsWith(File.separator)) && type == TYPE_FILE) {
-                this.finalText = textBefore + text;
-            } else {
-                this.finalText = textBefore + Tuils.SPACE + text;
-            }
-
-
             this.exec = exec;
             this.rate = rate;
             this.type = type;
+
+            this.object = tag;
+        }
+
+        public String getText() {
+            if(type == Suggestion.TYPE_CONTACT) {
+                ContactManager.Contact c = (ContactManager.Contact) object;
+
+                return textBefore + Tuils.SPACE + c.numbers.get(c.selectedNumber);
+            } else if(type == Suggestion.TYPE_PERMANENT) {
+                return text;
+            }
+
+            if(textBefore == null || textBefore.length() == 0) {
+                return text;
+            } else if((text.startsWith(File.separator) || textBefore.endsWith(File.separator)) && type == TYPE_FILE) {
+                return textBefore + text;
+            } else {
+                return textBefore + Tuils.SPACE + text;
+            }
         }
 
         @Override
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Assist.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Assist.java
new file mode 100644
index 0000000..cd1f61e
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Assist.java
@@ -0,0 +1,85 @@
+package ohi.andre.consolelauncher.tuils;
+
+import android.app.Activity;
+import android.graphics.Rect;
+import android.os.Build;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+
+import java.lang.reflect.Field;
+
+/**
+ * Created by francescoandreuzzi on 14/05/2017.
+ */
+
+public class Assist {
+
+    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
+    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
+
+    public static void assistActivity (Activity activity) {
+        new Assist(activity);
+    }
+
+    private View mChildOfContent;
+    private int usableHeightPrevious;
+    private FrameLayout.LayoutParams frameLayoutParams;
+
+    private Assist(Activity activity) {
+        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
+        mChildOfContent = content.getChildAt(0);
+        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            public void onGlobalLayout() {
+                possiblyResizeChildOfContent();
+            }
+        });
+        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
+    }
+
+    private void possiblyResizeChildOfContent() {
+        int usableHeightNow = computeUsableHeight();
+        if (usableHeightNow != usableHeightPrevious) {
+            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
+            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
+            if (heightDifference > (usableHeightSansKeyboard/4)) {
+                // keyboard probably just became visible
+                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
+            } else {
+                // keyboard probably just became hidden
+                frameLayoutParams.height = usableHeightSansKeyboard;
+            }
+            if (Build.VERSION.SDK_INT >= 11) {
+                mChildOfContent.setBottom(frameLayoutParams.height);
+            } else {
+                setPrivateField(mChildOfContent, "mBottom", frameLayoutParams.height);
+            }
+            mChildOfContent.requestLayout();
+            usableHeightPrevious = usableHeightNow;
+        }
+    }
+
+    private int computeUsableHeight() {
+        Rect r = new Rect();
+        mChildOfContent.getWindowVisibleDisplayFrame(r);
+        return (r.bottom - r.top);
+    }
+
+    private void setPrivateField(Object object, String fieldName, Object value) {
+        try {
+            Class<?> clazz = Class.forName(View.class.getName());
+            Field field = clazz.getDeclaredField(fieldName);
+            field.setAccessible(true);
+            field.set(object, value);
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (NoSuchFieldException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java
index 4cfb225..5187cc3 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java
@@ -40,7 +40,6 @@ public class KeeperService extends Service {
                 .setContentIntent(resultPendingIntent)
                 .build();
 
-
         startForeground(ONGOING_NOTIFICATION_ID, notification);
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/ShellUtils.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/ShellUtils.java
index fe58361..d56baac 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/ShellUtils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/ShellUtils.java
@@ -1,247 +1,184 @@
 package ohi.andre.consolelauncher.tuils;
 
+import android.util.Log;
+
 import java.io.BufferedReader;
-import java.io.DataOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.util.List;
+
+import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
 
 /**
- * ShellUtils
- * <ul>
- * <strong>Check root</strong>
- * <li>{@link ShellUtils#checkRootPermission()}</li>
- * </ul>
- * <ul>
- * <strong>Execte command</strong>
- * <li>{@link ShellUtils#execCommand(String, boolean, String)}</li>
- * <li>{@link ShellUtils#execCommand(String, boolean, boolean, String)}</li>
- * <li>{@link ShellUtils#execCommand(List, boolean, String)}</li>
- * <li>{@link ShellUtils#execCommand(List, boolean, boolean, String)}</li>
- * <li>{@link ShellUtils#execCommand(String[], boolean, String)}</li>
- * <li>{@link ShellUtils#execCommand(String[], boolean, boolean, String)}</li>
- * </ul>
- *
- * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
+ * Created by francescoandreuzzi on 24/04/2017.
  */
-public class ShellUtils {
 
-    public static final String SPACE = Tuils.SPACE;
-    public static final String COMMAND_SU = "su";
-    public static final String COMMAND_SU_ADD = "-c";
-    public static final String COMMAND_SH = "sh";
-    public static final String COMMAND_EXIT = "exit\n";
-    public static final String COMMAND_LINE_END = Tuils.NEWLINE;
-    public static final String COMMAND_CD = "cd";
-
-    private ShellUtils() {
-        throw new AssertionError();
-    }
+public class ShellUtils {
 
-    /**
-     * check whether has root permission
-     *
-     * @return
-     */
-    public static boolean checkRootPermission() {
-        return execCommand("echo root", true, false, null).result == 0;
-    }
+    public static class CommandResult {
+        public int result;
+        public String msg;
 
+        public CommandResult(int exit, String msg) {
+            this.result = exit;
+            this.msg = msg;
+        }
 
-    /**
-     * execute shell command, default return result msg
-     *
-     * @param command command
-     * @param isRoot  whether need to run with root
-     * @return
-     * @see ShellUtils#execCommand(String[], boolean, boolean, String)
-     */
-    public static CommandResult execCommand(String command, boolean isRoot, String path) {
-        return execCommand(new String[]{command}, isRoot, true, path);
+        @Override
+        public String toString() {
+            return msg;
+        }
     }
 
-    /**
-     * execute shell commands, default return result msg
-     *
-     * @param commands command list
-     * @param isRoot   whether need to run with root
-     * @return
-     * @see ShellUtils#execCommand(String[], boolean, boolean, String)
-     */
-    public static CommandResult execCommand(List<String> commands, boolean isRoot, String path) {
-        return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, true, path);
+    public static CommandResult execCommand(String cmd , boolean root, String path) {
+        return execCommand(new String[] {cmd}, root, path, null);
     }
 
-    /**
-     * execute shell commands, default return result msg
-     *
-     * @param commands command array
-     * @param isRoot   whether need to run with root
-     * @return
-     * @see ShellUtils#execCommand(String[], boolean, boolean, String)
-     */
-    public static CommandResult execCommand(String[] commands, boolean isRoot, String path) {
-        return execCommand(commands, isRoot, true, path);
+    public static CommandResult execCommand(String[] cmd , boolean root, String path) {
+        return execCommand(cmd, root, path, null);
     }
 
-    /**
-     * execute shell command
-     *
-     * @param command         command
-     * @param isRoot          whether need to run with root
-     * @param isNeedResultMsg whether need result msg
-     * @return
-     * @see ShellUtils#execCommand(String[], boolean, boolean, String)
-     */
-    public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg, String path) {
-        return execCommand(new String[]{command}, isRoot, isNeedResultMsg, path);
+    public static CommandResult execCommand(String cmd , boolean root, String path, Outputable outputable) {
+        return execCommand(new String[] {cmd}, root, path, outputable);
     }
 
-    /**
-     * execute shell commands
-     *
-     * @param commands        command list
-     * @param isRoot          whether need to run with root
-     * @param isNeedResultMsg whether need result msg
-     * @return
-     * @see ShellUtils#execCommand(String[], boolean, boolean, String)
-     */
-    public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg, String path) {
-        return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg, path);
-    }
+//    custom dir doesnt work, and also multiple commands
+    public static CommandResult execCommand(String[] cmds , boolean root, String path, final Outputable outputable) {
+//        try {
+//            Process process = Runtime.getRuntime().exec(cmds[0]);
+//            process.waitFor();
+//
+//            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+//
+//            StringBuilder log = new StringBuilder();
+//            String line;
+//            while ((line = bufferedReader.readLine()) != null) {
+//                Log.e("andre", "uh");
+//                log.append(line + "\n");
+//            }
+//            process.destroy();
+//
+//            return new CommandResult(0, log.toString());
+//        } catch (Exception e) {
+//            return new CommandResult(0, e.toString());
+//        }
+
+        if(cmds.length > 1) return null;
 
-    /**
-     * execute shell commands
-     *
-     * @param commands        command array
-     * @param isRoot          whether need to run with root
-     * @param isNeedResultMsg whether need result msg
-     * @return <ul>
-     * <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
-     * {@link CommandResult#errorMsg} is null.</li>
-     * <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
-     * </ul>
-     */
-    public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg, String path) {
         int result = -1;
-        if (commands == null || commands.length == 0) {
-            return new CommandResult(result, null, null);
+        if (cmds == null || cmds.length == 0) {
+            return null;
         }
 
-        Process process = null;
-        BufferedReader successResult = null;
         BufferedReader errorResult = null;
-        StringBuilder successMsg = null;
         StringBuilder errorMsg = null;
+        final StringBuilder output = new StringBuilder();
 
-        DataOutputStream os = null;
+//        DataOutputStream os = null;
         try {
-            process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
-            os = new DataOutputStream(process.getOutputStream());
-
-            if (path != null) {
-                String cdCommand = COMMAND_CD + SPACE + path;
-                os.write(cdCommand.getBytes());
-                os.writeBytes(COMMAND_LINE_END);
-                os.flush();
-            }
-
-            for (String command : commands) {
-                if (command == null) {
-                    continue;
+//            process = Runtime.getRuntime().exec(root ? "su" : "sh");
+//            os = new DataOutputStream(process.getOutputStream());
+//
+//            if (path != null) {
+//                String cdCommand = "cd " + path;
+//                os.write(cdCommand.getBytes());
+//                os.writeBytes(Tuils.NEWLINE);
+//                os.flush();
+//            }
+
+//            for (String command : cmds) {
+//                if (command == null) {
+//                    continue;
+//                }
+//
+//                os.write(command.getBytes());
+//                os.writeBytes(Tuils.NEWLINE);
+//            }
+//            os.flush();
+
+            final Process process = Runtime.getRuntime().exec((root ? "su -c " : "") + cmds[0], null, path != null ? new File(path) : null);
+            final Thread externalThread = Thread.currentThread();
+
+            Thread thread = new StoppableThread() {
+
+                @Override
+                public void run() {
+                    super.run();
+
+                    if(Thread.interrupted() || externalThread.isInterrupted()) return;
+
+                    BufferedReader successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
+                    String s;
+                    try {
+                        while ((s = successResult.readLine()) != null) {
+                            if(Thread.currentThread().isInterrupted() || externalThread.isInterrupted()) return;
+
+                            if(outputable != null) outputable.onOutput(Tuils.NEWLINE + s);
+
+                            output.append(Tuils.NEWLINE);
+                            output.append(s);
+                        }
+                    } catch (IOException e) {
+                        Log.e("andre", "", e);
+                    }
+
+                    try {
+                        sleep(50);
+                    } catch (InterruptedException e) {
+                        Log.e("andre", "", e);
+                        return;
+                    }
+
+                    run();
                 }
-
-                os.write(command.getBytes());
-                os.writeBytes(COMMAND_LINE_END);
-                os.flush();
-            }
-            os.writeBytes(COMMAND_EXIT);
-            os.flush();
+            };
+            thread.start();
 
             result = process.waitFor();
-            // get command result
-            if (isNeedResultMsg) {
-                successMsg = new StringBuilder();
+            thread.interrupt();
+
+            if(output.length() == 0) {
                 errorMsg = new StringBuilder();
-                successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
+
+//                successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
                 errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+
                 String s;
-                while ((s = successResult.readLine()) != null) {
-                    successMsg.append(COMMAND_LINE_END);
-                    successMsg.append(s);
-                }
+//                while ((s = successResult.readLine()) != null) {
+//                    successMsg.append(Tuils.NEWLINE);
+//                    successMsg.append(s);
+//                }
                 while ((s = errorResult.readLine()) != null) {
-                    successMsg.append(COMMAND_LINE_END);
+                    if(errorMsg.length() > 0) errorMsg.append(Tuils.NEWLINE);
                     errorMsg.append(s);
                 }
             }
+
+            process.destroy();
         }
         catch (Exception e) {}
         finally {
             try {
-                if (os != null) {
-                    os.close();
-                }
-                if (successResult != null) {
-                    successResult.close();
-                }
+//                if (os != null) {
+//                    os.close();
+//                }
+//                if (successResult != null) {
+//                    successResult.close();
+//                }
                 if (errorResult != null) {
                     errorResult.close();
                 }
             } catch (IOException e) {
-                e.printStackTrace();
-            }
-
-            if (process != null) {
-                process.destroy();
+                Log.e("andre", "", e);
             }
         }
-        return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
-                : errorMsg.toString());
-    }
-
-    /**
-     * result of command
-     * <ul>
-     * <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
-     * linux shell</li>
-     * <li>{@link CommandResult#successMsg} means success message of command result</li>
-     * <li>{@link CommandResult#errorMsg} means error message of command result</li>
-     * </ul>
-     *
-     * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
-     */
-    public static class CommandResult {
 
-        /**
-         * result of command
-         **/
-        public int result;
-        /**
-         * success message of command result
-         **/
-        public String successMsg;
-        /**
-         * error message of command result
-         **/
-        public String errorMsg;
-
-        public CommandResult(int result) {
-            this.result = result;
+        if(output.length() > 0) {
+            return new CommandResult(result, output.toString());
         }
-
-        public CommandResult(int result, String successMsg, String errorMsg) {
-            this.result = result;
-            this.successMsg = successMsg;
-            this.errorMsg = errorMsg;
-        }
-
-        @Override
-        public String toString() {
-            if (successMsg != null && successMsg.length() > 0)
-                return successMsg;
-            else
-                return errorMsg;
+        else if(errorMsg != null) {
+            return new CommandResult(result, errorMsg.toString());
         }
+        return null;
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/SquareImageView.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/SquareImageView.java
index bdf7d9b..23176af 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/SquareImageView.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/SquareImageView.java
@@ -1,8 +1,6 @@
 package ohi.andre.consolelauncher.tuils;
 
-import android.annotation.TargetApi;
 import android.content.Context;
-import android.os.Build;
 import android.support.annotation.Nullable;
 import android.util.AttributeSet;
 import android.widget.ImageView;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/StoppableThread.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/StoppableThread.java
new file mode 100644
index 0000000..4772add
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/StoppableThread.java
@@ -0,0 +1,22 @@
+package ohi.andre.consolelauncher.tuils;
+
+/**
+ * Created by francescoandreuzzi on 27/04/2017.
+ */
+
+public class StoppableThread extends Thread {
+
+    private volatile boolean stopped = false;
+
+    @Override
+    public void interrupt() {
+        super.interrupt();
+
+        stopped = true;
+    }
+
+    @Override
+    public boolean isInterrupted() {
+        return stopped || super.isInterrupted();
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
index 8346f75..ebb75a9 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
@@ -12,6 +12,7 @@ import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
@@ -19,6 +20,7 @@ import android.os.Build;
 import android.os.Environment;
 import android.provider.MediaStore;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
@@ -32,8 +34,11 @@ import java.util.Enumeration;
 import java.util.List;
 
 import dalvik.system.DexFile;
+import ohi.andre.consolelauncher.BuildConfig;
 import ohi.andre.consolelauncher.managers.MusicManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.tuils.stuff.FakeLauncherActivity;
 import ohi.andre.consolelauncher.tuils.tutorial.TutorialActivity;
 
 public class Tuils {
@@ -45,6 +50,7 @@ public class Tuils {
     public static final String DOT = ".";
     public static final String EMPTYSTRING = "";
     private static final String TUI_FOLDER = "t-ui";
+    public static final String MINUS = "-";
 
     public static boolean arrayContains(int[] array, int value) {
         for(int i : array) {
@@ -92,6 +98,36 @@ public class Tuils {
         return songs;
     }
 
+    public static boolean hasNotificationAccess(Context context) {
+        String pkgName = BuildConfig.APPLICATION_ID;
+        final String flat = Settings.Secure.getString(context.getContentResolver(), "enabled_notification_listeners");
+        if (!TextUtils.isEmpty(flat)) {
+            final String[] names = flat.split(":");
+            for (int i = 0; i < names.length; i++) {
+                final ComponentName cn = ComponentName.unflattenFromString(names[i]);
+                if (cn != null) {
+                    if (TextUtils.equals(pkgName, cn.getPackageName())) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    public static void resetPreferredLauncherAndOpenChooser(Context context) {
+        PackageManager packageManager = context.getPackageManager();
+        ComponentName componentName = new ComponentName(context, FakeLauncherActivity.class);
+        packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+
+        Intent selector = new Intent(Intent.ACTION_MAIN);
+        selector.addCategory(Intent.CATEGORY_HOME);
+        selector.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        context.startActivity(selector);
+
+        packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP);
+    }
+
     public static void showTutorial(Context context) {
         context.startActivity(new Intent(context, TutorialActivity.class));
     }
@@ -133,6 +169,12 @@ public class Tuils {
         return classes;
     }
 
+    public static String[] toString(Enum[] enums) {
+        String[] arr = new String[enums.length];
+        for(int count = 0; count < enums.length; count++) arr[count] = enums[count].name();
+        return arr;
+    }
+
     private static String getNicePath(String filePath) {
         String home = Tuils.getInternalDirectoryPath();
 
@@ -145,6 +187,33 @@ public class Tuils {
         }
     }
 
+    public static int find(Object o, Object[] array) {
+        for(int count = 0; count < array.length; count++) {
+            if(o.equals(array[count])) return count;
+        }
+        return -1;
+    }
+
+    public static int find(Object o, List<Object> list) {
+        for(int count = 0; count < list.size(); count++) {
+            Object x = list.get(count);
+            if(o instanceof XMLPrefsManager.XMLPrefsSave) {
+                try {
+                    if(((XMLPrefsManager.XMLPrefsSave) o).is((String) x)) return count;
+                } catch (Exception e) {}
+            }
+
+            if(o instanceof String && x instanceof XMLPrefsManager.XMLPrefsSave) {
+                try {
+                    if(((XMLPrefsManager.XMLPrefsSave) x).is((String) o)) return count;
+                } catch (Exception e) {}
+            }
+
+            if(o.equals(list.get(count))) return count;
+        }
+        return -1;
+    }
+
     public static String getHint(SkinManager skinManager, String currentPath) {
 
         if(!skinManager.showUsernameAndDeviceWhenEmpty) {
@@ -169,10 +238,10 @@ public class Tuils {
             path = ":" + getNicePath(currentPath);
         }
 
-        if(username == Tuils.EMPTYSTRING) {
+        if(username.equals(Tuils.EMPTYSTRING)) {
             return deviceName + path;
         } else {
-            if(deviceName == Tuils.EMPTYSTRING) {
+            if(deviceName.equals(Tuils.EMPTYSTRING)) {
                 return username + path;
             } else {
                 return username + "@" + deviceName + path;
@@ -402,7 +471,7 @@ public class Tuils {
         return null;
     }
 
-    public static File getTuiFolder() {
+    private static File getTuiFolder() {
         String internalDir = Tuils.getInternalDirectoryPath();
         if(internalDir == null) {
             return null;
@@ -536,7 +605,10 @@ public class Tuils {
     }
 
     private static final int FILEUPDATE_DELAY = 300;
+    private static File folder = null;
     public static File getFolder() {
+        if(folder != null) return folder;
+
         final File tuiFolder = Tuils.getTuiFolder();
 
         while (true) {
@@ -549,6 +621,7 @@ public class Tuils {
             } catch (InterruptedException e) {}
         }
 
-        return tuiFolder;
+        folder = tuiFolder;
+        return folder;
     }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Inputable.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Inputable.java
index ff47b4e..6142350 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Inputable.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Inputable.java
@@ -6,4 +6,6 @@ package ohi.andre.consolelauncher.tuils.interfaces;
 
 public interface Inputable {
     void in(String s);
+    void changeHint(String s);
+    void resetHint();
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnNewInputListener.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnNewInputListener.java
deleted file mode 100644
index 686cf18..0000000
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnNewInputListener.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package ohi.andre.consolelauncher.tuils.interfaces;
-
-/**
- * Created by francescoandreuzzi on 29/03/16.
- */
-public interface OnNewInputListener {
-
-    void onNewInput(String input);
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/stuff/FakeLauncherActivity.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/stuff/FakeLauncherActivity.java
new file mode 100644
index 0000000..cc45826
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/stuff/FakeLauncherActivity.java
@@ -0,0 +1,9 @@
+package ohi.andre.consolelauncher.tuils.stuff;
+
+import android.app.Activity;
+
+/**
+ * Created by francescoandreuzzi on 21/05/2017.
+ */
+
+public class FakeLauncherActivity extends Activity{}
diff --git a/app/src/main/res/layout/input_down_layout.xml b/app/src/main/res/layout/input_down_layout.xml
index ea654e2..dfabbfe 100644
--- a/app/src/main/res/layout/input_down_layout.xml
+++ b/app/src/main/res/layout/input_down_layout.xml
@@ -12,7 +12,7 @@
         android:layout_alignParentBottom="true">
         <LinearLayout
             android:id="@+id/suggestions_group"
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="@dimen/suggestion_height"
             android:gravity="left|center_vertical"
             android:orientation="horizontal">
@@ -76,7 +76,7 @@
             android:paddingTop="@dimen/input_padding"
 
             android:lines="1"
-            android:singleLine="true" />
+            android:singleLine="true"/>
 
         <ImageButton
             android:id="@+id/submit_tv"
@@ -93,18 +93,33 @@
 
     <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="match_parent"
 
-        android:layout_above="@id/input_group">
-        <TextView
-            android:id="@+id/terminal_view"
+        android:layout_above="@id/input_group"
+
+        android:fillViewport="true">
+
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
+
+            android:orientation="vertical">
+
+            <View
+                android:layout_width="0dp"
+                android:layout_weight="1"
+                android:layout_height="match_parent"/>
+
+            <TextView
+                android:id="@+id/terminal_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+
+                android:scrollHorizontally="false"
+                android:scrollbars="vertical"/>
+
+        </LinearLayout>
 
-            android:gravity="bottom"
-            android:scrollHorizontally="false"
-            android:scrollbars="vertical"
-            android:textIsSelectable="true"/>
     </ScrollView>
 
 </RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/raw/alias.txt b/app/src/main/res/raw/alias.txt
deleted file mode 100755
index dc7e830..0000000
--- a/app/src/main/res/raw/alias.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-// do not insert random spaces!
-
-root=cd /
-st=settings
-mp3=mv Downloads/*.mp3 Music
-pdf=mv Downloads/*.pdf Docs
\ No newline at end of file
diff --git a/app/src/main/res/raw/settings.txt b/app/src/main/res/raw/settings.txt
deleted file mode 100755
index 784d05e..0000000
--- a/app/src/main/res/raw/settings.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-// do not edit the settingsVersion property!
-settingsVersion=89
-
-// when you are ready go back to t-ui and type "restart" to see changes
-
-// skin
-deviceColor=#ffff9800
-inputColor=#ff00ff00
-outputColor=#ffffffff
-backgroundColor=#ff000000
-useSystemFont=false
-fontSize=15
-ramColor=#fff44336
-inputFieldBottom=true
-username=user
-showUsername=true
-showSubmit=true
-deviceName=null
-showRam=true
-showDevice=true
-showToolbar=true
-showSessionInfoWhenInputEmpty=true
-linuxAppearance=true
-showPathInSessionInfo=true
-showDeviceNameInSessionInfo=true
-
-// suggestions
-suggestionTextColor=#ff000000
-transparentSuggestions=false
-multicolorSuggestions=true
-executeOnSuggestionClick=true
-aliasSuggestionBg=#ffFF5722
-appSuggestionBg=#ff00897B
-commandSuggestionsBg=#ff76FF03
-songSuggestionBg=#ffEEFF41
-contactSuggestionBg=#ff64FFDA
-fileSuggestionBg=#ff03A9F4
-defaultSuggestionBg=#ffFFFFFF
-
-// rates (change values if you want to show less or more result in suggestions)
-minAppsRate=4
-minFilesRate=2
-minSongsRate=4
-minContactsRate=4
-minCommandsRate=4
-
-// pre-load
-useSystemWallpaper=false
-fullscreen=false
-keepAliveWithNotification=true
-openKeyboardOnStart=true
-
-// music
-fromMediastore=true
-playRandom=true
-songsFolder=/sdcard/Music
-
-// others
-closeOnDbTap=true
-doubleTapSU=true
-showSuggestions=true
-enableEnterInPhysicalKeyboard=false
-compareStringForApps=false
-showDonationMessage=true
-showAliasValue=true
-
-// commands
-defaultSearch=-g
-
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 96ace6f..fc38f9f 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,6 +2,7 @@
 
     <!-- various text -->
     <string name="app_name">T-UI</string>
+    <string name="notification_reader">Notification Reader</string>
     <string name="separator_text">>></string>
     <string name="separator_text_su">$</string>
     <string name="su">T-UI got SU permission</string>
@@ -9,6 +10,11 @@
     <string name="permissions_toast">You have to grant Storage permission</string>
     <string name="version_label">Version:</string>
     <string name="output_error">An unknown error has occurred</string>
+    <string name="location_off">Turn on GPS or network location</string>
+
+    <!-- busy -->
+    <string name="busy">T-UI is busy, wait until the execution finishes or use the command \"ctrlc\"</string>
+    <string name="busy_hint">type "ctrlc" to stop</string>
 
     <string name="rate_donate_text">\nDo you like my work? Rate on Play Store (command: >>rate) or offer me a coffee (command: >>donate). Thank you for using T-UI.\n\nYou can disable this message in >>tuisettings</string>
 
@@ -31,6 +37,8 @@
     <string name="output_waitingpermission">Waiting permission</string>
     <string name="output_invalidcalc">calc encountered this error:</string>
     <string name="output_problemcamera">There was a problem while connecting to your device camera</string>
+    <string name="output_numberformat">Wrong number format</string>
+    <string name="output_invalidarg">Invalid argument</string>
 
     <!-- tuixt -->
     <string name="help_tuixt_help">Print the list of commands, or info about a command
@@ -78,7 +86,7 @@
     <!-- command/args -->
     <string name="output_commandnotfound">Command not found.\nTry to use \">>help\" or \">>tutorial\"</string>
     <string name="output_toomanyargs">More arguments than expected</string>
-    <string name="output_invalid_param">Invalid parameter</string>
+    <string name="output_invalid_param">Invalid option:</string>
     <string name="output_commandexitvalue">Command returned </string>
 
     <!-- flash -->
@@ -107,18 +115,18 @@
     <string name="output_smssent">SMS sent</string>
 
 
-    <string name="help_about">Informations about the app</string>
     <string name="help_airplane">Toggle Airplane Mode</string>
     <string name="help_aliases">Print alias that are currently saved in \"sdcard\"/t-ui/alias.txt</string>
     <string name="help_aliasfile">Open alias.txt</string>
     <string name="help_apps">Manage your apps
         \n\nUsage:
         \n>>apps [option] [app name]
-        \n\n[option] can be:
-        \n-sh -> show hidden apps
-        \n-ps [app name] -> show Google Play Store page for this app
-        \n-st [app name] -> show Settings details for this app
-        \n-f [app name] -> force t-ui to open this app
+        \n\n-lshidden -> show hidden apps
+        \n-show -> show an hidden application
+        \n-hide -> hide an application
+        \n-ps -> show Google Play Store page for this app
+        \n-st -> show Settings details for this app
+        \n-frc -> force t-ui to open this app
         \nno option -> list your apps
         \n\nExample:
         \n>>apps -st T-UI
@@ -151,6 +159,14 @@
         \n\n>>call James
     </string>
     <string name="help_contacts">Print your contacts</string>
+    <string name="help_config">Manage your config files.
+        \nUsage:
+        \n>>config [option] [file OR config_entry] [*value]
+        \n\n-set -> set the value of a config node
+        \n-open -> open a config file
+        \n\nExample:
+        \n>>config -set bg_color #ff0000aa
+        \n>>config -open suggestions.xml</string>
     <string name="help_cp">Copy one or more files to a folder
         \nUsage:
         \n>>[su] cp [files] [folder]
@@ -179,9 +195,6 @@
     <string name="help_previous">Play the last track played</string>
     <string name="help_rate">Help T-UI with a positive rate (or negative, I don\'t know)\t;)</string>
     <string name="help_refresh">Refresh apps and alias</string>
-    <string name="help_remove">Uninstall t-ui automatically.
-        \n\nMake sure you have another Launcher!
-    </string>
     <string name="help_restart">Restart t-ui and load modified values</string>
     <string name="help_rm">Remove a file:
         \nUsage:
@@ -193,8 +206,7 @@
     <string name="help_search">Search something somewhere
         \nUsage:
         \nsearch [option] something
-        \n\n[option] can be:
-        \n-g -> (Google Search)
+        \n\n-g -> (Google Search)
         \n-p -> (Google Play Store)
         \n-f -> (Files)
         \n-y -> (YouTube)
@@ -213,11 +225,14 @@
     <string name="help_time">Print current time</string>
     <string name="help_track">Print informations about the current track</string>
     <string name="help_tracks">Print all of the tracks in your music folder</string>
-    <string name="help_tuisettings">Open t-ui settings file</string>
-    <string name="help_tuixt">Open tuixt, the T-UI text editor.
+    <string name="help_tuixt">Open the text editor.
         \nUsage:
         \n>>tuixt [text file]
     </string>
+    <string name="help_tui">Usage:
+        \nt>>tui [option]
+        \n\n-rm -> remove t-ui
+        \n-about -> show info about the developer and the current version</string>
     <string name="help_tutorial">Go to T-UI tutorial page</string>
     <string name="help_uninstall">Uninstall an application
         \nUsage:
@@ -226,6 +241,43 @@
         \n>>uninstall dropbox
     </string>
     <string name="help_wifi">Toggle wifi</string>
+    <string name="help_sms">Send an SMS.
+        \nUsage:
+        \n>>sms [contact name] OR [phone number] {newline}
+        \n>>[text]
+        \n\nExample:
+        \n>>sms John Smith
+        \n>>Hi John, I need to talk you about T-UI, it\'s a fantastic launcher!</string>
+    <string name="help_vibrate">Vibrates your device.
+        \nUsage:
+        \n>>vibrate [ms]
+        \n\nExample:
+        \n\nvibrate 2000</string>
+    <string name="help_beep">Emits a beep.
+        \nUsage:
+        \n>>beep</string>
+    <string name="help_notifications">Manage your notifications.
+        \nUsage:
+        \nnotifications [option] [appName] [*optional* color]
+        \n\n-inc -> include an application
+        \n-exc -> exclude an appliation
+        \n-clr -> set the color to be used for the application
+        \n\nExample:
+        \n\nnotifications -inc Clock
+        \nnotifications -clr Settings #FF0000</string>
+    <string name="help_location">Show the current location</string>
+    <string name="help_cntcts">Manage your contacts.
+        \nUsage:
+        \ncntcts [option] [*optional* contact]
+        \n\n-ls -> list your contacts
+        \n-show -> show details about a contact
+        \n-new -> create a new contact
+        \n-edit -> edit an existing contact
+        \n-rm -> remove a contact
+        \n\nExample:
+        \n\ncntcts -edit James Pike
+        \ncntcts -new</string>
+    <string name="help_exit">Close T-UI and reset launcher preferences</string>
 
     <!-- linux -->
     <string name="help_cd">Change the current directory
@@ -246,13 +298,6 @@
         \n\nExample:
         \n>>ls Downloads
     </string>
-    <string name="help_sms">Send an SMS.
-        \nUsage:
-        \n>>sms [contact name] OR [phone number] {newline}
-        \n>>[text]
-        \n\nExample:
-        \n>>sms John Smith
-        \n>>Hi John, I need to talk you about T-UI, it\'s a fantastic launcher!</string>
 
     <string name="start_notification">T-UI started</string>
     <string name="tui_running">T-UI is running</string>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index db370fe..6f391a7 100755
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -3,6 +3,7 @@
     <style name="Custom.Solid" parent="Theme.AppCompat.Light.NoActionBar">
         <item name="android:textColorHint">@color/hint_color</item>
         <item name="android:statusBarColor">@android:color/black</item>
+        <item name="android:navigationBarColor">@android:color/black</item>
     </style>
     <style name="Custom.Solid.Fullscreen" parent="Custom.Solid">
         <item name="android:windowFullscreen">true</item>
@@ -13,6 +14,7 @@
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:textColorHint">@color/hint_color</item>
         <item name="android:statusBarColor">@android:color/black</item>
+        <item name="android:navigationBarColor">@android:color/black</item>
     </style>
     <style name="Custom.SystemWP.Fullscreen" parent="Custom.SystemWP">
         <item name="android:windowFullscreen">true</item>
diff --git a/build.gradle b/build.gradle
index 6ac76f7..e21e380 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.3.0'
+        classpath 'com.android.tools.build:gradle:2.3.1'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
-- 
GitLab