diff --git a/app/build.gradle b/app/build.gradle
index a15995c6a6644fc0a7cf04eaeedb2aa3ab5c7970..ee26b31e702bc837dcbc9eaaf836aeed054d2ae8 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,8 +11,8 @@ android {
         minSdkVersion 9
         targetSdkVersion 23
 
-        versionCode 125
-        versionName "6.3b"
+        versionCode 136
+        versionName "6.3j"
     }
 
     buildTypes {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0beffc523a9219fef3c5c95eb5e70fb4ac8aae59..5937f1abe5a1c1fe899813f874a322b6ff5ccdb0 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -204,6 +204,8 @@
 
         </service>
 
+        <service android:name=".managers.notifications.NotificationMonitorService"/>
+
         <activity
             android:name=".tuils.stuff.FakeLauncherActivity"
             android:enabled="false">
diff --git a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
index 1df632d720c336b51b96aca523bd90c4e4617e67..ab8c991f6c085f7aafa6c672172636e5881de185 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
@@ -1,8 +1,7 @@
 package ohi.andre.consolelauncher;
 
 import android.Manifest;
-import android.content.BroadcastReceiver;
-import android.content.Context;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
@@ -13,7 +12,6 @@ import android.os.Bundle;
 import android.os.Handler;
 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.view.ContextMenu;
 import android.view.KeyEvent;
@@ -36,6 +34,7 @@ import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.TerminalManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
+import ohi.andre.consolelauncher.managers.notifications.NotificationMonitorService;
 import ohi.andre.consolelauncher.managers.notifications.NotificationService;
 import ohi.andre.consolelauncher.managers.suggestions.SuggestionsManager;
 import ohi.andre.consolelauncher.tuils.Assist;
@@ -63,7 +62,9 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
     private UIManager ui;
     private MainManager main;
 
-    private boolean openKeyboardOnStart, fullscreen, canApplyTheme;
+    private InputOutputReceiver ioReceiver;
+
+    private boolean openKeyboardOnStart, canApplyTheme;
 
     private CommandExecuter ex = new CommandExecuter() {
 
@@ -242,8 +243,8 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         filter.addAction(InputOutputReceiver.ACTION_CMD);
         filter.addAction(InputOutputReceiver.ACTION_OUTPUT);
 
-        InputOutputReceiver inputOutputReceiver = new InputOutputReceiver(ex, out);
-        getApplicationContext().registerReceiver(inputOutputReceiver, filter);
+        ioReceiver = new InputOutputReceiver(ex, out);
+        getApplicationContext().registerReceiver(ioReceiver, filter);
 
         try {
             XMLPrefsManager.create(this);
@@ -259,7 +260,6 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
 
             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
-
             window.setStatusBarColor(XMLPrefsManager.getColor(XMLPrefsManager.Theme.statusbar_color));
             window.setNavigationBarColor(XMLPrefsManager.getColor(XMLPrefsManager.Theme.navigationbar_color));
         }
@@ -274,7 +274,7 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
             } catch (Exception e) {}
         }
 
-        fullscreen = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.fullscreen);
+        boolean fullscreen = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.fullscreen);
 
         boolean useSystemWP = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.system_wallpaper);
         if (useSystemWP) {
@@ -297,11 +297,15 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
             Tuils.toFile(e);
         }
 
-        boolean notifications = XMLPrefsManager.get(boolean.class, NotificationManager.Options.show_notifications);
-        if(!notifications) notifications = XMLPrefsManager.get(String.class, NotificationManager.Options.show_notifications).equalsIgnoreCase("enabled");
+
+        boolean notifications = XMLPrefsManager.get(boolean.class, NotificationManager.Options.show_notifications) ||
+                XMLPrefsManager.get(String.class, NotificationManager.Options.show_notifications).equalsIgnoreCase("enabled");
 
         if(notifications) {
-            LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));
+            ComponentName thisComponent = new ComponentName(this, NotificationService.class);
+            PackageManager pm = getPackageManager();
+            pm.setComponentEnabledSetting(thisComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+
             if(!Tuils.hasNotificationAccess(this)) {
                 Intent i = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
                 if(i.resolveActivity(getPackageManager()) == null) {
@@ -310,6 +314,14 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
                     startActivity(i);
                 }
             }
+
+            Intent monitor = new Intent(this, NotificationMonitorService.class);
+            startService(monitor);
+
+            Intent timeColorIntent = new Intent(this, NotificationService.class);
+            Tuils.log(XMLPrefsManager.get(XMLPrefsManager.Theme.time_color));
+            timeColorIntent.putExtra(XMLPrefsManager.Theme.time_color.label(), XMLPrefsManager.getColor(XMLPrefsManager.Theme.time_color));
+            startService(timeColorIntent);
         }
 
         openKeyboardOnStart = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.auto_show_keyboard);
@@ -375,9 +387,9 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
 
         try {
             stopService(new Intent(this, KeeperService.class));
-            stopService(new Intent(this, NotificationService.class));
-        } catch (NoClassDefFoundError e) {}
-        LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
+            stopService(new Intent(this, NotificationMonitorService.class));
+            getApplicationContext().unregisterReceiver(ioReceiver);
+        } catch (NoClassDefFoundError | Exception e) {}
 
         overridePendingTransition(0,0);
 
@@ -526,14 +538,4 @@ 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) {
-            CharSequence text = intent.getCharSequenceExtra("text");
-
-            if(ui != null) ui.setOutput(text, TerminalManager.CATEGORY_NOTIFICATION);
-        }
-    };
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
index 24568dc98deccb76f9f84a8bacfd9bbd7642dc12..4363a30c7888dfb3fb6a85dd48bd7aad06253f8c 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
@@ -129,7 +129,7 @@ public class MainManager {
             cont = new ContactManager(mContext);
         } catch (NullPointerException e) {}
 
-        MusicManager2 music = new MusicManager2(mContext);
+        MusicManager2 music = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.enable_music) ? new MusicManager2(mContext) : null;
 
         AppsManager appsMgr = new AppsManager(c, sugg);
         AliasManager aliasManager = new AliasManager(mContext);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
index df46d313977b413fcffdb7c5224cffbffc981664..189809a9e9c33827ea45d16f5c438c3ebcb3b908 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
@@ -9,6 +9,7 @@ import android.content.Intent;
 import android.graphics.Typeface;
 import android.os.Handler;
 import android.text.Editable;
+import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.DisplayMetrics;
 import android.view.GestureDetector;
@@ -36,12 +37,13 @@ import java.util.regex.Pattern;
 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.MessagesManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.managers.TerminalManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.managers.suggestions.SuggestionRunnable;
 import ohi.andre.consolelauncher.managers.suggestions.SuggestionsManager;
-import ohi.andre.consolelauncher.tuils.Sequence;
+import ohi.andre.consolelauncher.tuils.AllowEqualsSequence;
 import ohi.andre.consolelauncher.tuils.StoppableThread;
 import ohi.andre.consolelauncher.tuils.TimeManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -73,11 +75,9 @@ public class UIManager implements OnTouchListener {
     private CommandExecuter trigger;
     private TerminalManager mTerminalAdapter;
 
-    private TextView ram;
-    private TextView device;
-    private TextView battery;
-    private TextView time;
-    private TextView storage;
+    private TextView[] ts;
+    private CharSequence deviceText, ramText, storageText, batteryText, timeText;
+    private int deviceIndex, ramIndex, storageIndex, batteryIndex, timeIndex;
 
     int mediumPercentage, lowPercentage;
     String batteryFormat;
@@ -85,7 +85,7 @@ public class UIManager implements OnTouchListener {
 
     private String multipleCmdSeparator;
 
-    private boolean selectFirstSuggestionEnter = false;
+//    private boolean selectFirstSuggestionEnter = false;
     private OnNewInputListener inputListener = new OnNewInputListener() {
         @Override
         public void onNewInput(String input) {
@@ -108,18 +108,21 @@ public class UIManager implements OnTouchListener {
         public void update(float p) {
             int percentage = (int) p;
 
+            int color;
+
             if(skinManager.manyColorsBattery) {
-                if(percentage > mediumPercentage) battery.setTextColor(skinManager.battery_color_high);
-                else if(percentage > lowPercentage) battery.setTextColor(skinManager.battery_color_medium);
-                else battery.setTextColor(skinManager.battery_color_low);
+                if(percentage > mediumPercentage) color = skinManager.battery_color_high;
+                else if(percentage > lowPercentage) color = skinManager.battery_color_medium;
+                else color = skinManager.battery_color_low;
             } else {
-                battery.setTextColor(skinManager.battery_color_high);
+                color = skinManager.battery_color_high;
             }
 
             if(batteryFormat == null) batteryFormat = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.battery_format);
 
             String cp = batteryFormat.replaceAll("%[vV]", String.valueOf(percentage)).replaceAll("%[nN]", Tuils.NEWLINE);
-            battery.setText(cp);
+            batteryText = Tuils.color(cp, color);
+            UIManager.this.update(batteryIndex);
         }
     };
 
@@ -212,16 +215,18 @@ public class UIManager implements OnTouchListener {
             copy = storagePatterns.get(25).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) eav, Tuils.GIGA))));
             copy = storagePatterns.get(26).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) etot, Tuils.GIGA))));
 
-            storage.setText(copy);
-            storage.postDelayed(this, STORAGE_DELAY);
+            storageText = Tuils.color(copy, info.skinManager.storageColor);
+            update(storageIndex);
+            ts[storageIndex].postDelayed(this, STORAGE_DELAY);
         }
     };
 
     private Runnable timeRunnable = new Runnable() {
         @Override
         public void run() {
-            time.setText(TimeManager.replace("%t0"));
-            time.postDelayed(this, TIME_DELAY);
+            timeText = TimeManager.replace("%t0", skinManager.time_color);
+            update(timeIndex);
+            ts[timeIndex].postDelayed(this, TIME_DELAY);
         }
     };
 
@@ -277,18 +282,45 @@ public class UIManager implements OnTouchListener {
 
             copy = ramPatterns.get(11).matcher(copy).replaceAll(Matcher.quoteReplacement(Tuils.NEWLINE));
 
-            ram.setText(copy);
-            ram.postDelayed(this, RAM_DELAY);
+            ramText = Tuils.color(copy, info.skinManager.ramColor);
+            update(ramIndex);
+            ts[ramIndex].postDelayed(this, RAM_DELAY);
         }
     };
 
+    private void update(int index) {
+        CharSequence sequence = Tuils.EMPTYSTRING;
+
+        if(deviceIndex == index && deviceText != null) {
+            sequence = deviceText;
+        }
+
+        if(batteryIndex == index && batteryText != null) {
+            sequence = TextUtils.concat(sequence, batteryText);
+        }
+
+        if(storageIndex == index && storageText != null) {
+            sequence = TextUtils.concat(sequence, storageText);
+        }
+
+        if(ramIndex == index && ramText != null) {
+            sequence = TextUtils.concat(sequence, ramText);
+        }
+
+        if(timeIndex == index && timeText != null) {
+            sequence = TextUtils.concat(sequence, timeText);
+        }
+
+        ts[index].setText(sequence);
+    }
+
     private boolean showSuggestions;
     private LinearLayout suggestionsView;
     private SuggestionViewDecorer suggestionViewDecorer;
     private SuggestionRunnable suggestionRunnable;
     private LinearLayout.LayoutParams suggestionViewParams;
     private SuggestionsManager suggestionsManager;
-    private boolean navigatingWithSpace = false;
+//    private boolean navigatingWithSpace = false;
 
     private TextView terminalView;
     private Thread lastSuggestionThread;
@@ -333,7 +365,7 @@ public class UIManager implements OnTouchListener {
                 if(multipleCmdSeparator.length() > 0) {
                     String[] split = input.split(multipleCmdSeparator);
                     if(split.length == 0) return;
-                    if(split.length == 1) mTerminalAdapter.setInput(text);
+                    if(split.length == 1) mTerminalAdapter.setInput(text + Tuils.SPACE);
                     else {
                         split[split.length - 1] = Tuils.EMPTYSTRING;
 
@@ -342,10 +374,10 @@ public class UIManager implements OnTouchListener {
                             beforeInputs = beforeInputs + split[count] + multipleCmdSeparator;
                         }
 
-                        mTerminalAdapter.setInput(beforeInputs + text);
+                        mTerminalAdapter.setInput(beforeInputs + text + Tuils.SPACE);
                     }
                 } else {
-                    mTerminalAdapter.setInput(text);
+                    mTerminalAdapter.setInput(text + Tuils.SPACE);
                 }
             }
 
@@ -477,7 +509,9 @@ public class UIManager implements OnTouchListener {
             }
         };
 
-        lastSuggestionThread.start();
+        try {
+            lastSuggestionThread.start();
+        } catch (InternalError e) {}
     }
 
     protected UIManager(ExecutePack info, final Context context, final ViewGroup rootView, final CommandExecuter tri, MainPack mainPack, boolean canApplyTheme) {
@@ -528,7 +562,8 @@ public class UIManager implements OnTouchListener {
         DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
         rootView.setPadding(Tuils.mmToPx(metrics, leftMM), Tuils.mmToPx(metrics, topMM), Tuils.mmToPx(metrics, rightMM), Tuils.mmToPx(metrics, bottomMM));
 
-        TextView[] ts = {
+//        batt, ram, ...
+        ts = new TextView[] {
                 (TextView) rootView.findViewById(R.id.tv0),
                 (TextView) rootView.findViewById(R.id.tv1),
                 (TextView) rootView.findViewById(R.id.tv2),
@@ -536,66 +571,71 @@ public class UIManager implements OnTouchListener {
                 (TextView) rootView.findViewById(R.id.tv4)
         };
 
-        int ramIndex = XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.ram_index);
-        int deviceIndex = XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.device_index);
-        int batteryIndex = XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.battery_index);
-        int timeIndex = XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.time_index);
-        int storageIndex = XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.storage_index);
-
-        final int RAM = 10, DEVICE = 11, TIME = 12, BATTERY = 13, STORAGE = 14;
-        Sequence s = new Sequence(new int[] {ramIndex, deviceIndex, batteryIndex, timeIndex, storageIndex}, new Integer[] {RAM, DEVICE, BATTERY, TIME, STORAGE});
-
-        for(int count = 0; count < s.size(); count++) {
-            int i = (int) s.get(count);
-
-            switch (i) {
-                case RAM:
-                    ram = ts[count];
-                    break;
-                case DEVICE:
-                    device = ts[count];
-                    break;
-                case BATTERY:
-                    battery = ts[count];
-                    break;
-                case STORAGE:
-                    storage = ts[count];
-                    break;
-                case TIME:
-                    time = ts[count];
-                    break;
+        boolean showRam = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_ram);
+        boolean showStorage = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_storage_info);
+        boolean showDevice = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_device_name);
+        boolean showTime = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_time);
+        boolean showBattery = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_battery);
+
+        int rIndex = showRam ? XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.ram_index) : Integer.MAX_VALUE;
+        int dIndex = showDevice ? XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.device_index) : Integer.MAX_VALUE;
+        int bIndex = showBattery ? XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.battery_index) : Integer.MAX_VALUE;
+        int tIndex = showTime ? XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.time_index) : Integer.MAX_VALUE;
+        int sIndex = showStorage ? XMLPrefsManager.get(int.class, XMLPrefsManager.Ui.storage_index) : Integer.MAX_VALUE;
+
+        final int RAM = 1;
+        final int DEVICE = 2;
+        final int TIME = 3;
+        final int BATTERY = 4;
+        final int STORAGE = 5;
+
+        Typeface t = skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole;
+
+        AllowEqualsSequence sequence = new AllowEqualsSequence(new int[] {rIndex, dIndex, bIndex, tIndex, sIndex}, new Integer[] {RAM, DEVICE, BATTERY, TIME, STORAGE});
+        for(int count = 0; count < ts.length; count++) {
+            Object[] os = sequence.get(count);
+
+            for(Object o : os) {
+                int i = (Integer) o;
+
+                switch (i) {
+                    case RAM:
+                        this.ramIndex = count;
+                        break;
+                    case DEVICE:
+                        this.deviceIndex = count;
+                        break;
+                    case BATTERY:
+                        this.batteryIndex = count;
+                        break;
+                    case STORAGE:
+                        this.storageIndex = count;
+                        break;
+                    case TIME:
+                        this.timeIndex = count;
+                        break;
+                }
+            }
+
+            if(count >= sequence.getMinKey() && count <= sequence.getMaxKey() && os.length > 0) {
+                ts[count].setTypeface(t);
+                ts[count].setTextSize(skinManager.getTextSize());
+            } else {
+                ts[count].setVisibility(View.GONE);
             }
         }
 
-        boolean showRam = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_ram);
         if (showRam) {
-            ram.setTextColor(skinManager.ramColor);
-            ram.setTextSize(skinManager.getTextSize());
-            ram.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
-
             memory = new ActivityManager.MemoryInfo();
             activityManager = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
-
-            ram.post(ramRunnable);
-        } else {
-            ram.setVisibility(View.GONE);
-            ram = null;
+            ts[this.ramIndex].post(ramRunnable);
         }
 
-        boolean showStorage = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_storage_info);
         if(showStorage) {
-            storage.setTextColor(skinManager.storageColor);
-            storage.setTextSize(skinManager.getTextSize());
-            storage.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
-
-            storage.post(storageRunnable);
-        } else {
-            storage.setVisibility(View.GONE);
+            ts[this.storageIndex].post(storageRunnable);
         }
 
-        boolean showDevice = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_device_name);
         if (showDevice) {
-
             Pattern USERNAME = Pattern.compile("%u", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
             Pattern DV = Pattern.compile("%d", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
             Pattern NEWLINE = Pattern.compile("%n", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
@@ -606,39 +646,25 @@ public class UIManager implements OnTouchListener {
             deviceFormat = DV.matcher(deviceFormat).replaceAll(Matcher.quoteReplacement(skinManager.deviceName != null ? skinManager.deviceName : "null"));
             deviceFormat = NEWLINE.matcher(deviceFormat).replaceAll(Matcher.quoteReplacement(Tuils.NEWLINE));
 
-            device.setText(deviceFormat);
-            device.setTextColor(skinManager.deviceColor);
-            device.setTextSize(skinManager.getTextSize());
-            device.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
-        } else {
-            device.setVisibility(View.GONE);
+            deviceText = Tuils.color(deviceFormat, skinManager.deviceColor);
+            update(this.deviceIndex);
         }
 
-        boolean showTime = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_time);
         if(showTime) {
-            time.setTextColor(skinManager.time_color);
-            time.setTextSize(skinManager.getTextSize());
-            time.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
-
-            time.post(timeRunnable);
-        } else {
-            time.setVisibility(View.GONE);
+            ts[this.timeIndex].post(timeRunnable);
         }
 
-        boolean showBattery = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_battery);
         if(showBattery) {
             mediumPercentage = XMLPrefsManager.get(int.class, XMLPrefsManager.Behavior.battery_medium);
             lowPercentage = XMLPrefsManager.get(int.class, XMLPrefsManager.Behavior.battery_low);
 
             if(mediumPercentage < lowPercentage) skinManager.manyColorsBattery = false;
 
-            battery.setTextSize(skinManager.getTextSize());
-            battery.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
-
             Tuils.registerBatteryReceiver(context, batteryUpdate);
         } else {
-            battery.setVisibility(View.GONE);
+            batteryUpdate = null;
         }
+//        batt, ram, ...
 
         final boolean inputBottom = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.input_bottom);
         int layoutId = inputBottom ? R.layout.input_down_layout : R.layout.input_up_layout;
@@ -737,8 +763,28 @@ public class UIManager implements OnTouchListener {
 
         mTerminalAdapter = new TerminalManager(terminalView, inputView, prefixView, submitView, backView, nextView, deleteView, pasteView, skinManager, context, mainPack);
         mTerminalAdapter.setInputListener(inputListener);
-        if(XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.donation_message)) {
-            mTerminalAdapter.addMessager(new TerminalManager.Messager(20, context.getString(R.string.rate_donate_text)));
+
+        if(XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.show_hints)) {
+            MessagesManager messagesManager = new MessagesManager(context,
+                    new MessagesManager.Message(context.getString(R.string.hint_alias)),
+                    new MessagesManager.Message(context.getString(R.string.hint_appgroups)),
+                    new MessagesManager.Message(context.getString(R.string.hint_clear)),
+                    new MessagesManager.Message(context.getString(R.string.hint_config)),
+                    new MessagesManager.Message(context.getString(R.string.hint_disable)),
+                    new MessagesManager.Message(context.getString(R.string.hint_donate)),
+                    new MessagesManager.Message(context.getString(R.string.hint_googlep)),
+                    new MessagesManager.Message(context.getString(R.string.hint_help)),
+                    new MessagesManager.Message(context.getString(R.string.hint_music)),
+                    new MessagesManager.Message(context.getString(R.string.hint_notifications)),
+                    new MessagesManager.Message(context.getString(R.string.hint_telegram)),
+                    new MessagesManager.Message(context.getString(R.string.hint_theme)),
+                    new MessagesManager.Message(context.getString(R.string.hint_theme2)),
+                    new MessagesManager.Message(context.getString(R.string.hint_tutorial)),
+                    new MessagesManager.Message(context.getString(R.string.hint_twitter)),
+                    new MessagesManager.Message(context.getString(R.string.hint_wallpaper)),
+                    new MessagesManager.Message(context.getString(R.string.hint_musicdisable)));
+
+            mTerminalAdapter.setMessagesManager(messagesManager);
         }
     }
 
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 d0033bdb65aaf6242e745849708ab11f8ea8ede0..b208ef03573157c62d96a25d29f71ff855ee10e6 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
@@ -47,13 +47,12 @@ public class Command {
                     return param.onNotArgEnough(info, nArgs);
                 }
             }
-        } else if (nArgs < cmd.minArgs() || (mArgs == null && cmd.minArgs() > 0)) {
-            return cmd.onNotArgEnough(info, nArgs);
-        }
-
-        if(indexNotFound != -1) {
+        } else if(indexNotFound != -1) {
             return cmd.onArgNotFound(info, indexNotFound);
         }
+        else if (nArgs < cmd.minArgs() || (mArgs == null && cmd.minArgs() > 0)) {
+            return cmd.onNotArgEnough(info, nArgs);
+        }
 
         String output = cmd.exec(info);
         info.clear();
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 5a118f18885dec7cde75a5d7314fdb83951e73d7..5fa17a3d50017370e135f723a1e369e9b2a6667a 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
@@ -22,6 +22,7 @@ public interface CommandAbstraction {
     int ALL_PACKAGES = 26;
     int NO_SPACE_STRING = 27;
     int APP_GROUP = 28;
+    int APP_INSIDE_GROUP = 29;
 
     String exec(ExecutePack pack) throws Exception;
 
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 a3cda5a398685d77ddd1fe847456c52d6d8bb1bd..e0e0dd6aeeb4bde146d1ccf25f6f4980f10e6b34 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
@@ -135,6 +135,8 @@ public class CommandTuils {
             return textList(input);
         } else if (type == CommandAbstraction.SONG && info instanceof MainPack) {
             MainPack pack = (MainPack) info;
+            if(pack.player == null) return null;
+
             return song(input, pack.player);
         } else if (type == CommandAbstraction.FILE_LIST && info instanceof MainPack) {
             MainPack pack = (MainPack) info;
@@ -163,6 +165,8 @@ public class CommandTuils {
             return noSpaceString(input);
         } else if(type == CommandAbstraction.APP_GROUP) {
             return noSpaceString(input);
+        } else if(type == CommandAbstraction.APP_INSIDE_GROUP) {
+            return activityName(input, ((MainPack) info).appsManager);
         }
 
         return null;
@@ -393,8 +397,6 @@ public class CommandTuils {
     private static ArgInfo configEntry(String input) {
         int index = input.indexOf(Tuils.SPACE);
 
-        Tuils.log(input);
-
         if(xmlPrefsEntrys == null) {
             xmlPrefsEntrys = new ArrayList<>();
 
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 5fa04a612cb48a9f0e0aafd8ea03aab4f836eb23..6d7f55a63546ae9fb7015be90468123870d0f822 100755
--- 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,13 +1,10 @@
 package ohi.andre.consolelauncher.commands.main;
 
 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.Environment;
 
 import java.io.File;
 import java.lang.reflect.Method;
@@ -19,6 +16,7 @@ import ohi.andre.consolelauncher.managers.AliasManager;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.managers.flashlight.TorchManager;
 import ohi.andre.consolelauncher.managers.music.MusicManager2;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
@@ -42,9 +40,9 @@ public class MainPack extends ExecutePack {
     public Resources res;
 
     //	flashlight
-    public boolean isFlashOn = false, canUseFlash = false;
-    public Camera camera;
-    public Camera.Parameters parameters;
+//    public boolean isFlashOn = false, canUseFlash = false;
+//    public Camera camera;
+//    public Camera.Parameters parameters;
 
     //	internet
     public WifiManager wifi;
@@ -86,7 +84,7 @@ public class MainPack extends ExecutePack {
                     ContactManager c, Reloadable r, CommandExecuter executeCommand, Redirectator redirectator, ShellHolder shellHolder) {
         super(commandGroup);
 
-        this.currentDirectory = Environment.getExternalStorageDirectory();
+        this.currentDirectory = XMLPrefsManager.get(File.class, XMLPrefsManager.Behavior.home_path);
 
         this.shellHolder = shellHolder;
 
@@ -99,7 +97,7 @@ public class MainPack extends ExecutePack {
         this.aliasManager = alMgr;
         this.appsManager = appmgr;
 
-        this.canUseFlash = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
+//        this.canUseFlash = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
 
         this.cmdPrefs = new CommandsPreferences();
 
@@ -143,7 +141,7 @@ public class MainPack extends ExecutePack {
     }
 
     public void destroy() {
-        player.destroy();
+        if(player != null) player.destroy();
         appsManager.onDestroy();
     }
 }
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 e524b514b3115ded38872c59fb9c99fb6424a59b..277e8986f36ae1a47b3dfcd535ecffd8d7bbe89d 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
@@ -72,6 +72,18 @@ public class alias extends ParamCommand {
             public int[] args() {
                 return new int[0];
             }
+        },
+        tutorial {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://github.com/Andre1299/TUI-ConsoleLauncher/wiki/Alias"));
+                return null;
+            }
         };
 
         static Param get(String p) {
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 36bd6e8e3f211e0edc293785e2333fd2e8a37a0b..96f7baeed75bf3b41b9c5a7b5942aaefe7454c82 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
@@ -81,7 +81,7 @@ public class apps extends ParamCommand {
                     AppsManager.LaunchInfo i = pack.get(AppsManager.LaunchInfo.class, 1);
 
                     PackageInfo info = pack.context.getPackageManager().getPackageInfo(i.componentName.getPackageName(), PackageManager.GET_PERMISSIONS | PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES | PackageManager.GET_RECEIVERS);
-                    return AppsManager.AppUtils.format(info);
+                    return AppsManager.AppUtils.format(i, info);
                 } catch (PackageManager.NameNotFoundException e) {
                     return e.toString();
                 }
@@ -175,6 +175,21 @@ public class apps extends ParamCommand {
                 return null;
             }
         },
+        reset {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.VISIBLE_PACKAGE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                AppsManager.LaunchInfo app = pack.get(AppsManager.LaunchInfo.class, 1);
+                app.launchedTimes = 0;
+                ((MainPack) pack).appsManager.writeLaunchTimes(app);
+
+                return null;
+            }
+        },
         mkgp {
             @Override
             public int[] args() {
@@ -286,7 +301,7 @@ public class apps extends ParamCommand {
         rmfromgp {
             @Override
             public int[] args() {
-                return new int[] {CommandAbstraction.APP_GROUP, CommandAbstraction.VISIBLE_PACKAGE};
+                return new int[] {CommandAbstraction.APP_GROUP, CommandAbstraction.APP_INSIDE_GROUP};
             }
 
             @Override
@@ -295,6 +310,18 @@ public class apps extends ParamCommand {
                 AppsManager.LaunchInfo app = pack.get(AppsManager.LaunchInfo.class, 2);
                 return ((MainPack) pack).appsManager.removeAppFromGroup(name, app);
             }
+        },
+        tutorial {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://github.com/Andre1299/TUI-ConsoleLauncher/wiki/Apps"));
+                return null;
+            }
         };
 
         static Param get(String p) {
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
index 60a2da760a269c4c4f2b7e76d8861051dc27bad9..7949a5e2b3668e11d334e8631622620975e2942e 100755
--- 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
@@ -1,13 +1,17 @@
 package ohi.andre.consolelauncher.commands.main.raw;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 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.ParamCommand;
+import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
 /**
@@ -41,7 +45,7 @@ public class config extends ParamCommand {
                 return set.exec(pack);
             }
         },
-        open {
+        file {
             @Override
             public int[] args() {
                 return new int[] {CommandAbstraction.CONFIG_FILE};
@@ -73,6 +77,56 @@ public class config extends ParamCommand {
                 return s;
             }
         },
+        ls {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.CONFIG_FILE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                File file = new File(Tuils.getFolder(), pack.get(String.class, 1));
+                String name = file.getName();
+
+                for(XMLPrefsManager.XMLPrefsRoot r : XMLPrefsManager.XMLPrefsRoot.values()) {
+                    if(name.equalsIgnoreCase(r.path)) {
+                        List<String> strings = r.getValues().values();
+                        Tuils.addPrefix(strings, Tuils.DOUBLE_SPACE);
+                        strings.add(0, r.path);
+                        return Tuils.toPlanString(strings, Tuils.NEWLINE);
+                    }
+                }
+
+                return "[]";
+            }
+
+            @Override
+            public String onArgNotFound(ExecutePack pack, int index) {
+                List<String> ss = new ArrayList<>();
+
+                for(XMLPrefsManager.XMLPrefsRoot element : XMLPrefsManager.XMLPrefsRoot.values()) {
+                    ss.add(element.path);
+                    for(XMLPrefsManager.XMLPrefsSave save : element.copy) {
+                        ss.add(Tuils.DOUBLE_SPACE + save.label());
+                    }
+                }
+                ss.add(AppsManager.PATH);
+                for(XMLPrefsManager.XMLPrefsSave save : AppsManager.Options.values()) {
+                    ss.add(Tuils.DOUBLE_SPACE + save.label());
+                }
+                ss.add(NotificationManager.PATH);
+                for(XMLPrefsManager.XMLPrefsSave save : NotificationManager.Options.values()) {
+                    ss.add(Tuils.DOUBLE_SPACE + save.label());
+                }
+
+                return Tuils.toPlanString(ss);
+            }
+
+            @Override
+            public String onNotArgEnough(ExecutePack pack, int n) {
+                return onArgNotFound(pack, -1);
+            }
+        },
         reset {
             @Override
             public int[] args() {
@@ -85,6 +139,36 @@ public class config extends ParamCommand {
                 save.parent().write(save, save.defaultValue());
                 return null;
             }
+        },
+        apply {
+            @Override
+            public int[] args() {
+                return new int[] {CommandAbstraction.FILE};
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                File file = pack.get(File.class, 1);
+
+                File old = new File(Tuils.getFolder(), file.getName());
+                Tuils.insertOld(old);
+
+                file.renameTo(new File(Tuils.getFolder(), file.getName()));
+
+                return null;
+            }
+        },
+        tutorial {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://github.com/Andre1299/TUI-ConsoleLauncher/wiki/Customize-T_UI"));
+                return null;
+            }
         };
 
         static Param get(String p) {
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/devutils.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/devutils.java
index 26fd109f1f73814d5563ac6929d3c9a709bb07ef..4c143cd7d82b4a60616fc209f9cfe7863e99f815 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/devutils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/devutils.java
@@ -5,6 +5,7 @@ import android.support.v4.app.NotificationManagerCompat;
 
 import java.util.List;
 
+import ohi.andre.consolelauncher.BuildConfig;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
@@ -45,6 +46,17 @@ public class devutils extends ParamCommand {
             public int[] args() {
                 return new int[] {CommandAbstraction.TEXTLIST};
             }
+        },
+        check_notifications {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                return "Notification access: " + NotificationManagerCompat.getEnabledListenerPackages(pack.context).contains(BuildConfig.APPLICATION_ID) + Tuils.NEWLINE + "Notification service running: " + Tuils.notificationServiceIsRunning(pack.context);
+            }
         };
 
         static Param get(String p) {
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
index 22c45d44a5412b164456f013f07fb857a1a55012..592c1f74edf6765092ae67070d742f4625b05121 100755
--- 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
@@ -3,7 +3,6 @@ package ohi.andre.consolelauncher.commands.main.raw;
 import android.Manifest;
 import android.app.Activity;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.location.Location;
 import android.location.LocationListener;
@@ -18,7 +17,7 @@ import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.specific.APICommand;
-import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
+import ohi.andre.consolelauncher.tuils.Tuils;
 
 /**
  * Created by francescoandreuzzi on 10/05/2017.
@@ -28,7 +27,7 @@ public class location extends APICommand {
 
     @Override
     public String exec(final ExecutePack pack) throws Exception {
-        Context context = ((MainPack) pack).context;
+        final 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) {
@@ -44,9 +43,7 @@ public class location extends APICommand {
         LocationListener locationListener = new LocationListener() {
             @Override
             public void onLocationChanged(Location location) {
-                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                intent.putExtra(InputOutputReceiver.TEXT, "Lat: " + location.getLatitude() + "; Long: " + location.getLongitude());
-                pack.context.sendBroadcast(intent);
+                Tuils.sendOutput(context, "Lat: " + location.getLatitude() + "; Long: " + location.getLongitude());
             }
 
             @Override
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/music.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/music.java
index e684d70c1116fdbb382cf2bd67b565b80a251480..e402c36b8331954e604ff0c7b0e3a73a07cf59aa 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/music.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/music.java
@@ -20,6 +20,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 String title = ((MainPack) pack).player.playNext();
                 if(title != null) return pack.context.getString(R.string.output_playing) + Tuils.SPACE + title;
                 return null;
@@ -33,6 +35,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 String title = ((MainPack) pack).player.playPrev();
                 if(title != null) return pack.context.getString(R.string.output_playing) + Tuils.SPACE + title;
                 return null;
@@ -46,6 +50,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 return ((MainPack) pack).player.lsSongs();
             }
         },
@@ -57,6 +63,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 String title = ((MainPack) pack).player.play();
                 if(title == null) return null;
                 return pack.context.getString(R.string.output_playing) + Tuils.SPACE + title;
@@ -70,6 +78,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 ((MainPack) pack).player.stop();
                 return null;
             }
@@ -82,6 +92,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 String s = pack.get(String.class, 1);
                 ((MainPack) pack).player.select(s);
                 return null;
@@ -100,6 +112,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 StringBuilder builder = new StringBuilder();
 
                 MusicManager2 m = ((MainPack) pack).player;
@@ -135,6 +149,8 @@ public class music extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
+                if(((MainPack) pack).player == null) return pack.context.getString(R.string.output_musicdisabled);
+
                 ((MainPack) pack).player.seekTo(pack.get(int.class, 1) * 1000);
                 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
index 4fa7fcb95f7bedd3be86a4b84514d9ccb383af62..a3ab9701d87d1ab5f7876451b8821fd8f24a0666 100755
--- 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
@@ -163,6 +163,18 @@ public class notifications extends ParamCommand {
                 }
                 return null;
             }
+        },
+        tutorial {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://github.com/Andre1299/TUI-ConsoleLauncher/wiki/Notifications"));
+                return null;
+            }
         };
 
         static Param get(String p) {
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 4652f03fc5d6c4f55e825edb4ec586c75311ff95..860d2092062b72562f7e94651442476f4e011586 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
@@ -18,10 +18,8 @@ public class open implements CommandAbstraction {
 
         int result = FileManager.openFile(info.context, file);
 
-        if (result == FileManager.ISDIRECTORY)
-            return info.res.getString(R.string.output_isdirectory);
-        if (result == FileManager.IOERROR)
-            return info.res.getString(R.string.output_error);
+        if (result == FileManager.ISDIRECTORY) return info.res.getString(R.string.output_isdirectory);
+        if (result == FileManager.IOERROR) return info.res.getString(R.string.output_error);
 
         return Tuils.EMPTYSTRING;
     }
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 78d761edd23afd56a5d4d0630275ecae37ce4234..8f7d63c284489440a4d5536feb030b1cf56073dc 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
@@ -12,7 +12,7 @@ public class refresh implements CommandAbstraction {
         MainPack info = (MainPack) pack;
         info.appsManager.fill();
         info.aliasManager.reload();
-        info.player.refresh();
+        if(info.player != null) info.player.refresh();
         info.contacts.refreshContacts(info.context);
 
         return info.res.getString(R.string.output_refresh);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/theme.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/theme.java
index fc05a0eebe2a04d813b293f8b908319d32b2948c..a1248c4c79f51751ad07ce4bb3a2e00897f59508 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/theme.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/theme.java
@@ -1,10 +1,13 @@
 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.MainPack;
 import ohi.andre.consolelauncher.commands.specific.ParamCommand;
+import ohi.andre.consolelauncher.managers.ThemesManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
 /**
@@ -23,11 +26,9 @@ public class theme extends ParamCommand {
 
             @Override
             public String exec(ExecutePack pack) {
-                return "Hehehehe you wanted! Wait some days...";
-
-//                String theme = pack.get(String.class, 1);
-//                ThemesManager.apply(pack.context, theme);
-//                return null;
+                String theme = pack.get(String.class, 1);
+                ThemesManager.apply(pack.context, theme);
+                return null;
             }
         },
         view {
@@ -53,6 +54,55 @@ public class theme extends ParamCommand {
                 pack.context.startActivity(Tuils.webPage("http://tui-launcher.surge.sh/create"));
                 return null;
             }
+        },
+        ls {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                ThemesManager.ls(pack.context);
+                return null;
+            }
+        },
+        old {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                File theme = Tuils.getOld("theme.xml");
+                File suggestions = Tuils.getOld("suggestions.xml");
+
+                if(theme == null || suggestions == null) return pack.context.getString(R.string.theme_old_not_found);
+
+                File themeDest = new File(Tuils.getFolder(), "theme.xml");
+                File suggestionsDest = new File(Tuils.getFolder(), "suggestions.xml");
+
+                if(themeDest.exists()) themeDest.delete();
+                if(suggestionsDest.exists()) suggestionsDest.delete();
+
+                theme.renameTo(themeDest);
+                suggestions.renameTo(suggestionsDest);
+
+                return pack.context.getString(R.string.theme_reverted);
+            }
+        },
+        tutorial {
+            @Override
+            public int[] args() {
+                return new int[0];
+            }
+
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://github.com/Andre1299/TUI-ConsoleLauncher/wiki/Themes"));
+                return null;
+            }
         };
 
         static Param get(String p) {
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
index 78e1f40186c063bb47d49545fa7e5bf75f4d8837..3ed9d11e19e4930a1b248c7b1c85e671a14b83f7 100755
--- 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
@@ -89,7 +89,25 @@ public class tui extends ParamCommand {
 
                 return null;
             }
-        };
+        }
+//        ,
+//        exclude_message {
+//            @Override
+//            public int[] args() {
+//                return new int[] {CommandAbstraction.INT};
+//            }
+//
+//            @Override
+//            public String exec(ExecutePack pack) {
+//                return null;
+//            }
+//
+//            @Override
+//            public String onNotArgEnough(ExecutePack pack, int n) {
+//
+//            }
+//        }
+        ;
 
         @Override
         public int[] args() {
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 55a1e7726b875c5ec7113ad53b9e4e475427f4ae..14758b9c3468c915c2c358d663a3f669d28b7b5e 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
@@ -1,7 +1,7 @@
 package ohi.andre.consolelauncher.managers;
 
 import android.content.Context;
-import android.content.Intent;
+import android.graphics.Color;
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
@@ -19,7 +19,6 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.Reloadable;
 
@@ -151,13 +150,11 @@ public class AliasManager implements Reloadable {
                 value = value.trim();
 
                 if(name.equalsIgnoreCase(value)) {
-                    Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                    intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.output_notaddingalias1) + Tuils.SPACE + name + Tuils.SPACE + context.getString(R.string.output_notaddingalias2));
-                    context.sendBroadcast(intent);
+                    Tuils.sendOutput(Color.RED, context,
+                            context.getString(R.string.output_notaddingalias1) + Tuils.SPACE + name + Tuils.SPACE + context.getString(R.string.output_notaddingalias2));
                 } else if(value.startsWith(name + Tuils.SPACE)) {
-                    Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                    intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.output_notaddingalias1) + Tuils.SPACE + name + Tuils.SPACE + context.getString(R.string.output_notaddingalias3));
-                    context.sendBroadcast(intent);
+                    Tuils.sendOutput(Color.RED, context,
+                            context.getString(R.string.output_notaddingalias1) + Tuils.SPACE + name + Tuils.SPACE + context.getString(R.string.output_notaddingalias3));
                 } else {
                     aliases.put(name, value);
                 }
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 6e7a87a4960e894cc8ff45320e52479ed363de6b..177a104fe0713a146ce082eba915a324aa4a7d1e 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
@@ -33,7 +33,6 @@ import ohi.andre.consolelauncher.MainManager;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.tuils.Compare;
-import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
 import ohi.andre.consolelauncher.tuils.TimeManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.Suggester;
@@ -73,6 +72,10 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
 
     public static List<Group> groups;
 
+    private Pattern pp, pl, pn;
+    private String appInstalledFormat, appUninstalledFormat;
+    int appInstalledColor, appUninstalledColor;
+
     public enum Options implements XMLPrefsManager.XMLPrefsSave {
 
         default_app_n1 {
@@ -159,6 +162,22 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
 
         this.context = context;
 
+        appInstalledFormat = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_app_installed) ? XMLPrefsManager.get(XMLPrefsManager.Behavior.app_installed_format) : null;
+        appUninstalledFormat = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_app_uninstalled) ? XMLPrefsManager.get(XMLPrefsManager.Behavior.app_uninstalled_format) : null;
+
+        if(appInstalledFormat != null || appUninstalledFormat != null) {
+            pp = Pattern.compile("%p", Pattern.CASE_INSENSITIVE);
+            pl = Pattern.compile("%l", Pattern.CASE_INSENSITIVE);
+            pn = Pattern.compile("%n", Pattern.CASE_INSENSITIVE);
+
+            appInstalledColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.app_installed_color);
+            appUninstalledColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.app_uninstalled_color);
+        } else {
+            pp = null;
+            pl = null;
+            pn = null;
+        }
+
         this.file = new File(Tuils.getFolder(), PATH);
 
         this.preferences = context.getSharedPreferences(PREFS, 0);
@@ -205,12 +224,8 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
             try {
                 o = XMLPrefsManager.buildDocument(file, NAME);
             } catch (Exception e) {
-                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.output_xmlproblem1) + Tuils.SPACE + NAME + context.getString(R.string.output_xmlproblem2) +
-                        Tuils.NEWLINE + context.getString(R.string.output_errorlabel) + e.toString());
-                intent.putExtra(InputOutputReceiver.COLOR, Color.parseColor("#ff0000"));
-                context.sendBroadcast(intent);
-
+                Tuils.sendOutput(Color.RED, context, context.getString(R.string.output_xmlproblem1) + Tuils.SPACE + PATH + context.getString(R.string.output_xmlproblem2) +
+                                Tuils.NEWLINE + context.getString(R.string.output_errorlabel) + e.toString());
                 return;
             }
 
@@ -243,10 +258,7 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
                         if(e.hasAttribute(APPS_ATTRIBUTE)) {
                             final String name = e.getNodeName();
                             if(name.contains(Tuils.SPACE)) {
-                                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                                intent.putExtra(InputOutputReceiver.TEXT, PATH + ": " + context.getString(R.string.output_groupspace) + ": " + name);
-                                intent.putExtra(InputOutputReceiver.COLOR, Color.parseColor("#ff0000"));
-                                context.sendBroadcast(intent);
+                                Tuils.sendOutput(Color.RED, context, PATH + ": " + context.getString(R.string.output_groupspace) + ": " + name);
                                 continue;
                             }
 
@@ -278,10 +290,7 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
                                             try {
                                                 g.setBgColor(Color.parseColor(c));
                                             } catch (Exception e) {
-                                                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                                                intent.putExtra(InputOutputReceiver.TEXT, PATH + ": " + context.getString(R.string.output_invalidcolor) + ": " + c);
-                                                intent.putExtra(InputOutputReceiver.COLOR, Color.parseColor("#ff0000"));
-                                                context.sendBroadcast(intent);
+                                                Tuils.sendOutput(Color.RED, context, PATH + ": " + context.getString(R.string.output_invalidcolor) + ": " + c);
                                             }
                                         }
                                     }
@@ -292,10 +301,7 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
                                             try {
                                                 g.setForeColor(Color.parseColor(c));
                                             } catch (Exception e) {
-                                                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                                                intent.putExtra(InputOutputReceiver.TEXT, PATH + ": " + context.getString(R.string.output_invalidcolor) + ": " + c);
-                                                intent.putExtra(InputOutputReceiver.COLOR, Color.parseColor("#ff0000"));
-                                                context.sendBroadcast(intent);
+                                                Tuils.sendOutput(Color.RED, context, PATH + ": " + context.getString(R.string.output_invalidcolor) + ": " + c);
                                             }
                                         }
                                     }
@@ -410,6 +416,28 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
         try {
             PackageManager manager = context.getPackageManager();
 
+            PackageInfo packageInfo = manager.getPackageInfo(packageName, 0);
+
+            if(appInstalledFormat != null) {
+                String cp = appInstalledFormat;
+
+                cp = pp.matcher(cp).replaceAll(packageName);
+                if(packageInfo != null) {
+                    CharSequence sequence = packageInfo.applicationInfo.loadLabel(manager);
+                    if(sequence != null) cp = pl.matcher(cp).replaceAll(sequence.toString());
+                } else {
+                    int index = packageName.lastIndexOf(Tuils.DOT);
+                    if(index == -1) cp = pl.matcher(cp).replaceAll(Tuils.EMPTYSTRING);
+                    else {
+                        cp = pl.matcher(cp).replaceAll(packageName.substring(index + 1));
+                    }
+                }
+
+                cp = pn.matcher(cp).replaceAll(Tuils.NEWLINE);
+
+                Tuils.sendOutput(appInstalledColor, context, cp);
+            }
+
             Intent i = manager.getLaunchIntentForPackage(packageName);
             if(i == null) return;
 
@@ -419,21 +447,32 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
 
             LaunchInfo app = new LaunchInfo(packageName, activity, label);
             appsHolder.add(app);
-
-            Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-            intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.app_installed) + Tuils.SPACE + packageName);
-            context.sendBroadcast(intent);
         } catch (Exception e) {}
     }
 
     private void appUninstalled(String packageName) {
         if(appsHolder == null || context == null) return;
 
-        Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-        intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.app_uninstalled) + Tuils.SPACE + packageName);
-        context.sendBroadcast(intent);
-
         List<LaunchInfo> infos = AppUtils.findLaunchInfosWithPackage(packageName, appsHolder.getApps());
+
+        if(appUninstalledFormat != null) {
+            String cp = appUninstalledFormat;
+
+            cp = pp.matcher(cp).replaceAll(packageName);
+            if(infos.size() > 0) {
+                cp = pl.matcher(cp).replaceAll(infos.get(0).publicLabel);
+            } else {
+                int index = packageName.lastIndexOf(Tuils.DOT);
+                if(index == -1) cp = pl.matcher(cp).replaceAll(Tuils.EMPTYSTRING);
+                else {
+                    cp = pl.matcher(cp).replaceAll(packageName.substring(index + 1));
+                }
+            }
+            cp = pn.matcher(cp).replaceAll(Tuils.NEWLINE);
+
+            Tuils.sendOutput(appUninstalledColor, context, cp);
+        }
+
         for(LaunchInfo i : infos) appsHolder.remove(i);
     }
 
@@ -448,17 +487,23 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
         return AppUtils.findLaunchInfoWithLabel(appList, label);
     }
 
-    public Intent getIntent(LaunchInfo info) {
-        info.launchedTimes++;
-        appsHolder.requestSuggestionUpdate(info);
-
-        editor.putInt(info.componentName.getPackageName() + "-" + info.componentName.getClassName(), info.launchedTimes);
+    public void writeLaunchTimes(LaunchInfo info) {
+        editor.putInt(info.write(), info.launchedTimes);
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
             editor.apply();
         } else {
             editor.commit();
         }
 
+        if(appsHolder != null) appsHolder.update(true);
+    }
+
+    public Intent getIntent(LaunchInfo info) {
+        info.launchedTimes++;
+        appsHolder.requestSuggestionUpdate(info);
+
+        writeLaunchTimes(info);
+
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.setComponent(info.componentName);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -488,14 +533,32 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
     }
 
     public String createGroup(String name) {
-        return XMLPrefsManager.set(file, NAME, name, new String[]{APPS_ATTRIBUTE}, new String[]{Tuils.EMPTYSTRING});
+        int index = Tuils.find(name, groups);
+        if(index == -1) {
+            groups.add(new Group(name));
+            return XMLPrefsManager.set(file, NAME, name, new String[]{APPS_ATTRIBUTE}, new String[]{Tuils.EMPTYSTRING});
+        }
+
+        return context.getString(R.string.output_groupexists);
     }
 
     public String groupBgColor(String name, String color) {
+        int index = Tuils.find(name, groups);
+        if(index == -1) {
+            return context.getString(R.string.output_groupnotfound);
+        }
+
+        groups.get(index).setBgColor(Color.parseColor(color));
         return XMLPrefsManager.set(file, NAME, name, new String[]{BGCOLOR_ATTRIBUTE}, new String[]{color});
     }
 
     public String groupForeColor(String name, String color) {
+        int index = Tuils.find(name, groups);
+        if(index == -1) {
+            return context.getString(R.string.output_groupnotfound);
+        }
+
+        groups.get(index).setForeColor(Color.parseColor(color));
         return XMLPrefsManager.set(file, NAME, name, new String[]{FORECOLOR_ATTRIBUTE}, new String[]{color});
     }
 
@@ -504,6 +567,10 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
 
         if(output == null) return null;
         if(output.length() == 0) return context.getString(R.string.output_groupnotfound);
+
+        int index = Tuils.find(name, groups);
+        if(index != -1) groups.remove(index);
+
         return output;
     }
 
@@ -532,6 +599,10 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
         e.setAttribute(APPS_ATTRIBUTE, apps);
 
         XMLPrefsManager.writeTo(d, file);
+
+        int index = Tuils.find(group, groups);
+        if(index != -1) groups.get(index).add(app);
+
         return null;
     }
 
@@ -567,6 +638,10 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
         e.setAttribute(APPS_ATTRIBUTE, apps);
 
         XMLPrefsManager.writeTo(d, file);
+
+        int index = Tuils.find(group, groups);
+        if(index != -1) groups.get(index).remove(app);
+
         return null;
     }
 
@@ -646,6 +721,7 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
     }
 
     public List<LaunchInfo> shownApps() {
+        if(appsHolder == null) return new ArrayList<>();
         return appsHolder.getApps();
     }
 
@@ -692,6 +768,10 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
             apps.add(info);
         }
 
+        public void remove(LaunchInfo info) {
+            apps.remove(info);
+        }
+
         public boolean contains(LaunchInfo info) {
             return apps.contains(info);
         }
@@ -1198,11 +1278,12 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
             }
         }
 
-        public static String format(PackageInfo info) {
+        public static String format(LaunchInfo app, PackageInfo info) {
             StringBuilder builder = new StringBuilder();
 
             builder.append(info.packageName).append(Tuils.NEWLINE);
             builder.append("vrs: ").append(info.versionCode).append(" - ").append(info.versionName).append(Tuils.NEWLINE).append(Tuils.NEWLINE);
+            builder.append("launched_times: ").append(app.launchedTimes).append(Tuils.NEWLINE).append(Tuils.NEWLINE);
 
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
                 builder.append("Install: ").append(TimeManager.replace("%t0", info.firstInstallTime, SkinManager.COLOR_NOT_SET)).append(Tuils.NEWLINE).append(Tuils.NEWLINE);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/MessagesManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/MessagesManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..b883180525fbb57b1445135db2d81b9277596883
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/MessagesManager.java
@@ -0,0 +1,71 @@
+package ohi.andre.consolelauncher.managers;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+/**
+ * Created by francescoandreuzzi on 31/08/2017.
+ */
+
+public class MessagesManager {
+
+    final String MARKER = "---------------";
+
+    final int REACH_THIS = 20;
+
+    List<Message> original;
+    List<Message> copy;
+
+    int count;
+    Random random;
+
+    Context context;
+    int color;
+
+    public MessagesManager(Context context, Message... ms) {
+        this.context = context;
+
+        original = new ArrayList<>();
+        for(Message m : ms) original.add(m);
+        copy = new ArrayList<>(original);
+
+        count = 0;
+        random = new Random();
+
+        color = XMLPrefsManager.getColor(XMLPrefsManager.Theme.hint_color);
+    }
+
+    public void onCmd() {
+        count++;
+
+        if(count == REACH_THIS) {
+            count = 0;
+
+            if(copy.size() == 0) {
+                copy = new ArrayList<>(original);
+                random = new Random();
+            }
+
+            int index = random.nextInt(copy.size());
+            if(copy.size() <= index) {
+                return;
+            }
+
+            Tuils.sendOutput(color, context, MARKER + Tuils.NEWLINE + copy.remove(index).msg + Tuils.NEWLINE + MARKER);
+        }
+    }
+
+    public static class Message {
+        String msg;
+//        more coming
+
+        public Message(String msg) {
+            this.msg = msg;
+        }
+    }
+}
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 540982504b2b47bd775a71403b370196210f64bc..4708be10ba65f99b339d16798a6613d6a346c0a1 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
@@ -162,7 +162,7 @@ public class SkinManager implements Parcelable {
             return new ColorDrawable(Color.TRANSPARENT);
         } else {
             switch (type) {
-                case SuggestionsManager.Suggestion.TYPE_APP:case SuggestionsManager.Suggestion.TYPE_APPGROUP:
+                case SuggestionsManager.Suggestion.TYPE_APP:
                     return new ColorDrawable(suggAppBg);
                 case SuggestionsManager.Suggestion.TYPE_ALIAS:
                     return new ColorDrawable(suggAliasBg);
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 ea9a8b8d06b33af5ac9613f461a92c94d1cc7b7d..09d2a940eac0297b0d58c4920db7d022bf1e7861 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalManager.java
@@ -66,6 +66,8 @@ public class TerminalManager {
     private TextView mPrefix;
     private boolean suMode;
 
+    private MessagesManager messagesManager;
+
     private List<String> cmdList = new ArrayList<>(CMD_LIST_SIZE);
     private int howBack = -1;
 
@@ -80,15 +82,13 @@ public class TerminalManager {
     private SkinManager mSkinManager;
 
     private UIManager.OnNewInputListener mInputListener;
-    private UIManager.SuggestionNavigator mSuggestionNavigator;
-
-    private List<Messager> messagers = new ArrayList<>();
+//    private UIManager.SuggestionNavigator mSuggestionNavigator;
 
     private MainPack mainPack;
 
     private boolean defaultHint = true;
 
-    private int clearCmdsCount= 0, messagesCmdsCount = 0;
+    private int clearCmdsCount= 0;
 
     private int clearAfterCmds, clearAfterMs, maxLines;
     private Runnable clearRunnable = new Runnable() {
@@ -267,10 +267,6 @@ public class TerminalManager {
         });
     }
 
-    public void addMessager(Messager messager) {
-        messagers.add(messager);
-    }
-
     private void setupNewInput() {
         mInputView.setText(Tuils.EMPTYSTRING);
 
@@ -290,11 +286,10 @@ public class TerminalManager {
 
         if(input.length() > 0) {
             clearCmdsCount++;
-            messagesCmdsCount++;
 
             if(clearCmdsCount != 0 && clearAfterCmds > 0 && clearCmdsCount % clearAfterCmds == 0) clear();
 
-            for (Messager messager : messagers) if (messagesCmdsCount != 0 && messagesCmdsCount % messager.n == 0) writeToView(messager.message, CATEGORY_OUTPUT);
+            if(messagesManager != null) messagesManager.onCmd();
 
             writeToView(input, CATEGORY_INPUT);
 
@@ -396,7 +391,6 @@ public class TerminalManager {
     }
 
     private CharSequence getFinalText(CharSequence t, int type) {
-
         CharSequence s;
         switch (type) {
             case CATEGORY_INPUT:
@@ -404,8 +398,7 @@ public class TerminalManager {
 
                 boolean su = t.toString().startsWith("su ") || suMode;
 
-                SpannableString si = new SpannableString(inputFormat);
-                si.setSpan(new ForegroundColorSpan(mSkinManager.inputColor), 0, inputFormat.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                SpannableString si = Tuils.color(inputFormat, mSkinManager.inputColor);
 
                 s = TimeManager.replace(si, mSkinManager.time_color);
                 s = TextUtils.replace(s,
@@ -417,8 +410,7 @@ public class TerminalManager {
             case CATEGORY_OUTPUT:
                 t = t.toString().trim();
 
-                SpannableString so = new SpannableString(outputFormat);
-                so.setSpan(new ForegroundColorSpan(mSkinManager.outputColor), 0, outputFormat.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                SpannableString so = Tuils.color(outputFormat, mSkinManager.outputColor);
 
                 s = TextUtils.replace(so,
                         new String[] {FORMAT_OUTPUT, FORMAT_NEWLINE, FORMAT_OUTPUT.toUpperCase(), FORMAT_NEWLINE.toUpperCase()},
@@ -468,13 +460,17 @@ public class TerminalManager {
         }
     }
 
+    public void setMessagesManager(MessagesManager msg) {
+        this.messagesManager = msg;
+    }
+
     public void setInputListener(UIManager.OnNewInputListener listener) {
         this.mInputListener = listener;
     }
 
-    public void setSuggestionNavigator(UIManager.SuggestionNavigator navigator) {
-        this.mSuggestionNavigator = navigator;
-    }
+//    public void setSuggestionNavigator(UIManager.SuggestionNavigator navigator) {
+//        this.mSuggestionNavigator = navigator;
+//    }
 
     public void focusInputEnd() {
         mInputView.setSelection(getInput().length());
@@ -533,15 +529,4 @@ public class TerminalManager {
         };
     }
 
-    public static class Messager {
-
-        int n;
-        String message;
-
-        public Messager(int n, String message) {
-            this.n = n;
-            this.message = message;
-        }
-    }
-
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/ThemesManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/ThemesManager.java
index 565aeea1f42d60221fbaf8bd2cd14a19994e503a..46509c6629ac44115af09fac51359ebe05200873 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/ThemesManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/ThemesManager.java
@@ -1,10 +1,10 @@
 package ohi.andre.consolelauncher.managers;
 
 import android.content.Context;
-import android.content.Intent;
 
 import com.google.firebase.database.DataSnapshot;
 import com.google.firebase.database.DatabaseError;
+import com.google.firebase.database.DatabaseReference;
 import com.google.firebase.database.FirebaseDatabase;
 import com.google.firebase.database.ValueEventListener;
 
@@ -12,15 +12,13 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
 import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
 /**
@@ -29,18 +27,10 @@ import ohi.andre.consolelauncher.tuils.Tuils;
 
 public class ThemesManager {
 
-    static DocumentBuilderFactory factory;
-    static DocumentBuilder builder;
-
-    static {
-        factory = DocumentBuilderFactory.newInstance();
-        try {
-            builder = factory.newDocumentBuilder();
-        } catch (ParserConfigurationException e) {}
-    }
-
     public static void apply(final Context context, final String name) {
-        FirebaseDatabase.getInstance().getReference().addListenerForSingleValueEvent(new ValueEventListener() {
+        final DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
+
+        reference.addListenerForSingleValueEvent(new ValueEventListener() {
             @Override
             public void onDataChange(DataSnapshot dataSnapshot) {
 
@@ -53,30 +43,85 @@ public class ThemesManager {
                     String themePath = currentTheme.getAbsolutePath();
                     String suggestionsPath = currentSuggestions.getAbsolutePath();
 
-                    File old = new File(Tuils.getFolder(), "old");
-                    if(old.exists()) Tuils.delete(old);
-                    old.mkdir();
-
-                    currentTheme.renameTo(new File(old, "theme.xml"));
-                    currentSuggestions.renameTo(new File(old, "suggestions.xml"));
+                    Tuils.insertOld(currentTheme);
+                    Tuils.insertOld(currentSuggestions);
+
+                    Object o;
+
+                    String author = Tuils.EMPTYSTRING;
+                    if(theme.hasChild("author")) {
+                        o = theme.child("author").getValue();
+                        if(o != null) {
+                            author = o.toString();
+                        }
+                    }
+
+                    if(theme.hasChild("downloads")) {
+                        o = theme.child("downloads").getValue();
+                        if (o != null) {
+                            try {
+                                long downloads = Long.parseLong(o.toString());
+                                reference.child("themes").child(name).child("downloads").setValue(downloads + 1);
+                            } catch (Exception e) {
+                                Tuils.log(e);
+                            }
+                        }
+                    }
 
                     theme = theme.child("files");
+                    if(theme == null || !theme.exists()) {
+                        Tuils.sendOutput(context, R.string.theme_invalid);
+                        return;
+                    }
+
                     DataSnapshot t = theme.child("THEME");
                     DataSnapshot s = theme.child("SUGGESTIONS");
 
+                    if(t == null || !t.exists() || s == null || !s.exists()) {
+                        Tuils.sendOutput(context, R.string.theme_invalid);
+                        return;
+                    }
+
                     createFile(themePath, "THEME", t);
                     createFile(suggestionsPath, "SUGGESTIONS", s);
 
-                    Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                    intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.theme_done));
-                    context.sendBroadcast(intent);
+                    Tuils.sendOutput(context, "Applied theme " + name + (author.length() > 0 ? " by " + author : Tuils.EMPTYSTRING));
                 } else {
-                    Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                    intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.theme_not_found));
-                    context.sendBroadcast(intent);
+                    Tuils.sendOutput(context, R.string.theme_not_found);
                 }
             }
 
+            @Override
+            public void onCancelled(DatabaseError databaseError) {
+                Tuils.sendOutput(context, databaseError.getMessage());
+            }
+        });
+    }
+
+    public static void ls(final Context context) {
+        FirebaseDatabase.getInstance().getReference().addListenerForSingleValueEvent(new ValueEventListener() {
+
+            @Override
+            public void onDataChange(DataSnapshot dataSnapshot) {
+                List<String> strings = new ArrayList<>();
+
+                DataSnapshot themes = dataSnapshot.child("themes");
+                for(DataSnapshot s : themes.getChildren()) {
+                    String name = s.getKey();
+                    if(name.startsWith("custom_theme")) continue;
+
+                    strings.add(s.getKey());
+                }
+
+                Collections.sort(strings);
+                Tuils.addPrefix(strings, Tuils.DOUBLE_SPACE);
+                Tuils.insertHeaders(strings, false);
+
+                Tuils.log(strings.toString());
+
+                Tuils.sendOutput(context, Tuils.toPlanString(strings, Tuils.NEWLINE));
+            }
+
             @Override
             public void onCancelled(DatabaseError databaseError) {}
         });
@@ -84,24 +129,31 @@ public class ThemesManager {
 
     private static Pattern rgbaExtractor = Pattern.compile("rgba\\(([0-9]+),([0-9]+),([0-9]+),([0-9]+)\\)");
 
-    private static void createFile(String path, String root, DataSnapshot s) {
+    private static void createFile(String path, String r, DataSnapshot s) {
         File file = new File(path);
-        XMLPrefsManager.resetFile(file, root);
+        XMLPrefsManager.resetFile(file, r);
 
         try {
-            Document document = builder.parse(file);
-            Element r = (Element) document.getElementsByTagName(root).item(0);
+            Object[] o;
+            try {
+                o = XMLPrefsManager.buildDocument(file, r);
+            } catch (Exception e) {
+                return;
+            }
+
+            Document d = (Document) o[0];
+            Element root = (Element) o[1];
 
             for(DataSnapshot ds : s.getChildren()) {
                 String value = ds.getValue().toString();
                 if(value.startsWith("rgba(")) value = rgbaToHex(value);
 
-                Element em = document.createElement(ds.getKey());
+                Element em = d.createElement(ds.getKey());
                 em.setAttribute(XMLPrefsManager.VALUE_ATTRIBUTE, value);
-                r.appendChild(em);
+                root.appendChild(em);
             }
 
-            XMLPrefsManager.writeTo(document, file);
+            XMLPrefsManager.writeTo(d, file);
 
         } catch (Exception e) {
             Tuils.log(e);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
index f86d92a50959c56165a31d9802b0891857e58584..d68c60f2bfdce9e35229c76a5dd77425381609ed 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
@@ -1,8 +1,8 @@
 package ohi.andre.consolelauncher.managers;
 
 import android.content.Context;
-import android.content.Intent;
 import android.graphics.Color;
+import android.os.Environment;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -26,7 +26,6 @@ import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
 public class XMLPrefsManager {
@@ -154,6 +153,24 @@ public class XMLPrefsManager {
             public String defaultValue() {
                 return "#000000";
             }
+        },
+        app_installed_color {
+            @Override
+            public String defaultValue() {
+                return "#FF7043";
+            }
+        },
+        app_uninstalled_color {
+            @Override
+            public String defaultValue() {
+                return "#FF7043";
+            }
+        },
+        hint_color {
+            @Override
+            public String defaultValue() {
+                return "#4CAF50";
+            }
         };
 
         @Override
@@ -329,6 +346,18 @@ public class XMLPrefsManager {
             public String defaultValue() {
                 return "false";
             }
+        },
+        show_app_installed {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
+        },
+        show_app_uninstalled {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
         };
 
         @Override
@@ -555,7 +584,7 @@ public class XMLPrefsManager {
                 return "true";
             }
         },
-        donation_message {
+        show_hints {
             @Override
             public String defaultValue() {
                 return "true";
@@ -576,7 +605,7 @@ public class XMLPrefsManager {
         clear_after_cmds {
             @Override
             public String defaultValue() {
-                return "20";
+                return "-1";
             }
         },
         clear_after_seconds {
@@ -588,7 +617,7 @@ public class XMLPrefsManager {
         max_lines {
             @Override
             public String defaultValue() {
-                return "300";
+                return "-1";
             }
         },
         time_format {
@@ -692,6 +721,42 @@ public class XMLPrefsManager {
             public String defaultValue() {
                 return "%a --> [%v]";
             }
+        },
+        external_storage_path {
+            @Override
+            public String defaultValue() {
+                String path = System.getenv("SECONDARY_STORAGE");
+                if(path == null) return Tuils.EMPTYSTRING;
+
+                File file = new File(path);
+                if(file != null && file.exists()) return file.getAbsolutePath();
+
+                return Tuils.EMPTYSTRING;
+            }
+        },
+        home_path {
+            @Override
+            public String defaultValue() {
+                return Environment.getExternalStorageDirectory().getAbsolutePath();
+            }
+        },
+        app_installed_format {
+            @Override
+            public String defaultValue() {
+                return "App installed: %p";
+            }
+        },
+        app_uninstalled_format {
+            @Override
+            public String defaultValue() {
+                return "App uninstalled: %p";
+            }
+        },
+        enable_music {
+            @Override
+            public String defaultValue() {
+                return "true";
+            }
         };
 
         @Override
@@ -758,13 +823,13 @@ public class XMLPrefsManager {
         UI("ui.xml", Ui.values()) {
             @Override
             public String[] deleted() {
-                return new String[] {"show_timestamp_before_cmd", "linux_like", "show_username_ssninfo", "show_ssninfo", "show_path_ssninfo", "show_devicename_ssninfo", "show_alias_suggestions"};
+                return new String[] {"show_timestamp_before_cmd", "linux_like", "show_username_ssninfo", "show_ssninfo", "show_path_ssninfo", "show_devicename_ssninfo", "show_alias_suggestions", "transparent_bars"};
             }
         },
         BEHAVIOR("behavior.xml", Behavior.values()) {
             @Override
             public String[] deleted() {
-                return new String[] {"double_tap_closes"};
+                return new String[] {"double_tap_closes", "donation_message"};
             }
         },
         SUGGESTIONS("suggestions.xml", Suggestions.values()) {
@@ -859,7 +924,7 @@ public class XMLPrefsManager {
 
         public List<String> values() {
             List<String> vs = new ArrayList<>();
-            for(XMLPrefsEntry entry : list) vs.add(entry.value);
+            for(XMLPrefsEntry entry : list) vs.add(entry.key + "=" + entry.value);
             return vs;
         }
     }
@@ -879,12 +944,8 @@ public class XMLPrefsManager {
             try {
                 o = buildDocument(file, element.name());
             } catch (Exception e) {
-                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.output_xmlproblem1) + Tuils.SPACE + element.name() + context.getString(R.string.output_xmlproblem2) +
+                Tuils.sendOutput(Color.RED, context, context.getString(R.string.output_xmlproblem1) + Tuils.SPACE + element.path + context.getString(R.string.output_xmlproblem2) +
                         Tuils.NEWLINE + context.getString(R.string.output_errorlabel) + e.toString());
-                intent.putExtra(InputOutputReceiver.COLOR, Color.parseColor("#ff0000"));
-                context.sendBroadcast(intent);
-
                 continue;
             }
 
@@ -953,6 +1014,14 @@ public class XMLPrefsManager {
         if(c == Color.class) return Color.parseColor(s);
         if(c == boolean.class) return Boolean.parseBoolean(s);
         if(c == String.class) return s;
+        if(c == File.class) {
+            if(s.length() == 0) return null;
+
+            File file = new File(s);
+            if(!file.exists()) throw new UnsupportedOperationException();
+
+            return file;
+        }
 
         return Tuils.getDefaultValue(c);
     }
@@ -1188,6 +1257,10 @@ public class XMLPrefsManager {
         return null;
     }
 
+    public static String get(XMLPrefsManager.XMLPrefsSave prefsSave) {
+        return get(String.class, prefsSave);
+    }
+
     public static int getColor(XMLPrefsManager.XMLPrefsSave prefsSave) {
         try {
             return (int) transform(prefsSave.parent().getValues().get(prefsSave).value, Color.class);
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
index 7842f2a9b045c482aab6fcecaba9f485e11082af..80bda6240f7c591c75e1e06de9d9bda750509149 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationManager.java
@@ -2,7 +2,6 @@ package ohi.andre.consolelauncher.managers.notifications;
 
 import android.annotation.TargetApi;
 import android.content.Context;
-import android.content.Intent;
 import android.graphics.Color;
 import android.os.Build;
 import android.util.SparseArray;
@@ -22,10 +21,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.regex.Pattern;
 
-import ohi.andre.consolelauncher.BuildConfig;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
-import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
 import static ohi.andre.consolelauncher.managers.XMLPrefsManager.VALUE_ATTRIBUTE;
@@ -128,11 +125,14 @@ public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
     private NotificationManager() {}
 
     public static void create(Context context) {
-        instance = new NotificationManager();
 
-        if(created) return;
+        if(created) {
+            return;
+        }
         created = true;
 
+        instance = new NotificationManager();
+
         apps = new ArrayList<>();
         groups = new ArrayList<>();
         applies = new SparseArray<>();
@@ -148,12 +148,8 @@ public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
             try {
                 o = XMLPrefsManager.buildDocument(file, NAME);
             } catch (Exception e) {
-                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
-                intent.putExtra(InputOutputReceiver.TEXT, context.getString(R.string.output_xmlproblem1) + Tuils.SPACE + NAME + context.getString(R.string.output_xmlproblem2) +
+                Tuils.sendOutput(Color.RED, context, context.getString(R.string.output_xmlproblem1) + Tuils.SPACE + PATH + context.getString(R.string.output_xmlproblem2) +
                         Tuils.NEWLINE + context.getString(R.string.output_errorlabel) + e.toString());
-                intent.putExtra(InputOutputReceiver.COLOR, Color.parseColor("#ff0000"));
-                context.sendBroadcast(intent);
-
                 return;
             }
 
@@ -301,7 +297,7 @@ public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
     }
 
     public static boolean match(String pkg, String text, String title) {
-        if(pkg.equals(BuildConfig.APPLICATION_ID)) return true;
+//        if(pkg.equals(BuildConfig.APPLICATION_ID)) return true;
 
         for(FilterGroup group : groups) {
 
@@ -435,6 +431,8 @@ public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
                     textCount++;
                 }
 
+                if(s == null) continue;
+
                 boolean b = filter.pattern.matcher(s).find();
 
                 if(filter.on == TITLE) matchTitle = matchTitle || b;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationMonitorService.java b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationMonitorService.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb0e08ca4d50556f2f5992c7e2a73903cf780145
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationMonitorService.java
@@ -0,0 +1,44 @@
+package ohi.andre.consolelauncher.managers.notifications;
+
+/**
+ * Created by francescoandreuzzi on 03/09/2017.
+ */
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+
+public class NotificationMonitorService extends Service {
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        ensureCollectorRunning();
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        return START_STICKY;
+    }
+
+    private void ensureCollectorRunning() {
+        if(Tuils.notificationServiceIsRunning(this)) toggleNotificationListenerService();
+    }
+
+    private void toggleNotificationListenerService() {
+        ComponentName thisComponent = new ComponentName(this, NotificationService.class);
+        PackageManager pm = getPackageManager();
+        pm.setComponentEnabledSetting(thisComponent, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+        pm.setComponentEnabledSetting(thisComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+}
\ No newline at end of file
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
index 701a726ed93d3e2661aa3b5199f608c74ac0b4e9..d36b2958b2b327d9a15ef016b3c3c07566f48f6c 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationService.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/notifications/NotificationService.java
@@ -15,18 +15,17 @@ import android.os.Handler;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.support.v4.app.NotificationCompat;
-import android.support.v4.content.LocalBroadcastManager;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.style.ForegroundColorSpan;
+import android.util.SparseArray;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import ohi.andre.consolelauncher.managers.TerminalManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.tuils.TimeManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -40,7 +39,7 @@ public class NotificationService extends NotificationListenerService {
 
     private final int UPDATE_TIME = 1500;
 
-    Map<Integer, Long> recentNotifications = new HashMap<>();
+    SparseArray<Long> ids = new SparseArray<>();
     Handler handler = new Handler();
 
     @Override
@@ -51,7 +50,8 @@ public class NotificationService extends NotificationListenerService {
 
         manager = getPackageManager();
         format = NotificationManager.getFormat();
-        timeColor = XMLPrefsManager.getColor(XMLPrefsManager.Theme.time_color);
+        enabled = XMLPrefsManager.get(boolean.class, NotificationManager.Options.show_notifications) ||
+                XMLPrefsManager.get(String.class, NotificationManager.Options.show_notifications).equalsIgnoreCase("enabled");
 
         if(NotificationManager.apps() == 0) {
             NotificationManager.notificationsChangeFor(new ArrayList<>(Arrays.asList(
@@ -68,11 +68,14 @@ public class NotificationService extends NotificationListenerService {
         handler.post(new Runnable() {
             @Override
             public void run() {
-                Map<Integer, Long> copy = new HashMap<>(recentNotifications);
+                SparseArray<Long> clone = ids.clone();
 
                 long time = System.currentTimeMillis();
-                for(Map.Entry<Integer, Long> entry : copy.entrySet()) {
-                    if(time - entry.getValue() > 1500) recentNotifications.remove(entry.getKey());
+                for(int c = 0; c < clone.size(); c++) {
+                    int key = clone.keyAt(c);
+                    long tm = clone.valueAt(c);
+
+                    if(time - tm > UPDATE_TIME) ids.remove(key);
                 }
 
                 handler.postDelayed(this, UPDATE_TIME);
@@ -82,6 +85,12 @@ public class NotificationService extends NotificationListenerService {
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
+        if(intent != null) {
+            timeColor = intent.getIntExtra(XMLPrefsManager.Theme.time_color.label(), Color.parseColor(XMLPrefsManager.Theme.time_color.defaultValue()));
+        } else {
+            timeColor = Color.parseColor(XMLPrefsManager.Theme.time_color.defaultValue());
+        }
+
         return START_STICKY;
     }
 
@@ -92,6 +101,7 @@ public class NotificationService extends NotificationListenerService {
 
     String format;
     int timeColor;
+    boolean enabled;
 
     final Pattern patternPkg = Pattern.compile("%pkg", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
     final Pattern patternText = Pattern.compile("%txt", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
@@ -104,8 +114,13 @@ public class NotificationService extends NotificationListenerService {
     @Override
     public void onNotificationPosted(StatusBarNotification sbn) {
 
-        if (recentNotifications.containsKey(sbn.getId())) return;
-        recentNotifications.put(sbn.getId(), System.currentTimeMillis());
+        if(!enabled) return;
+
+        for(int c = 0; c < ids.size(); c++) {
+            int key = ids.keyAt(c);
+            if(key == sbn.getId()) return;
+        }
+        ids.put(sbn.getId(), System.currentTimeMillis());
 
         Notification notification = sbn.getNotification();
         if (notification == null) {
@@ -185,10 +200,7 @@ public class NotificationService extends NotificationListenerService {
             return;
         }
 
-        Intent msgrcv = new Intent("Msg");
-        msgrcv.putExtra("text", s);
-
-        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(msgrcv);
+        Tuils.sendOutput(this, s, TerminalManager.CATEGORY_NOTIFICATION);
     }
 
     @Override
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 1c014a9aca63ea0b2993d3b23873829d046382f4..b8c3180a18c9024285e9f397b88cc83e7bbc1ce7 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionRunnable.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionRunnable.java
@@ -99,8 +99,7 @@ public class SuggestionRunnable implements Runnable {
 //                bg and fore
                 int bgColor = SkinManager.COLOR_NOT_SET;
                 int foreColor = SkinManager.COLOR_NOT_SET;
-                if(suggestions[count].type == SuggestionsManager.Suggestion.TYPE_APP ||
-                        suggestions[count].type == SuggestionsManager.Suggestion.TYPE_APPGROUP) {
+                if(suggestions[count].type == SuggestionsManager.Suggestion.TYPE_APP) {
 
                     Object o = suggestions[count].object;
                     if(o != null && o instanceof AppsManager.LaunchInfo) {
@@ -143,8 +142,7 @@ public class SuggestionRunnable implements Runnable {
 //                    bg and fore
                     int bgColor = SkinManager.COLOR_NOT_SET;
                     int foreColor = SkinManager.COLOR_NOT_SET;
-                    if(suggestions[count].type == SuggestionsManager.Suggestion.TYPE_APP ||
-                            suggestions[count].type == SuggestionsManager.Suggestion.TYPE_APPGROUP) {
+                    if(suggestions[count].type == SuggestionsManager.Suggestion.TYPE_APP) {
 
                         Object o = suggestions[count].object;
                         if(o != null && o instanceof AppsManager.LaunchInfo) {
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 acd15e14a9e9f18e31e7ba0755424db7a11f7094..c332d0ab604e0e649481ace9240235734aedf8a9 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java
@@ -124,7 +124,7 @@ public class SuggestionsManager {
                         suggestFile(info, suggestionList, Tuils.EMPTYSTRING, before);
                     } else {
 //                        ==> app
-                        suggestApp(info, suggestionList, before + Tuils.SPACE, Tuils.EMPTYSTRING);
+                        if(!suggestAppInsideGroup(suggestionList, Tuils.EMPTYSTRING, before, false)) suggestApp(info, suggestionList, before + Tuils.SPACE, Tuils.EMPTYSTRING);
                     }
 
                 }
@@ -169,7 +169,7 @@ public class SuggestionsManager {
                     if(isShellCmd) {
                         suggestFile(info, suggestionList, lastWord, before);
                     } else {
-                        suggestApp(info, suggestionList, before + Tuils.SPACE + lastWord, Tuils.EMPTYSTRING);
+                        if(!suggestAppInsideGroup(suggestionList, lastWord, before, false)) suggestApp(info, suggestionList, before + Tuils.SPACE + lastWord, Tuils.EMPTYSTRING);
                     }
                 }
 
@@ -271,6 +271,9 @@ public class SuggestionsManager {
             case CommandAbstraction.APP_GROUP:
                 suggestAppGroup(suggestions, prev, before);
                 break;
+            case CommandAbstraction.APP_INSIDE_GROUP:
+                suggestAppInsideGroup(suggestions, prev, before, true);
+                break;
         }
     }
 
@@ -372,6 +375,8 @@ public class SuggestionsManager {
     }
 
     private void suggestSong(MainPack info, List<Suggestion> suggestions, String prev, String before) {
+        if(info.player == null) return;
+
         List<Song> songs = info.player.getSongs();
         if(songs == null) return;
 
@@ -436,43 +441,10 @@ public class SuggestionsManager {
     }
 
     private void suggestApp(MainPack info, List<Suggestion> suggestions, String prev, String before) {
-//        try to find a group only if it was called outside a command
-        int index = prev.indexOf(Tuils.SPACE);
-        if(before.length() == 0 && index != -1) {
-            String temp = prev;
-
-            String gpName = prev.substring(0,index);
-            prev = prev.substring(index + 1);
-
-            int gpIndex = Tuils.find(gpName, AppsManager.groups);
-            if(gpIndex != -1) {
-                AppsManager.Group g = AppsManager.groups.get(gpIndex);
-
-                List<? extends Compare.Stringable> apps = g.members();
-                if(apps != null && apps.size() > 0) {
-                    if (prev.length() == 0) {
-                        for (Compare.Stringable s : apps) {
-                            suggestions.add(new Suggestion(before, s.getString(), clickToLaunch, NO_RATE, Suggestion.TYPE_APP, s));
-                        }
-                    }
-                    else {
-                        List<SimpleMutableEntry<Compare.Stringable, Integer>> infos = Compare.matchesWithRate(apps, true, prev);
-                        for(SimpleMutableEntry<Compare.Stringable, Integer> i : infos) {
-                            suggestions.add(new Suggestion(before, i.getKey().getString(), clickToLaunch, i.getValue(), Suggestion.TYPE_APP, i.getKey()));
-                        }
-                    }
-                    return;
-                }
-            }
-
-            prev = temp;
-        }
-
-//        group not found...
         List<AppsManager.LaunchInfo> apps = info.appsManager.shownApps();
         if(apps == null) return;
 
-        if (prev.length() == 0) {
+        if (prev == null || prev.length() == 0) {
             for (AppsManager.LaunchInfo l : apps) {
                 suggestions.add(new Suggestion(before, l.publicLabel, clickToLaunch, NO_RATE, Suggestion.TYPE_APP, l));
             }
@@ -598,7 +570,7 @@ public class SuggestionsManager {
 
         if(prev == null || prev.length() == 0) {
             for(AppsManager.Group g : groups) {
-                Suggestion sg = new Suggestion(before, g.getName(), false, NO_RATE, Suggestion.TYPE_APPGROUP, g);
+                Suggestion sg = new Suggestion(before, g.getName(), false, NO_RATE, Suggestion.TYPE_APP, g);
                 suggestions.add(sg);
             }
         }
@@ -607,10 +579,65 @@ public class SuggestionsManager {
                 String label = g.getName();
                 int rate = Compare.matches(label, prev, true);
                 if(rate != -1) {
-                    suggestions.add(new Suggestion(before, label, false, rate, Suggestion.TYPE_APPGROUP, g));
+                    suggestions.add(new Suggestion(before, label, false, rate, Suggestion.TYPE_APP, g));
+                }
+            }
+        }
+    }
+
+    private boolean suggestAppInsideGroup(List<Suggestion> suggestions, String prev, String before, boolean keepGroupName) {
+        int index = -1;
+
+        String app = Tuils.EMPTYSTRING;
+
+        if(!before.contains(Tuils.SPACE)) {
+            index = Tuils.find(before, AppsManager.groups);
+            app = prev;
+            if(!keepGroupName) before = Tuils.EMPTYSTRING;
+        } else {
+            String[] split = before.split(Tuils.SPACE);
+            for(int count = 0; count < split.length; count++) {
+                index = Tuils.find(split[count], AppsManager.groups);
+                if(index != -1) {
+
+                    before = Tuils.EMPTYSTRING;
+                    for(int i = 0; (keepGroupName ? i <= count : i < count); i++) {
+                        before = before + split[i] + Tuils.SPACE;
+                    }
+                    before = before.trim();
+
+                    count += 1;
+                    for(; count < split.length; count++) {
+                        app = app + split[count] + Tuils.SPACE;
+                    }
+                    if(prev != null) app = app + Tuils.SPACE + prev;
+                    app = app.trim();
+
+                    break;
                 }
             }
         }
+
+        if(index == -1) return false;
+
+        AppsManager.Group g = AppsManager.groups.get(index);
+
+        List<? extends Compare.Stringable> apps = g.members();
+        if(apps != null && apps.size() > 0) {
+            if (app == null || app.length() == 0) {
+                for (Compare.Stringable s : apps) {
+                    suggestions.add(new Suggestion(before, s.getString(), clickToLaunch, NO_RATE, Suggestion.TYPE_APP, s));
+                }
+            }
+            else {
+                List<SimpleMutableEntry<Compare.Stringable, Integer>> infos = Compare.matchesWithRate(apps, true, app);
+                for(SimpleMutableEntry<Compare.Stringable, Integer> i : infos) {
+                    suggestions.add(new Suggestion(before, i.getKey().getString(), clickToLaunch, i.getValue(), Suggestion.TYPE_APP, i.getKey()));
+                }
+            }
+        }
+
+        return true;
     }
 
     public class Suggestion implements Comparable<Suggestion> {
@@ -624,7 +651,6 @@ public class SuggestionsManager {
         public static final int TYPE_BOOLEAN = 16;
         public static final int TYPE_COLOR = 17;
         public static final int TYPE_PERMANENT = 18;
-        public static final int TYPE_APPGROUP = 19;
 
         public String text;
         public String textBefore;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/AllowEqualsSequence.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/AllowEqualsSequence.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f2e1cb3591a6b4f7b5bc33683036a0ffcb808c9
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/AllowEqualsSequence.java
@@ -0,0 +1,82 @@
+package ohi.andre.consolelauncher.tuils;
+
+import android.support.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by francescoandreuzzi on 28/08/2017.
+ */
+
+public class AllowEqualsSequence {
+
+    List<Entry> sequence;
+
+    public AllowEqualsSequence(int[] keys, Object[] values) {
+        this.sequence = new ArrayList<>();
+
+        for (int count = 0; count < keys.length; count++) {
+            if(keys[count] == Integer.MAX_VALUE) continue;
+            sequence.add(new Entry(keys[count], values[count]));
+        }
+        Collections.sort(this.sequence);
+
+        int counter = -1, last = Integer.MAX_VALUE;
+        for(int count = 0; count < sequence.size(); count++) {
+            Entry entry = sequence.get(count);
+
+            int key = entry.key;
+            if(key != last) {
+                counter++;
+            }
+            entry.key = counter;
+            last = key;
+        }
+    }
+
+    public Object[] get(int key) {
+        List<Object> o = new ArrayList<>();
+        for(Entry entry : sequence) {
+            if(entry.key == key) o.add(entry.value);
+            else if(o.size() > 0) break;
+        }
+
+        return o.toArray(new Object[o.size()]);
+    }
+
+    public int getMaxKey() {
+        if(sequence.size() == 0) return -1;
+        return sequence.get(sequence.size() - 1).key;
+    }
+
+    public int getMinKey() {
+        if(sequence.size() == 0) return -1;
+        return sequence.get(0).key;
+    }
+
+    public int size() {
+        return sequence.size();
+    }
+
+    private class Entry implements Comparable<Entry> {
+        int key;
+        Object value;
+
+        public Entry(int key, Object value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        @Override
+        public int compareTo(@NonNull Entry o) {
+            return this.key - o.key;
+        }
+
+        @Override
+        public String toString() {
+            return key + ": " + value.toString();
+        }
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Animator.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Animator.java
deleted file mode 100755
index 85500799a65e298ca401ee4614cfde74a64ea1c3..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Animator.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package ohi.andre.consolelauncher.tuils;
-
-import android.view.View;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.widget.TextView;
-
-/**
- * Created by francescoandreuzzi on 17/02/2017.
- */
-
-public class Animator {
-
-    private static final int[] PATTERN = {20,60,30,80};
-    private static final int FADE_DURATION = 300;
-
-    private static final int USEFAST_LIMIT = 30;
-    private static final int FAST_DURATION = 10;
-
-    private static void animate(final TextView textView, final String text, final Animator chained) {
-
-        Runnable runnable = new Runnable() {
-
-            final Animator a = chained;
-            int index = 0;
-            int patternIndex = 0;
-            char[] array = text.toCharArray();
-
-            @Override
-            public void run() {
-                if(patternIndex == PATTERN.length) {
-                    patternIndex = 0;
-                }
-
-                if(index < array.length) {
-                    textView.append(array[index++] + "");
-                    textView.postDelayed(this, array.length >= USEFAST_LIMIT ? FAST_DURATION : PATTERN[patternIndex++]);
-                } else {
-                    if(a != null) a.animate();
-                }
-            }
-        };
-
-        runnable.run();
-    }
-
-    private static void animate(View view, final Animator chained) {
-        AlphaAnimation animation = new AlphaAnimation(0f, 1f);
-        animation.setDuration(FADE_DURATION);
-        animation.setFillAfter(true);
-        if (chained != null) {
-            animation.setAnimationListener(new Animation.AnimationListener() {
-                @Override
-                public void onAnimationStart(Animation animation) {
-                }
-
-                @Override
-                public void onAnimationEnd(Animation animation) {
-                    chained.animate();
-                }
-
-                @Override
-                public void onAnimationRepeat(Animation animation) {
-                }
-            });
-        }
-        view.startAnimation(animation);
-    }
-
-//    class
-
-    View view;
-    Object param;
-    Animator chained;
-
-    public Animator(TextView textView, String text) {
-        view = textView;
-        param = text;
-    }
-
-    public Animator(View view) {
-        this.view = view;
-
-        AlphaAnimation hide = new AlphaAnimation(1f, 0f);
-        hide.setFillAfter(true);
-        hide.setDuration(0);
-        view.startAnimation(hide);
-    }
-
-    public Animator setChained(Animator a) {
-        chained = a;
-        return this;
-    }
-
-    public void animate() {
-        if(view instanceof TextView && param instanceof String) {
-            Animator.animate((TextView) view, (String) param, chained);
-        } else {
-            Animator.animate(view, chained);
-        }
-    }
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/InputOutputReceiver.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/InputOutputReceiver.java
index 122374dfba52341e423fbda1073f53997d2570e6..4d6cd7a467c8ee4d38678a6cedd54a01feecc524 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/InputOutputReceiver.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/InputOutputReceiver.java
@@ -8,6 +8,7 @@ import android.support.v4.app.NotificationManagerCompat;
 import android.support.v4.app.RemoteInput;
 
 import ohi.andre.consolelauncher.managers.SkinManager;
+import ohi.andre.consolelauncher.managers.TerminalManager;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
 import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
 
@@ -25,6 +26,7 @@ public class InputOutputReceiver extends BroadcastReceiver {
     public static final String ACTION_CMD = "ohi.andre.consolelauncher.action_cmd";
     public static final String ACTION_OUTPUT = "ohi.andre.consolelauncher.action_output";
     public static final String TEXT = "ohi.andre.consolelauncher.text";
+    public static final String TYPE = "ohi.andre.consolelauncher.type";
     public static final String COLOR = "ohi.andre.consolelauncher.color";
 
     CommandExecuter executer;
@@ -47,7 +49,15 @@ public class InputOutputReceiver extends BroadcastReceiver {
                 executer.exec(text.toString());
             } else {
                 int color = intent.getIntExtra(COLOR, SkinManager.COLOR_NOT_SET);
-                outputable.onOutput(color, text);
+
+                if(color != SkinManager.COLOR_NOT_SET) {
+                    outputable.onOutput(color, text);
+                }
+                else {
+                    int type = intent.getIntExtra(TYPE, -1);
+                    if(type != -1) outputable.onOutput(text, type);
+                    else outputable.onOutput(text, TerminalManager.CATEGORY_OUTPUT);
+                }
             }
         } else {
             String cmd = remoteInput.getString(TEXT);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Sequence.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Sequence.java
deleted file mode 100644
index 06a5e3ba42e2abc2909946af769cdbf107c96da8..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Sequence.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package ohi.andre.consolelauncher.tuils;
-
-import android.support.annotation.NonNull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Created by francescoandreuzzi on 12/07/2017.
- */
-
-public class Sequence {
-
-    List<Entry> sequence;
-
-    public Sequence(int[] keys, Object[] values) {
-        this.sequence = new ArrayList<>();
-
-        for(int count = 0; count < keys.length; count++) add(keys[count], values[count]);
-        Collections.sort(this.sequence);
-    }
-
-    public void add(int key, Object v) {
-        add(new Entry(key, v));
-    }
-
-    public void add(Entry e) {
-        int i = indexOf(e);
-        if(i == -1) this.sequence.add(e);
-        else {
-            e.key++;
-            i = indexOf(e);
-            if(i == -1) this.sequence.add(e);
-            else {
-                Entry x = sequence.remove(i);
-                sequence.add(e);
-                add(x);
-            }
-        }
-    }
-
-    public Object get(int index) {
-        return sequence.get(index).value;
-    }
-
-    public int size() {
-        return sequence.size();
-    }
-
-    private int indexOf(Entry e) {
-        for(int count = 0; count < sequence.size(); count++) if(e.equals(sequence.get(count))) return count;
-        return -1;
-    }
-
-    private class Entry implements Comparable<Entry> {
-        int key;
-        Object value;
-
-        public Entry(int key, Object value) {
-            this.key = key;
-            this.value = value;
-        }
-
-        @Override
-        public int compareTo(@NonNull Entry o) {
-            return this.key - o.key;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if(obj instanceof Entry) return key == ((Entry) obj).key;
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return key + ": " + value.toString();
-        }
-    }
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/SquareImageView.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/SquareImageView.java
deleted file mode 100755
index 23176af4e1cfd9ed3d0e30c26096772ac13fd8c6..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/SquareImageView.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package ohi.andre.consolelauncher.tuils;
-
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-/**
- * Created by francescoandreuzzi on 23/02/2017.
- */
-
-public class SquareImageView extends ImageView {
-
-    public SquareImageView(Context context) {
-        super(context);
-    }
-
-    public SquareImageView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
-        int width = getMeasuredWidth();
-        setMeasuredDimension(width, width);
-    }
-}
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 5ce0c469638f0b52a435c84fdaa0445bac8768b9..8a9f63f8fe992cd52562fb09e4e324331d449b7d 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
@@ -17,9 +17,13 @@ import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.Build;
 import android.os.Environment;
+import android.os.Process;
 import android.os.StatFs;
 import android.provider.Settings;
+import android.text.SpannableString;
+import android.text.Spanned;
 import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
@@ -53,6 +57,7 @@ import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.managers.music.MusicManager2;
 import ohi.andre.consolelauncher.managers.music.Song;
+import ohi.andre.consolelauncher.managers.notifications.NotificationService;
 import ohi.andre.consolelauncher.tuils.interfaces.OnBatteryUpdate;
 import ohi.andre.consolelauncher.tuils.stuff.FakeLauncherActivity;
 
@@ -67,6 +72,26 @@ public class Tuils {
     private static final String TUI_FOLDER = "t-ui";
     public static final String MINUS = "-";
 
+    public static boolean notificationServiceIsRunning(Context context) {
+        ComponentName collectorComponent = new ComponentName(context, NotificationService.class);
+        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        boolean collectorRunning = false;
+        List<ActivityManager.RunningServiceInfo> runningServices = manager.getRunningServices(Integer.MAX_VALUE);
+        if (runningServices == null ) {
+            return false;
+        }
+
+        for (ActivityManager.RunningServiceInfo service : runningServices) {
+            if (service.service.equals(collectorComponent)) {
+                if (service.pid == Process.myPid()) {
+                    collectorRunning = true;
+                }
+            }
+        }
+
+        return collectorRunning;
+    }
+
     public static boolean arrayContains(int[] array, int value) {
         for(int i : array) {
             if(i == value) {
@@ -200,7 +225,7 @@ public class Tuils {
 
     public static double getAvailableExternalMemorySize(int unit) {
         try {
-            return getAvailableSpace(new File(System.getenv("SECONDARY_STORAGE")), unit);
+            return getAvailableSpace(XMLPrefsManager.get(File.class, XMLPrefsManager.Behavior.external_storage_path), unit);
         } catch (Exception e) {
             return -1;
         }
@@ -208,19 +233,23 @@ public class Tuils {
 
     public static double getTotalExternalMemorySize(int unit) {
         try {
-            return getTotaleSpace(new File(System.getenv("SECONDARY_STORAGE")), unit);
+            return getTotaleSpace(XMLPrefsManager.get(File.class, XMLPrefsManager.Behavior.external_storage_path), unit);
         } catch (Exception e) {
             return -1;
         }
     }
 
     public static double getAvailableSpace(File dir, int unit) {
+        if(dir == null) return -1;
+
         StatFs statFs = new StatFs(dir.getAbsolutePath());
         long blocks = statFs.getAvailableBlocks();
         return formatSize(blocks * statFs.getBlockSize(), unit);
     }
 
     public static double getTotaleSpace(File dir, int unit) {
+        if(dir == null) return -1;
+
         StatFs statFs = new StatFs(dir.getAbsolutePath());
         long blocks = statFs.getBlockCount();
         return formatSize(blocks * statFs.getBlockSize(), unit);
@@ -258,6 +287,12 @@ public class Tuils {
         return round(result, 2);
     }
 
+    public static SpannableString color(String text, int color) {
+        SpannableString spannableString = new SpannableString(text);
+        spannableString.setSpan(new ForegroundColorSpan(color), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        return spannableString;
+    }
+
     public static void delete(File dir) {
         for(File f : dir.listFiles()) {
             if(f.isDirectory()) delete(f);
@@ -266,6 +301,28 @@ public class Tuils {
         dir.delete();
     }
 
+    public static boolean insertOld(File oldFile) {
+        if(oldFile == null || !oldFile.exists()) return false;
+
+        String oldPath = oldFile.getAbsolutePath();
+
+        File oldFolder = new File(Tuils.getFolder(), "old");
+        if(!oldFolder.exists()) oldFolder.mkdir();
+
+        File dest = new File(oldFolder, oldFile.getName());
+        if(dest.exists()) dest.delete();
+
+        return oldFile.renameTo(dest) && new File(oldPath).delete();
+    }
+
+    public static File getOld(String name) {
+        File old = new File(Tuils.getFolder(), "old");
+        File file = new File(old, name);
+
+        if(file.exists()) return file;
+        return null;
+    }
+
     public static void deepView(View v) {
         Tuils.log(v.toString());
 
@@ -278,6 +335,42 @@ public class Tuils {
         Tuils.log("end of parents of: " + v.toString());
     }
 
+    public static void sendOutput(Context context, int res) {
+        sendOutput(SkinManager.COLOR_NOT_SET, context, res);
+    }
+
+    public static void sendOutput(int color, Context context, int res) {
+        sendOutput(color, context, context.getString(res));
+    }
+
+    public static void sendOutput(Context context, int res, int type) {
+        sendOutput(SkinManager.COLOR_NOT_SET, context, res, type);
+    }
+
+    public static void sendOutput(int color, Context context, int res, int type) {
+        sendOutput(color, context, context.getString(res), type);
+    }
+
+    public static void sendOutput(Context context, CharSequence s) {
+        sendOutput(SkinManager.COLOR_NOT_SET, context, s);
+    }
+
+    public static void sendOutput(int color, Context context, CharSequence s) {
+        sendOutput(color, context, s, -1);
+    }
+
+    public static void sendOutput(Context context, CharSequence s, int type) {
+        sendOutput(SkinManager.COLOR_NOT_SET, context, s, type);
+    }
+
+    public static void sendOutput(int color, Context context, CharSequence s, int type) {
+        Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
+        intent.putExtra(InputOutputReceiver.TEXT, s);
+        intent.putExtra(InputOutputReceiver.COLOR, color);
+        intent.putExtra(InputOutputReceiver.TYPE, type);
+        context.sendBroadcast(intent);
+    }
+
     public static final int TERA = 0;
     public static final int GIGA = 1;
     public static final int MEGA = 2;
@@ -342,7 +435,7 @@ public class Tuils {
     }
 
     private static String getNicePath(String filePath) {
-        String home = Environment.getExternalStorageDirectory().getAbsolutePath();
+        String home = XMLPrefsManager.get(File.class, XMLPrefsManager.Behavior.home_path).getAbsolutePath();
 
         if(filePath.equals(home)) {
             return "~";
@@ -425,8 +518,9 @@ public class Tuils {
     }
 
     public static void addPrefix(List<String> list, String prefix) {
-        for (int count = 0; count < list.size(); count++)
+        for (int count = 0; count < list.size(); count++) {
             list.set(count, prefix.concat(list.get(count)));
+        }
     }
 
     public static void addSeparator(List<String> list, String separator) {
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/libsuperuser/ShellHolder.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/libsuperuser/ShellHolder.java
index 73cbbe94fc89627549fde7eb69b48f38282ba4f8..ef8b1dcf44f1f03117956fbc2f4c1129889db3bf 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/libsuperuser/ShellHolder.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/libsuperuser/ShellHolder.java
@@ -1,7 +1,8 @@
 package ohi.andre.consolelauncher.tuils.libsuperuser;
 
-import android.os.Environment;
+import java.io.File;
 
+import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
 
 /**
@@ -31,7 +32,7 @@ public class ShellHolder {
                     }
                 })
                 .open();
-        interactive.addCommand("cd " + Environment.getExternalStorageDirectory().getAbsolutePath());
+        interactive.addCommand("cd " + XMLPrefsManager.get(File.class, XMLPrefsManager.Behavior.home_path));
         return interactive;
     }
 }
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c77adc7c7e3ab1a3ee56006305ada3a683caa4ec..14be3fc7e9a817539a9ff22656e3e59d558b8ec8 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -16,8 +16,10 @@
     <string name="admin_permission">Lock the screen on double tap</string>
 
     <!-- theme -->
-    <string name="theme_done">Done</string>
     <string name="theme_not_found">Theme not found</string>
+    <string name="theme_invalid">Invalid theme</string>
+    <string name="theme_old_not_found">You don\'t have an old theme</string>
+    <string name="theme_reverted">Reverted to the previous theme</string>
 
     <!-- files -->
     <string name="output_error">An unknown error has occurred</string>
@@ -29,12 +31,31 @@
     <string name="no_notification_access">Unfortunately t-ui can\'t redirect you to the \"Notification access\" page of your system settings</string>
 
     <!-- helps texts -->
-    <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 with the command\nconfig -set donation_message false</string>
     <string name="firsthelp_text">First time with t-ui? Use the command \"tutorial\" or \"help\"</string>
     <string name="permissions_toast">You have to grant Storage permission</string>
     <string name="output_usedefapp">You can use "apps -default_app" instead</string>
 
+    <!-- hints -->
+    <string name="hint_donate">\nDo you like my work?\nIf yes, rate t-ui on Play Store (cmd: $ rate) or offer me a coffee (cmd: $ donate). Thank you!</string>
+    <string name="hint_twitter">Did you know? t-ui is on Twitter. You can have a look with the cmd \"$ tui -twitter\"</string>
+    <string name="hint_telegram">Did you know? There\'s a Telegram group with many enthusiastic users, where you can discuss, share and chat with the developer.\nJust use the cmd \"$ tui -telegram\"</string>
+    <string name="hint_googlep">Did you know? Our official Google+ community is full of tips, experimental apks and discussions.\nYou can have a look with the cmd \"$ tui -googlep\"</string>
+    <string name="hint_tutorial">Did you read the tutorial? If you don\'t remember how to view it, the cmd is \"$ tutorial\"</string>
+    <string name="hint_theme">Did you know that you can easily switch your theme? Have a look at the cmd \"$ theme\"</string>
+    <string name="hint_theme2">Did you know? You can create your custom theme and share it to other users. Have a look at the cmd \"$ theme -new\"</string>
+    <string name="hint_help">Are you having any doubts about a command? Just use the cmd \"$ help cmdName\"</string>
+    <string name="hint_music">Did you know? You can listen your music without launching other apps but t-ui. Have a look at the cmd \"$ music\"</string>
+    <string name="hint_appgroups">Did you know? t-ui 6.4 introduced App Groups, a feature that let\'s you customize your app suggestions, creating different categories.\nYou can get more details with the cmd
+        \"$ apps -tutorial\"</string>
+    <string name="hint_notifications">Did you know? You can see your notifications directly from t-ui.\nIf you\'re interested, have a look at the tutorial: \"$ notifications -tutorial\"</string>
+    <string name="hint_clear">Are you sick of clearing your screen? Have a look at the options \"clear_after_cmds\", \"clear_after_seconds\" and \"maxlines\"</string>
+    <string name="hint_wallpaper">Do you want to use your wallpaper as t-ui background? Use the cmd: \"$ config -set system_wallpaper true\"</string>
+    <string name="hint_config">Are you having doubts about any config option? Use the cmd \"$ config -tutorial\" and look for that option inside the table</string>
+    <string name="hint_alias">Did you know that t-ui supports aliases? It also supports parameterized aliases.\nFor more info, use the cmd \"$ alias -tutorial\"</string>
+    <string name="hint_musicdisable">Do you want to make t-ui lighter? Use the cmd \"$ config -set enable_music false\" to disable the music player and save resources</string>
+
+    <string name="hint_disable">You can disable this messages with the cmd \"$ config -set show_hints false\"</string>
+
     <!-- apps -->
     <string name="output_appnotfound">Application not found</string>
     <string name="activity_not_found">Activity not found</string>
@@ -59,6 +80,7 @@
     <string name="output_errorlabel">Error:</string>
     <string name="output_invalidcolor">Invalid color</string>
     <string name="output_groupnotfound">Group not found</string>
+    <string name="output_groupexists">This group already exists</string>
     <string name="output_groupspace">Spaces are not allowed inside group names</string>
 
     <!-- alias -->
@@ -93,6 +115,7 @@
     <string name="output_playing">Playing:</string>
     <string name="output_stopped">Player stopped</string>
     <string name="output_songnotfound">Song not found</string>
+    <string name="output_musicdisabled">enable_music is false!</string>
 
     <!-- command/args -->
     <string name="output_commandnotfound">Command not found.\nTry to use \">>help\" or \">>tutorial\"</string>
@@ -135,6 +158,7 @@
         \n-default_app [index] [appName or most_used or null] -> set the default_app at the specified index
         \n-frc [appName] -> force t-ui to launch an app
         \n-file -> open apps.xml
+        \n-refresh [appName] -> refresh the \"launched_times\" value of the given app to 0
         \n-mkgp [groupName] -> create a new group with the given name
         \n-rmgp [groupName] -> delete the group with the given name
         \n-gpcolor [groupName] [color] -> set the color for the given group
@@ -156,12 +180,12 @@
     <string name="help_call">Make a call
         \nUsage: call [number] OR [contactName]
     </string>
-    <string name="help_config">Manage your config files.
-        \nUsage:
+    <string name="help_config">Usage:
         \n-set [option] [value] -> set the value of an option
-        \n-open [file] -> open a config file
+        \n-file [file] -> open a config file
         \n-get [option] -> get the value of an option
         \n-reset [option] -> reset the value of an option
+        \n-apply [file] -> move a file to the t-ui directory
     </string>
     <string name="help_data">Toggle mobile data</string>
     <string name="help_devutils">Usage:
@@ -199,9 +223,10 @@
     <string name="help_shellcommands">Print the commands in /system/bin and /system/xbin</string>
     <string name="help_status">Get info about battery charge, wifi status and mobile data</string>
     <string name="help_theme">Usage:
-        \n-apply [theme] -> apply the selected theme (case sensitive)
+        \n-apply [theme] -> apply the selected theme (case sensitive). require internet connection. may take some seconds
         \n-view -> view the available themes
-        \n-create -> create a new theme</string>
+        \n-create -> create a new theme
+        \n-old -> re-apply the theme that was replaced by the current one</string>
     <string name="help_time">Print the current time with the given format
         \n\nUsage:
         \n$ time [index] (index means the index of the desired time_format</string>