diff --git a/app/build.gradle b/app/build.gradle
index cd0208e483232d0fc582ce42f9acc4886e24479d..74bfe7801272576f49f598119c7b4fbfe6a7e96e 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
         minSdkVersion 8
         targetSdkVersion 23
 
-        versionCode 119
-        versionName "6.1g"
+        versionCode 121
+        versionName "6.2b"
     }
 
     buildTypes {
@@ -49,5 +49,5 @@ android {
     }
 }
 dependencies {
-//    compile files('libs/anrwatchdog-1.3.0.jar')
+    compile files('libs/anrwatchdog-1.3.0.jar')
 }
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ba66070dfb8fa407843994f5479030316e3cd4ce..a13b89d274c77c844302da3629eb3adc5c5973b6 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -29,6 +29,14 @@
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+    <permission
+        android:name="android.permission.FLASHLIGHT"
+        android:description="@string/help_flash"
+        android:label="@string/help_flash"
+        android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
+        android:protectionLevel="normal" />
 
     <!-- features -->
     <uses-feature android:name="android.hardware.camera"
@@ -84,7 +92,8 @@
 
         <receiver
             android:name=".tuils.stuff.PolicyReceiver"
-            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            android:permission="android.permission.BIND_DEVICE_ADMIN"
+            android:description="@string/admin_permission">
             <meta-data
                 android:name="android.app.device_admin"
                 android:resource="@xml/policy" />
@@ -100,6 +109,10 @@
             android:enabled="true"
             android:exported="false" />
 
+        <service android:name=".managers.music.MusicService"
+            android:enabled="true"
+            android:exported="true"/>
+
         <activity
             android:name=".commands.tuixt.TuixtActivity"
             android:theme="@style/Custom.Solid"
diff --git a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
index b66e36e926666b6e036f9bf8937d571dc308aa10..274e5058d9be0a08f287815ddda3f8eb65f1c092 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
@@ -23,10 +23,8 @@ import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.Toast;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
+import com.github.anrwatchdog.ANRError;
+import com.github.anrwatchdog.ANRWatchDog;
 
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.tuixt.TuixtActivity;
@@ -37,6 +35,7 @@ import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
 import ohi.andre.consolelauncher.managers.notifications.NotificationService;
 import ohi.andre.consolelauncher.managers.suggestions.SuggestionsManager;
 import ohi.andre.consolelauncher.tuils.Assist;
+import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
 import ohi.andre.consolelauncher.tuils.KeeperService;
 import ohi.andre.consolelauncher.tuils.TimeManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -71,9 +70,17 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
 
         @Override
         public String exec(String input) {
+            exec(input, false);
+            return null;
+        }
+
+        @Override
+        public String exec(String input, boolean needWriteInput) {
+            if(ui != null && needWriteInput) ui.setOutput(input, TerminalManager.CATEGORY_INPUT);
             if(main != null) main.onCommand(input, null);
             return null;
         }
+
     };
 
     private Inputable in = new Inputable() {
@@ -115,6 +122,11 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         public void onOutput(CharSequence output, int category) {
             if(ui != null) ui.setOutput(output, category);
         }
+
+        @Override
+        public void onOutput(int color, CharSequence output) {
+            ui.setOutput(color, output);
+        }
     };
 
     private Suggester sugg = new Suggester() {
@@ -147,24 +159,22 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
 
     private void finishOnCreate() {
 
-//        new ANRWatchDog(5000)
-//                .setANRListener(new ANRWatchDog.ANRListener() {
-//                    @Override
-//                    public void onAppNotResponding(ANRError anrError) {
-//                        Tuils.log(anrError);
-//                        Tuils.toFile(anrError);
-//                    }
-//                })
-//                .setReportMainThreadOnly()
-//                .start();
+        new ANRWatchDog(5000)
+                .setANRListener(new ANRWatchDog.ANRListener() {
+                    @Override
+                    public void onAppNotResponding(ANRError anrError) {
+                        Tuils.log(anrError);
+                        Tuils.toFile(anrError);
+                    }
+                })
+                .setReportMainThreadOnly()
+                .start();
 
         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
             @Override
             public void uncaughtException(Thread t, Throwable e) {
                 Tuils.log(e);
-                try {
-                    e.printStackTrace(new PrintStream(new FileOutputStream(new File(Tuils.getFolder(), "crash.txt"), true)));
-                } catch (FileNotFoundException e1) {}
+                Tuils.toFile(e);
             }
         });
 
@@ -182,7 +192,9 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         if (showNotification) {
             startService(keeperIntent);
         } else {
-            stopService(keeperIntent);
+            try {
+                stopService(keeperIntent);
+            } catch (Exception e) {}
         }
 
         fullscreen = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.fullscreen);
@@ -228,7 +240,7 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
         setContentView(R.layout.base_view);
 
         ViewGroup mainView = (ViewGroup) findViewById(R.id.mainview);
-        main = new MainManager(this, in, out, sugg);
+        main = new MainManager(this, in, out, sugg, ex);
         ui = new UIManager(main.getMainPack(), this, mainView, ex, main.getMainPack(), canApplyTheme);
         main.setRedirectionListener(ui.buildRedirectionListener());
         main.setHintable(ui.getHintable());
@@ -250,6 +262,13 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable {
             ui.setInput("tutorial");
         }
 
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(InputOutputReceiver.ACTION_CMD);
+        filter.addAction(InputOutputReceiver.ACTION_OUTPUT);
+
+        InputOutputReceiver inputOutputReceiver = new InputOutputReceiver(ex, out);
+        getApplicationContext().registerReceiver(inputOutputReceiver, filter);
+
         System.gc();
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
index 7e9dc513038babb79b01b7457e605fc1b3987540..08d8540e317e074ff1f48cd920f88676a03e00f2 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
@@ -2,13 +2,13 @@ package ohi.andre.consolelauncher;
 
 import android.content.Context;
 import android.content.Intent;
-import android.os.Environment;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
 
 import java.io.File;
 import java.util.List;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import ohi.andre.consolelauncher.commands.Command;
@@ -22,7 +22,7 @@ import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.TerminalManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
-import ohi.andre.consolelauncher.managers.music.MusicManager;
+import ohi.andre.consolelauncher.managers.music.MusicManager2;
 import ohi.andre.consolelauncher.tuils.StoppableThread;
 import ohi.andre.consolelauncher.tuils.TimeManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -35,7 +35,7 @@ import ohi.andre.consolelauncher.tuils.interfaces.Redirectator;
 import ohi.andre.consolelauncher.tuils.interfaces.Rooter;
 import ohi.andre.consolelauncher.tuils.interfaces.Suggester;
 import ohi.andre.consolelauncher.tuils.libsuperuser.Shell;
-import ohi.andre.consolelauncher.tuils.libsuperuser.StreamGobbler;
+import ohi.andre.consolelauncher.tuils.libsuperuser.ShellHolder;
 
 /*Copyright Francesco Andreuzzi
 
@@ -107,7 +107,7 @@ public class MainManager {
 
     private Hintable hintable;
 
-    protected MainManager(LauncherActivity c, Inputable i, Outputable o, Suggester sugg) {
+    protected MainManager(LauncherActivity c, Inputable i, Outputable o, Suggester sugg, CommandExecuter executer) {
         mContext = c;
 
         in = i;
@@ -125,43 +125,15 @@ public class MainManager {
             cont = new ContactManager(mContext);
         } catch (NullPointerException e) {}
 
-        CommandExecuter executer = new CommandExecuter() {
-            @Override
-            public String exec(String aliasValue, String alias) {
-                onCommand(aliasValue, alias);
-                return null;
-            }
-
-            @Override
-            public String exec(String input) {
-                onCommand(input, null);
-                return null;
-            }
-        };
-
-        MusicManager music = new MusicManager(mContext, out);
+        MusicManager2 music = new MusicManager2(mContext);
 
-        AppsManager appsMgr = new AppsManager(c, out, sugg);
+        AppsManager appsMgr = new AppsManager(c, sugg);
         AliasManager aliasManager = new AliasManager();
 
-        interactive = new Shell.Builder()
-                .setOnSTDOUTLineListener(new StreamGobbler.OnLineListener() {
-                    @Override
-                    public void onLine(String line) {
-                        out.onOutput(line);
-                    }
-                })
-                .setOnSTDERRLineListener(new StreamGobbler.OnLineListener() {
-                    @Override
-                    public void onLine(String line) {
-                        out.onOutput(line);
-                    }
-                })
-        .open();
+        ShellHolder shellHolder = new ShellHolder(out);
+        interactive = shellHolder.build();
 
-        interactive.addCommand("cd " + Environment.getExternalStorageDirectory().getAbsolutePath());
-
-        mainPack = new MainPack(mContext, group, aliasManager, appsMgr, music, cont, c, executer, out, redirectator);
+        mainPack = new MainPack(mContext, group, aliasManager, appsMgr, music, cont, c, executer, redirectator, shellHolder);
     }
 
 //    command manager
@@ -220,7 +192,16 @@ public class MainManager {
 
     public void destroy() {
         mainPack.destroy();
-        interactive.close();
+
+        new Thread() {
+            @Override
+            public void run() {
+                super.run();
+
+                interactive.kill();
+                interactive.close();
+            }
+        }.start();
     }
 
     public MainPack getMainPack() {
@@ -318,10 +299,10 @@ public class MainManager {
         int timeColor;
         int outputColor;
 
-        Pattern pa = Pattern.compile("%a", Pattern.CASE_INSENSITIVE);
-        Pattern pp = Pattern.compile("%p", Pattern.CASE_INSENSITIVE);
-        Pattern pl = Pattern.compile("%l", Pattern.CASE_INSENSITIVE);
-        Pattern pn = Pattern.compile("%n", Pattern.CASE_INSENSITIVE);
+        Pattern pa = Pattern.compile("%a", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+        Pattern pp = Pattern.compile("%p", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+        Pattern pl = Pattern.compile("%l", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+        Pattern pn = Pattern.compile("%n", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
 
         @Override
         public boolean trigger(ExecutePack info, String input) {
@@ -343,10 +324,10 @@ public class MainManager {
                 }
 
                 String a = new String(appFormat);
-                a = pa.matcher(a).replaceAll(intent.getComponent().getClassName());
-                a = pp.matcher(a).replaceAll(intent.getComponent().getPackageName());
-                a = pl.matcher(a).replaceAll(i.publicLabel);
-                a = pn.matcher(a).replaceAll(Tuils.NEWLINE);
+                a = pa.matcher(a).replaceAll(Matcher.quoteReplacement(intent.getComponent().getClassName()));
+                a = pp.matcher(a).replaceAll(Matcher.quoteReplacement(intent.getComponent().getPackageName()));
+                a = pl.matcher(a).replaceAll(Matcher.quoteReplacement(i.publicLabel));
+                a = pn.matcher(a).replaceAll(Matcher.quoteReplacement(Tuils.NEWLINE));
 
                 SpannableString text = new SpannableString(a);
                 text.setSpan(new ForegroundColorSpan(outputColor), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
index 1d8f4c897a3fe017b59701b6ed7168a8c9ea3ee5..82c90638ba7d71077f580bf6f6a3afa1c2d560d7 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
@@ -30,6 +30,7 @@ import android.widget.TextView;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import ohi.andre.consolelauncher.commands.ExecutePack;
@@ -137,38 +138,38 @@ public class UIManager implements OnTouchListener {
             if(storagePatterns == null) {
                 storagePatterns = new ArrayList<>();
 
-                storagePatterns.add(Pattern.compile(INT_AV + "tb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_AV + "gb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_AV + "mb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_AV + "kb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_AV + "b", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_AV + "%", Pattern.CASE_INSENSITIVE));
-
-                storagePatterns.add(Pattern.compile(INT_TOT + "tb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_TOT + "gb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_TOT + "mb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_TOT + "kb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_TOT + "b", Pattern.CASE_INSENSITIVE));
-
-                storagePatterns.add(Pattern.compile(EXT_AV + "tb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_AV + "gb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_AV + "mb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_AV + "kb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_AV + "b", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_AV + "%", Pattern.CASE_INSENSITIVE));
-
-                storagePatterns.add(Pattern.compile(EXT_TOT + "tb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_TOT + "gb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_TOT + "mb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_TOT + "kb", Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_TOT + "b", Pattern.CASE_INSENSITIVE));
-
-                storagePatterns.add(Pattern.compile("%n", Pattern.CASE_INSENSITIVE));
-
-                storagePatterns.add(Pattern.compile(INT_AV, Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(INT_TOT, Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_AV, Pattern.CASE_INSENSITIVE));
-                storagePatterns.add(Pattern.compile(EXT_TOT, Pattern.CASE_INSENSITIVE));
+                storagePatterns.add(Pattern.compile(INT_AV + "tb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_AV + "gb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_AV + "mb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_AV + "kb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_AV + "b", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_AV + "%", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+
+                storagePatterns.add(Pattern.compile(INT_TOT + "tb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_TOT + "gb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_TOT + "mb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_TOT + "kb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_TOT + "b", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+
+                storagePatterns.add(Pattern.compile(EXT_AV + "tb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_AV + "gb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_AV + "mb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_AV + "kb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_AV + "b", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_AV + "%", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+
+                storagePatterns.add(Pattern.compile(EXT_TOT + "tb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_TOT + "gb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_TOT + "mb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_TOT + "kb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_TOT + "b", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+
+                storagePatterns.add(Pattern.compile("%n", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+
+                storagePatterns.add(Pattern.compile(INT_AV, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(INT_TOT, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_AV, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                storagePatterns.add(Pattern.compile(EXT_TOT, Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
             }
 
             double iav = Tuils.getAvailableInternalMemorySize(Tuils.BYTE);
@@ -178,38 +179,38 @@ public class UIManager implements OnTouchListener {
 
             String copy = storageFormat;
 
-            copy = storagePatterns.get(0).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) iav, Tuils.TERA)));
-            copy = storagePatterns.get(1).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) iav, Tuils.GIGA)));
-            copy = storagePatterns.get(2).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) iav, Tuils.MEGA)));
-            copy = storagePatterns.get(3).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) iav, Tuils.KILO)));
-            copy = storagePatterns.get(4).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) iav, Tuils.BYTE)));
-            copy = storagePatterns.get(5).matcher(copy).replaceAll(String.valueOf(Tuils.percentage(iav, itot)));
-
-            copy = storagePatterns.get(6).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) itot, Tuils.TERA)));
-            copy = storagePatterns.get(7).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) itot, Tuils.GIGA)));
-            copy = storagePatterns.get(8).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) itot, Tuils.MEGA)));
-            copy = storagePatterns.get(9).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) itot, Tuils.KILO)));
-            copy = storagePatterns.get(10).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) itot, Tuils.BYTE)));
-
-            copy = storagePatterns.get(11).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) eav, Tuils.TERA)));
-            copy = storagePatterns.get(12).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) eav, Tuils.GIGA)));
-            copy = storagePatterns.get(14).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) eav, Tuils.MEGA)));
-            copy = storagePatterns.get(14).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) eav, Tuils.KILO)));
-            copy = storagePatterns.get(15).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) eav, Tuils.BYTE)));
-            copy = storagePatterns.get(16).matcher(copy).replaceAll(String.valueOf(Tuils.percentage(eav, etot)));
-
-            copy = storagePatterns.get(17).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) etot, Tuils.TERA)));
-            copy = storagePatterns.get(18).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) etot, Tuils.GIGA)));
-            copy = storagePatterns.get(19).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) etot, Tuils.MEGA)));
-            copy = storagePatterns.get(20).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) etot, Tuils.KILO)));
-            copy = storagePatterns.get(21).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) etot, Tuils.BYTE)));
-
-            copy = storagePatterns.get(22).matcher(copy).replaceAll(Tuils.NEWLINE);
-
-            copy = storagePatterns.get(23).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) iav, Tuils.GIGA)));
-            copy = storagePatterns.get(24).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) itot, Tuils.GIGA)));
-            copy = storagePatterns.get(25).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) eav, Tuils.GIGA)));
-            copy = storagePatterns.get(26).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) etot, Tuils.GIGA)));
+            copy = storagePatterns.get(0).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) iav, Tuils.TERA))));
+            copy = storagePatterns.get(1).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) iav, Tuils.GIGA))));
+            copy = storagePatterns.get(2).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) iav, Tuils.MEGA))));
+            copy = storagePatterns.get(3).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) iav, Tuils.KILO))));
+            copy = storagePatterns.get(4).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) iav, Tuils.BYTE))));
+            copy = storagePatterns.get(5).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.percentage(iav, itot))));
+
+            copy = storagePatterns.get(6).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) itot, Tuils.TERA))));
+            copy = storagePatterns.get(7).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) itot, Tuils.GIGA))));
+            copy = storagePatterns.get(8).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) itot, Tuils.MEGA))));
+            copy = storagePatterns.get(9).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) itot, Tuils.KILO))));
+            copy = storagePatterns.get(10).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) itot, Tuils.BYTE))));
+
+            copy = storagePatterns.get(11).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) eav, Tuils.TERA))));
+            copy = storagePatterns.get(12).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) eav, Tuils.GIGA))));
+            copy = storagePatterns.get(14).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) eav, Tuils.MEGA))));
+            copy = storagePatterns.get(14).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) eav, Tuils.KILO))));
+            copy = storagePatterns.get(15).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) eav, Tuils.BYTE))));
+            copy = storagePatterns.get(16).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.percentage(eav, etot))));
+
+            copy = storagePatterns.get(17).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) etot, Tuils.TERA))));
+            copy = storagePatterns.get(18).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) etot, Tuils.GIGA))));
+            copy = storagePatterns.get(19).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) etot, Tuils.MEGA))));
+            copy = storagePatterns.get(20).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) etot, Tuils.KILO))));
+            copy = storagePatterns.get(21).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) etot, Tuils.BYTE))));
+
+            copy = storagePatterns.get(22).matcher(copy).replaceAll(Matcher.quoteReplacement(Tuils.NEWLINE));
+
+            copy = storagePatterns.get(23).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) iav, Tuils.GIGA))));
+            copy = storagePatterns.get(24).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) itot, Tuils.GIGA))));
+            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);
@@ -240,20 +241,20 @@ public class UIManager implements OnTouchListener {
             if(ramPatterns == null) {
                 ramPatterns = new ArrayList<>();
 
-                ramPatterns.add(Pattern.compile(AV + "tb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(AV + "gb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(AV + "mb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(AV + "kb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(AV + "b", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(AV + "%", Pattern.CASE_INSENSITIVE));
+                ramPatterns.add(Pattern.compile(AV + "tb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(AV + "gb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(AV + "mb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(AV + "kb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(AV + "b", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(AV + "%", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
 
-                ramPatterns.add(Pattern.compile(TOT + "tb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(TOT + "gb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(TOT + "mb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(TOT + "kb", Pattern.CASE_INSENSITIVE));
-                ramPatterns.add(Pattern.compile(TOT + "b", Pattern.CASE_INSENSITIVE));
+                ramPatterns.add(Pattern.compile(TOT + "tb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(TOT + "gb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(TOT + "mb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(TOT + "kb", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
+                ramPatterns.add(Pattern.compile(TOT + "b", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
 
-                ramPatterns.add(Pattern.compile("%n", Pattern.CASE_INSENSITIVE));
+                ramPatterns.add(Pattern.compile("%n", Pattern.CASE_INSENSITIVE | Pattern.LITERAL));
             }
 
             String copy = ramFormat;
@@ -261,20 +262,20 @@ public class UIManager implements OnTouchListener {
             double av = Tuils.freeRam(activityManager, memory);
             double tot = Tuils.totalRam() * 1024L;
 
-            copy = ramPatterns.get(0).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) av, Tuils.TERA)));
-            copy = ramPatterns.get(1).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) av, Tuils.GIGA)));
-            copy = ramPatterns.get(2).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) av, Tuils.MEGA)));
-            copy = ramPatterns.get(3).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) av, Tuils.KILO)));
-            copy = ramPatterns.get(4).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) av, Tuils.BYTE)));
-            copy = ramPatterns.get(5).matcher(copy).replaceAll(String.valueOf(Tuils.percentage(av, tot)));
+            copy = ramPatterns.get(0).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) av, Tuils.TERA))));
+            copy = ramPatterns.get(1).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) av, Tuils.GIGA))));
+            copy = ramPatterns.get(2).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) av, Tuils.MEGA))));
+            copy = ramPatterns.get(3).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) av, Tuils.KILO))));
+            copy = ramPatterns.get(4).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) av, Tuils.BYTE))));
+            copy = ramPatterns.get(5).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.percentage(av, tot))));
 
-            copy = ramPatterns.get(6).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) tot, Tuils.TERA)));
-            copy = ramPatterns.get(7).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) tot, Tuils.GIGA)));
-            copy = ramPatterns.get(8).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) tot, Tuils.MEGA)));
-            copy = ramPatterns.get(9).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) tot, Tuils.KILO)));
-            copy = ramPatterns.get(10).matcher(copy).replaceAll(String.valueOf(Tuils.formatSize((long) tot, Tuils.BYTE)));
+            copy = ramPatterns.get(6).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) tot, Tuils.TERA))));
+            copy = ramPatterns.get(7).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) tot, Tuils.GIGA))));
+            copy = ramPatterns.get(8).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) tot, Tuils.MEGA))));
+            copy = ramPatterns.get(9).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) tot, Tuils.KILO))));
+            copy = ramPatterns.get(10).matcher(copy).replaceAll(Matcher.quoteReplacement(String.valueOf(Tuils.formatSize((long) tot, Tuils.BYTE))));
 
-            copy = ramPatterns.get(11).matcher(copy).replaceAll(Tuils.NEWLINE);
+            copy = ramPatterns.get(11).matcher(copy).replaceAll(Matcher.quoteReplacement(Tuils.NEWLINE));
 
             ram.setText(copy);
             ram.postDelayed(this, RAM_DELAY);
@@ -595,15 +596,15 @@ public class UIManager implements OnTouchListener {
         boolean showDevice = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Ui.show_device_name);
         if (showDevice) {
 
-            Pattern USERNAME = Pattern.compile("%u", Pattern.CASE_INSENSITIVE);
-            Pattern DV = Pattern.compile("%d", Pattern.CASE_INSENSITIVE);
-            Pattern NEWLINE = Pattern.compile("%n", Pattern.CASE_INSENSITIVE);
+            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);
 
             String deviceFormat = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.device_format);
 
-            deviceFormat = USERNAME.matcher(deviceFormat).replaceAll(skinManager.username != null ? skinManager.username : "null");
-            deviceFormat = DV.matcher(deviceFormat).replaceAll(skinManager.deviceName != null ? skinManager.deviceName : "null");
-            deviceFormat = NEWLINE.matcher(deviceFormat).replaceAll(Tuils.NEWLINE);
+            deviceFormat = USERNAME.matcher(deviceFormat).replaceAll(Matcher.quoteReplacement(skinManager.username != null ? skinManager.username : "null"));
+            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);
@@ -775,6 +776,10 @@ public class UIManager implements OnTouchListener {
         mTerminalAdapter.setOutput(s, category);
     }
 
+    public void setOutput(int color, CharSequence output) {
+        mTerminalAdapter.setOutput(color, output);
+    }
+
     public void disableSuggestions() {
         if(suggestionsView != null) {
             showSuggestions = false;
@@ -843,7 +848,7 @@ public class UIManager implements OnTouchListener {
                     boolean admin = policy.isAdminActive(component);
 
                     if (!admin) {
-                        Intent i = Tuils.requestAdmin(component);
+                        Intent i = Tuils.requestAdmin(component, mContext.getString(R.string.admin_permission));
                         mContext.startActivity(i);
                     } else {
                         policy.lockNow();
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 79cdbd8b43578744a57813acedda375cc7bc922e..922fbeb7be339124bc976b09ece828e8468ac8f0 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
@@ -16,8 +16,8 @@ import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
 import ohi.andre.consolelauncher.managers.FileManager;
 import ohi.andre.consolelauncher.managers.FileManager.DirInfo;
-import ohi.andre.consolelauncher.managers.music.MusicManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
+import ohi.andre.consolelauncher.managers.music.MusicManager2;
 import ohi.andre.consolelauncher.managers.notifications.NotificationManager;
 import ohi.andre.consolelauncher.tuils.SimpleMutableEntry;
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -373,7 +373,7 @@ public class CommandTuils {
         return new ArgInfo(number, null, number != null, 1);
     }
 
-    private static ArgInfo song(String input, MusicManager music) {
+    private static ArgInfo song(String input, MusicManager2 music) {
         return new ArgInfo(input, null, true, 1);
     }
 
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 d6bfb0701510fcd5276b85b14eb7e95953363cbb..c5de9b4a01aa2db15d9c7d8f0630d855b3e2df06 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
@@ -22,12 +22,12 @@ 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.music.MusicManager;
+import ohi.andre.consolelauncher.managers.music.MusicManager2;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
-import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
 import ohi.andre.consolelauncher.tuils.interfaces.Redirectator;
 import ohi.andre.consolelauncher.tuils.interfaces.Reloadable;
 import ohi.andre.consolelauncher.tuils.interfaces.Rooter;
+import ohi.andre.consolelauncher.tuils.libsuperuser.ShellHolder;
 
 /**
  * Created by francescoandreuzzi on 24/01/2017.
@@ -35,8 +35,6 @@ import ohi.andre.consolelauncher.tuils.interfaces.Rooter;
 
 public class MainPack extends ExecutePack {
 
-    public Outputable outputable;
-
     //	current directory
     public File currentDirectory;
 
@@ -62,7 +60,7 @@ public class MainPack extends ExecutePack {
     public ContactManager contacts;
 
     //	music
-    public MusicManager player;
+    public MusicManager2 player;
 
     //	apps & assocs
     public AliasManager aliasManager;
@@ -84,13 +82,15 @@ public class MainPack extends ExecutePack {
 
     public Redirectator redirectator;
 
-    public MainPack(Context context, CommandGroup commandGroup, AliasManager alMgr, AppsManager appmgr, MusicManager p,
-                    ContactManager c, Reloadable r, CommandExecuter executeCommand, Outputable outputable, Redirectator redirectator) {
+    public ShellHolder shellHolder;
+
+    public MainPack(Context context, CommandGroup commandGroup, AliasManager alMgr, AppsManager appmgr, MusicManager2 p,
+                    ContactManager c, Reloadable r, CommandExecuter executeCommand, Redirectator redirectator, ShellHolder shellHolder) {
         super(commandGroup);
 
         this.currentDirectory = Environment.getExternalStorageDirectory();
 
-        this.outputable = outputable;
+        this.shellHolder = shellHolder;
 
         this.res = context.getResources();
 
@@ -142,7 +142,7 @@ public class MainPack extends ExecutePack {
     }
 
     public void destroy() {
-        player.destroy(this.context);
+        player.destroy();
         appsManager.onDestroy();
     }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/generals/music.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/generals/music.java
deleted file mode 100755
index 54c249c8304ad912776ab567081c130fd1bd5cd2..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/generals/music.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.generals;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-
-public abstract class music implements CommandAbstraction {
-
-    @Override
-    public String exec(ExecutePack info) {
-        MainPack pack = (MainPack) info;
-        if (!pack.player.initPlayer())
-            return pack.res.getString(R.string.output_musicfoldererror);
-
-        return null;
-    }
-
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/community.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/community.java
deleted file mode 100644
index 23fd4c49bea4a166e19edef685397cdeaa5f3367..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/community.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.tuils.Tuils;
-
-/**
- * Created by francescoandreuzzi on 17/07/2017.
- */
-
-public class community implements CommandAbstraction {
-
-    @Override
-    public String exec(ExecutePack pack) throws Exception {
-        pack.context.startActivity(Tuils.webPage("https://plus.google.com/communities/103936578623101446195"));
-        return null;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return new int[0];
-    }
-
-    @Override
-    public int priority() {
-        return 3;
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_community;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack pack, int indexNotFound) {
-        return null;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack pack, int nArgs) {
-        return null;
-    }
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ctrlc.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ctrlc.java
index 81aa1ed805a975849328fcdd441f50571940f6b2..99d95cd6df5355aceabc99e5bf26edc55b94efa5 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ctrlc.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/ctrlc.java
@@ -1,14 +1,10 @@
 package ohi.andre.consolelauncher.commands.main.raw;
 
-import android.os.Environment;
-
 import ohi.andre.consolelauncher.MainManager;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.tuils.libsuperuser.Shell;
-import ohi.andre.consolelauncher.tuils.libsuperuser.StreamGobbler;
 
 /**
  * Created by francescoandreuzzi on 26/07/2017.
@@ -27,22 +23,7 @@ public class ctrlc implements CommandAbstraction {
                 MainManager.interactive.close();
                 MainManager.interactive = null;
 
-                MainManager.interactive = new Shell.Builder()
-                        .setOnSTDOUTLineListener(new StreamGobbler.OnLineListener() {
-                            @Override
-                            public void onLine(String line) {
-                                ((MainPack) pack).outputable.onOutput(line);
-                            }
-                        })
-                        .setOnSTDERRLineListener(new StreamGobbler.OnLineListener() {
-                            @Override
-                            public void onLine(String line) {
-                                ((MainPack) pack).outputable.onOutput(line);
-                            }
-                        })
-                        .open();
-
-                MainManager.interactive.addCommand("cd " + Environment.getExternalStorageDirectory().getAbsolutePath());
+                MainManager.interactive = ((MainPack) pack).shellHolder.build();
             }
         }.start();
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/listen.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/listen.java
deleted file mode 100755
index 350af9b2e40914dfdb260b99b12221f2ba35cff2..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/listen.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.commands.main.generals.music;
-
-public class listen extends music {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        String output = super.exec(info);
-        if (output != null)
-            return output;
-
-        String name = info.get(String.class, 0);
-        String path = info.player.getPath(name);
-        if (info.player.jukebox(path))
-            return info.res.getString(R.string.output_playing) + " " + name;
-        return info.res.getString(R.string.output_nothing_found);
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_listen;
-    }
-
-    @Override
-    public int minArgs() {
-        return 1;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 1;
-    }
-
-    @Override
-    public int[] argType() {
-        return new int[]{CommandAbstraction.SONG};
-    }
-
-    @Override
-    public int priority() {
-        return 2;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack pack, int nArgs) {
-        MainPack info = (MainPack) pack;
-        return info.res.getString(helpRes());
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack pack, int index) {
-        MainPack info = (MainPack) pack;
-        return info.res.getString(R.string.output_nothing_found);
-    }
-
-}
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 bfe57402c50c4e0751f6510934220ba03188160c..aebce88d08b79fd271234a1670889c727f784ccf 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,6 +3,7 @@ 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;
@@ -17,6 +18,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;
 
 /**
  * Created by francescoandreuzzi on 10/05/2017.
@@ -25,7 +27,7 @@ import ohi.andre.consolelauncher.commands.specific.APICommand;
 public class location extends APICommand {
 
     @Override
-    public String exec(ExecutePack pack) throws Exception {
+    public String exec(final ExecutePack pack) throws Exception {
         Context context = ((MainPack) pack).context;
 
         if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
@@ -42,7 +44,9 @@ public class location extends APICommand {
         LocationListener locationListener = new LocationListener() {
             @Override
             public void onLocationChanged(Location location) {
-                main.outputable.onOutput("Lat: " + location.getLatitude() + "; Long: " + location.getLongitude());
+                Intent intent = new Intent(InputOutputReceiver.ACTION_OUTPUT);
+                intent.putExtra(InputOutputReceiver.TEXT, "Lat: " + location.getLatitude() + "; Long: " + location.getLongitude());
+                pack.context.sendBroadcast(intent);
             }
 
             @Override
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/next.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/next.java
deleted file mode 100755
index 3abb54b6d2894d848605c474e23f64d781a37c52..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/next.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.commands.main.generals.music;
-
-public class next extends music {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        String output = super.exec(info);
-        if (output != null)
-            return output;
-
-        output = info.player.next();
-        return info.res.getString(R.string.output_playing) + " " + output;
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_next;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return new int[0];
-    }
-
-    @Override
-    public int priority() {
-        return 5;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info, int index) {
-        return null;
-    }
-
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/previous.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/previous.java
deleted file mode 100755
index 629c5ce9475c0398f6f682cf2c0e07cb57398489..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/previous.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.commands.main.generals.music;
-
-public class previous extends music {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        String output = super.exec(info);
-        if (output != null)
-            return output;
-
-        output = info.player.prev();
-        return info.res.getString(R.string.output_playing) + " " + output;
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_previous;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return new int[0];
-    }
-
-    @Override
-    public int priority() {
-        return 3;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info, int index) {
-        return null;
-    }
-
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/refresh.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/refresh.java
index 7137a12093fbd91198a221c487b439fb94747dff..452dcfb3e7b870a75633f8ca928e0650e573d621 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(info.context);
+        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/search.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/search.java
index 3d98020be9c6c0805d25318d71ba542ad2f05111..afceeb99501a8344c8a70af3c3d6ee488a5d41e7 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/search.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/search.java
@@ -34,14 +34,14 @@ public class search extends ParamCommand {
                 return playstore(args, pack.context);
             }
         },
-        file {
-            @Override
-            public String exec(ExecutePack pack) {
-                List<String> args = pack.get(ArrayList.class, 1);
-                MainPack p = ((MainPack) pack);
-                return file(args, p.currentDirectory, p.res, p.outputable);
-            }
-        },
+//        file {
+//            @Override
+//            public String exec(ExecutePack pack) {
+//                List<String> args = pack.get(ArrayList.class, 1);
+//                MainPack p = ((MainPack) pack);
+//                return file(args, p.currentDirectory, p.res, p.outputable);
+//            }
+//        },
         gg {
             @Override
             public String exec(ExecutePack pack) {
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/stop.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/stop.java
deleted file mode 100755
index 4bc2abbc505a2f16618f0b502eb8bedd4dc6e2a5..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/stop.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.CommandAbstraction;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-
-public class stop implements CommandAbstraction {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        try {
-            info.player.stop();
-        } catch (IllegalStateException e) {
-            return info.res.getString(R.string.output_cantstop);
-        }
-        return info.res.getString(R.string.output_stopped);
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_stop;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return new int[0];
-    }
-
-    @Override
-    public int priority() {
-        return 3;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info, int index) {
-        return null;
-    }
-
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/track.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/track.java
deleted file mode 100755
index 20eac16ecdaeda4f76989460ee66de42567af59f..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/track.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.ExecutePack;
-import ohi.andre.consolelauncher.commands.main.MainPack;
-import ohi.andre.consolelauncher.commands.main.generals.music;
-
-public class track extends music {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        if (info.player.isPlaying())
-            return info.player.trackInfo();
-        else
-            return info.res.getString(R.string.output_nomusic);
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_track;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return new int[0];
-    }
-
-    @Override
-    public int priority() {
-        return 2;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info, int index) {
-        return null;
-    }
-
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tracks.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tracks.java
deleted file mode 100755
index 160fb2967a6455956fd21f3228c71ad57586ae1a..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tracks.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package ohi.andre.consolelauncher.commands.main.raw;
-
-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.tuils.Tuils;
-
-/**
- * Created by andre on 07/08/15.
- */
-
-public class tracks implements CommandAbstraction {
-
-    @Override
-    public String exec(ExecutePack pack) {
-        MainPack info = (MainPack) pack;
-        List<String> names = info.player.getNames();
-        if(names == null) {
-            return info.res.getString(R.string.output_musicfoldererror);
-        }
-
-        Tuils.addPrefix(names, Tuils.DOUBLE_SPACE);
-        Tuils.insertHeaders(names, false);
-        return Tuils.toPlanString(names);
-    }
-
-    @Override
-    public int helpRes() {
-        return R.string.help_tracks;
-    }
-
-    @Override
-    public int minArgs() {
-        return 0;
-    }
-
-    @Override
-    public int maxArgs() {
-        return 0;
-    }
-
-    @Override
-    public int[] argType() {
-        return new int[0];
-    }
-
-    @Override
-    public int priority() {
-        return 2;
-    }
-
-    @Override
-    public String onNotArgEnough(ExecutePack info, int nArgs) {
-        return null;
-    }
-
-    @Override
-    public String onArgNotFound(ExecutePack info, int index) {
-        return null;
-    }
-}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tui.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tui.java
index f1060a565d2d596cb012a1b485c93234bb1b5f4a..01da49d2725ba4b0b76d1df5e30085ece6364347 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
@@ -45,6 +45,27 @@ public class tui extends ParamCommand {
                 return info.res.getString(R.string.version_label) + Tuils.SPACE + BuildConfig.VERSION_NAME + Tuils.NEWLINE + Tuils.NEWLINE + info.res.getString(R.string.output_about);
             }
         },
+        telegram {
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://t.me/tuilauncher"));
+                return null;
+            }
+        },
+        googlep {
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://plus.google.com/communities/103936578623101446195"));
+                return null;
+            }
+        },
+        twitter {
+            @Override
+            public String exec(ExecutePack pack) {
+                pack.context.startActivity(Tuils.webPage("https://twitter.com/tui_launcher"));
+                return null;
+            }
+        },
         reset {
             @Override
             public String exec(ExecutePack pack) {
@@ -55,14 +76,6 @@ public class tui extends ParamCommand {
         folder {
             @Override
             public String exec(ExecutePack pack) {
-//                Intent intent = new Intent(Intent.ACTION_VIEW);
-//                intent.setData(Uri.fromFile(Tuils.getFolder()));
-//                pack.context.startActivity(intent);
-
-//                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
-//                Uri uri = Uri.parse(Tuils.getFolder().getAbsolutePath());
-//                intent.setDataAndType(uri, "*/*");
-//                pack.context.startActivity(Intent.createChooser(intent, "Open folder"));
 
                 Uri selectedUri = Uri.parse(Tuils.getFolder().getAbsolutePath());
                 Intent intent = new Intent(Intent.ACTION_VIEW);
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 f77cda65eb5ef35f887acd766a176c89ff727865..be3ff2ea4a1b42c00df439c67cb39a676999eb98 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
@@ -12,6 +12,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -48,26 +49,42 @@ public class AliasManager implements Reloadable {
     public String[] getAlias(String alias, boolean supportSpaces) {
         if(supportSpaces) {
 
-            String[] split = alias.split(Tuils.SPACE);
-            String name = Tuils.EMPTYSTRING;
-
-            for(int count = 0; count < split.length; count++) {
-                name += Tuils.SPACE + split[count];
-                name = name.trim();
-
-                String a = aliases.get(name);
-
-                if(a != null) {
-                    String residual = Tuils.EMPTYSTRING;
-                    for(int c = count + 1; c < split.length; c++) {
-                        residual += split[c] + Tuils.SPACE;
-                    }
-
-                    return new String[] {a, name, residual.trim()};
+//            String[] split = alias.split(Tuils.SPACE);
+//            String name = Tuils.EMPTYSTRING;
+//
+//            for(int count = 0; count < split.length; count++) {
+//                name += Tuils.SPACE + split[count];
+//                name = name.trim();
+//
+//                String a = aliases.get(name);
+//
+//                if(a != null) {
+//                    String residual = Tuils.EMPTYSTRING;
+//                    for(int c = count + 1; c < split.length; c++) {
+//                        residual += split[c] + Tuils.SPACE;
+//                    }
+//
+//                    return new String[] {a, name, residual.trim()};
+//                }
+//            }
+
+            String args = Tuils.EMPTYSTRING;
+
+            String aliasValue = null;
+            while (true) {
+                aliasValue = aliases.get(alias);
+                if(aliasValue != null) break;
+                else {
+                    int index = alias.lastIndexOf(Tuils.SPACE);
+                    if(index == -1) return new String[] {null, null, alias};
+
+                    args = alias.substring(index + 1) + Tuils.SPACE + args;
+                    args = args.trim();
+                    alias = alias.substring(0,index);
                 }
             }
 
-            return new String[] {null, null, alias};
+            return new String[] {aliasValue, alias, args};
         } else {
             return new String[] {aliases.get(alias), alias, Tuils.EMPTYSTRING};
         }
@@ -86,14 +103,14 @@ public class AliasManager implements Reloadable {
         return aliasValue;
     }
 
-    private final Pattern pn = Pattern.compile("%n", Pattern.CASE_INSENSITIVE);
-    private final Pattern pv = Pattern.compile("%v", Pattern.CASE_INSENSITIVE);
-    private final Pattern pa = Pattern.compile("%a", Pattern.CASE_INSENSITIVE);
+    private final Pattern pn = Pattern.compile("%n", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    private final Pattern pv = Pattern.compile("%v", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    private final Pattern pa = Pattern.compile("%a", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
     public String formatLabel(String aliasName, String aliasValue) {
         String a = aliasLabelFormat;
-        a = pn.matcher(a).replaceAll(Tuils.NEWLINE);
-        a = pv.matcher(a).replaceAll(aliasValue);
-        a = pa.matcher(a).replaceAll(aliasName);
+        a = pn.matcher(a).replaceAll(Matcher.quoteReplacement(Tuils.NEWLINE));
+        a = pv.matcher(a).replaceAll(Matcher.quoteReplacement(aliasValue));
+        a = pa.matcher(a).replaceAll(Matcher.quoteReplacement(aliasName));
         return a;
     }
 
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 0bd0bf729780bc6b31473cd4a4ddf7db465e1d0a..b8091768e24a6ca4b1dbd9bb53ca65215bbea81d 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
@@ -32,9 +32,9 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.tuils.InputOutputReceiver;
 import ohi.andre.consolelauncher.tuils.TimeManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
-import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
 import ohi.andre.consolelauncher.tuils.interfaces.Suggester;
 
 import static ohi.andre.consolelauncher.managers.XMLPrefsManager.VALUE_ATTRIBUTE;
@@ -58,8 +58,6 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
     private AppsHolder appsHolder;
     private List<LaunchInfo> hiddenApps;
 
-    private Outputable outputable;
-
     private final String PREFS = "apps";
     private SharedPreferences preferences;
     private SharedPreferences.Editor editor;
@@ -149,13 +147,11 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
         }
     };
 
-    public AppsManager(Context context, Outputable outputable, final Suggester s) {
+    public AppsManager(Context context, final Suggester s) {
         instance = this;
 
         this.context = context;
 
-        this.outputable = outputable;
-
         this.preferences = context.getSharedPreferences(PREFS, 0);
         this.editor = preferences.edit();
 
@@ -350,14 +346,18 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
             LaunchInfo app = new LaunchInfo(packageName, activity, label);
             appsHolder.add(app);
 
-            outputable.onOutput(context.getString(R.string.app_installed) + Tuils.SPACE + packageName);
+            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(outputable == null || appsHolder == null || context == null) return;
+        if(appsHolder == null || context == null) return;
 
-        outputable.onOutput(context.getString(R.string.app_uninstalled) + Tuils.SPACE + packageName);
+        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());
         for(LaunchInfo i : infos) appsHolder.remove(i);
@@ -809,7 +809,7 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement {
             }
         }
 
-        static Pattern activityPattern = Pattern.compile("activity", Pattern.CASE_INSENSITIVE);
+        static Pattern activityPattern = Pattern.compile("activity", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
         public static String insertActivityName(String oldLabel, String activityName) {
             String name;
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalManager.java
similarity index 95%
rename from app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
rename to app/src/main/java/ohi/andre/consolelauncher/managers/TerminalManager.java
index 457685b3595d78f1c2564cd03971c32d4f855cd6..ea9a8b8d06b33af5ac9613f461a92c94d1cc7b7d 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalManager.java
@@ -326,6 +326,25 @@ public class TerminalManager {
         writeToView(output, type);
     }
 
+    public void setOutput(int color, CharSequence output) {
+        if(output == null || output.length() == 0) return;
+
+        if(output.equals(clear.CLEAR)) {
+            clear();
+            return;
+        }
+
+        if(color == SkinManager.COLOR_NOT_SET) {
+            color = mSkinManager.outputColor;
+        }
+
+        SpannableString si = new SpannableString(output);
+        si.setSpan(new ForegroundColorSpan(color), 0, output.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        CharSequence s = TextUtils.concat(Tuils.NEWLINE, si);
+        writeToView(s);
+    }
+
     public void onBackPressed() {
         if(cmdList.size() > 0) {
 
@@ -360,13 +379,17 @@ public class TerminalManager {
     final String FORMAT_PREFIX = "%p";
     final String FORMAT_NEWLINE = "%n";
 
-    private void writeToView(final CharSequence text, final int type) {
+    private void writeToView(CharSequence text, int type) {
+        text = getFinalText(text, type);
+        text = TextUtils.concat(Tuils.NEWLINE, text);
+        writeToView(text);
+    }
+
+    private void writeToView(final CharSequence text) {
         mTerminalView.post(new Runnable() {
             @Override
             public void run() {
-
-                CharSequence s = getFinalText(text, type);
-                mTerminalView.append(TextUtils.concat(Tuils.NEWLINE, s));
+                mTerminalView.append(text);
                 scrollToEnd();
             }
         });
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 48cea170df27c39107a02679ddf772b067c4c6b8..e3b32498847aa673f0cdd8abf1e75d9a70abb7e6 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java
@@ -897,19 +897,13 @@ public class XMLPrefsManager {
         }
     }
 
-    public static Object transform(String s, Class<?> c) {
-        if(s == null) return null;
+    public static Object transform(String s, Class<?> c) throws Exception {
+        if(c == int.class) return Integer.parseInt(s);
+        if(c == Color.class) return Color.parseColor(s);
+        if(c == boolean.class) return Boolean.parseBoolean(s);
+        if(c == String.class) return s;
 
-        try {
-            if(c == int.class) return Integer.parseInt(s);
-            if(c == Color.class) return Color.parseColor(s);
-            if(c == boolean.class) return Boolean.parseBoolean(s);
-            if(c == String.class) return s;
-        } catch (Exception e) {
-            return null;
-        }
-
-        return null;
+        return Tuils.getDefaultValue(c);
     }
 
     static final Pattern p1 = Pattern.compile(">");
@@ -1098,9 +1092,16 @@ public class XMLPrefsManager {
             try {
                 return (T) transform(prefsSave.parent().getValues().get(prefsSave).value, c);
             } catch (Exception e) {
-                return (T) transform(prefsSave.defaultValue(), c);
+
+                try {
+                    return (T) transform(prefsSave.defaultValue(), c);
+                } catch (Exception e1) {
+                    return Tuils.getDefaultValue(c);
+                }
             }
         }
+
+//        this won't ever happen, I think
         return null;
     }
 
@@ -1112,7 +1113,12 @@ public class XMLPrefsManager {
             if(def == null || def.length() == 0) {
                 return SkinManager.COLOR_NOT_SET;
             }
-            return (int) transform(def, Color.class);
+
+            try {
+                return (int) transform(def, Color.class);
+            } catch (Exception e1) {
+                return SkinManager.COLOR_NOT_SET;
+            }
         }
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/music/MusicManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/music/MusicManager.java
deleted file mode 100755
index 0e28f8e6854306b5e49d0ee903e4de8451e01e61..0000000000000000000000000000000000000000
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/music/MusicManager.java
+++ /dev/null
@@ -1,276 +0,0 @@
-package ohi.andre.consolelauncher.managers.music;
-
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.Cursor;
-import android.media.MediaPlayer;
-import android.media.MediaPlayer.OnCompletionListener;
-import android.net.Uri;
-import android.provider.MediaStore;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import ohi.andre.consolelauncher.managers.XMLPrefsManager;
-import ohi.andre.consolelauncher.tuils.Tuils;
-import ohi.andre.consolelauncher.tuils.broadcast.HeadsetBroadcast;
-import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
-
-public class MusicManager implements OnCompletionListener {
-
-    public static final String[] MUSIC_EXTENSIONS = {".mp3", ".wav", ".ogg", ".flac"};
-
-    private List<File> files;
-    private MediaPlayer mp;
-
-    private int currentSongIndex = 0;
-    private File currentSong = null;
-
-    private boolean fromMediastore;
-    File songsFolder;
-
-    private Outputable outputable;
-
-    //	headset broadcast
-    private BroadcastReceiver headsetReceiver = new HeadsetBroadcast(new Runnable() {
-        @Override
-        public void run() {
-            onHeadsetUnplugged();
-        }
-    });
-
-    //	constructor
-    public MusicManager(Context c, Outputable outputable) {
-        try {
-            this.mp = new MediaPlayer();
-            this.mp.setOnCompletionListener(this);
-            this.files = new ArrayList<>();
-
-            this.outputable = outputable;
-
-            c.registerReceiver(headsetReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
-
-            boolean randomActive = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.random_play);
-            fromMediastore = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.songs_from_mediastore);
-            if (fromMediastore) {
-                songsFolder = null;
-            } else {
-                String path = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.songs_folder);
-                if (path == null || path.length() == 0 || path.equals("null")) {
-                    return;
-                }
-                songsFolder = new File(path);
-            }
-
-            refresh(c);
-
-            if (randomActive && files != null) {
-                Collections.shuffle(files);
-            }
-        } catch (Exception e) {}
-    }
-
-    public boolean initPlayer() {
-        return prepareSong(currentSongIndex);
-    }
-
-    public String getPath(String name) {
-        if(files == null) return null;
-
-        int count = 0;
-        File file = files.get(count);
-        while(!file.getName().equals(name)) {
-            if(count == files.size()) {
-                return null;
-            }
-            file = files.get(++count);
-        }
-        return file.getAbsolutePath();
-    }
-
-    //	return listNames
-    public List<String> getNames() {
-        if(files == null) {
-            return new ArrayList<>(0);
-        }
-
-        List<String> names = new ArrayList<>();
-
-        for (File file : files) {
-            names.add(file.getName());
-        }
-
-        Collections.sort(names);
-
-        return names;
-    }
-
-    //	return paths
-    public List<String> getPaths() {
-        if(files == null) {
-            return new ArrayList<>();
-        }
-
-        List<String> paths = new ArrayList<>();
-
-        for (File file : files)
-            paths.add(file.getAbsolutePath());
-
-        return paths;
-    }
-
-    public boolean isPlaying() {
-        try {
-            return mp.isPlaying();
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    private boolean prepareSong(int songIndex) {
-        if (files == null) {
-            return false;
-        }
-
-        List<String> songs = getPaths();
-        if(songs == null || songs.size() == 0) {
-            return false;
-        }
-
-        if (songIndex >= songs.size())
-            songIndex -= songs.size();
-        else if (songIndex < 0) {
-            songIndex += songs.size();
-        }
-
-        currentSongIndex = songIndex;
-
-        return prepareSong(songs.get(songIndex));
-    }
-
-    private boolean prepareSong(String path) {
-        if (path == null || path.length() == 0)
-            return false;
-
-        currentSong = new File(path);
-
-        try {
-            mp.reset();
-            mp.setDataSource(path);
-            mp.prepare();
-        } catch (Exception e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public boolean jukebox(String path) {
-        if (!prepareSong(path))
-            return false;
-
-        mp.start();
-        return true;
-    }
-
-    public String next() throws IllegalStateException {
-        if (!prepareSong(currentSongIndex + 1))
-            return null;
-
-        mp.start();
-        return currentSong.getName();
-    }
-
-    public String prev() throws IllegalStateException {
-        if (!prepareSong(currentSongIndex - 1))
-            return null;
-
-        mp.start();
-        return currentSong.getName();
-    }
-
-    public void stop() {
-        if (mp.isPlaying())
-            mp.stop();
-    }
-
-    public String trackInfo() {
-        int total = mp.getDuration() / 1000;
-        int position = mp.getCurrentPosition() / 1000;
-        return currentSong.getName() +
-                Tuils.NEWLINE + (total / 60) + "." + (total % 60) + " / " + (position / 60) + "." + (position % 60) +
-                " (" + (100 * position / total) + "%)";
-    }
-
-    public void refresh(Context c) {
-        if(fromMediastore) {
-            fillFromMediaStore(c, files);
-        } else {
-            fillFromDir(files, songsFolder);
-        }
-    }
-
-    private static void fillFromMediaStore(final Context c, final List<File> files) {
-        files.clear();
-
-        new Thread() {
-            @Override
-            public void run() {
-                ContentResolver cr = c.getContentResolver();
-
-                Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
-                String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
-                String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
-                Cursor cur = cr.query(uri, null, selection, null, sortOrder);
-                int count = 0;
-
-                if(cur != null) {
-                    count = cur.getCount();
-                    if(count > 0) {
-                        while(cur.moveToNext()) {
-                            String data = cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.DATA));
-                            if(data != null) {
-                                try {
-                                    files.add(new File(data));
-                                } catch (Exception e) {}
-                            }
-                        }
-                    }
-
-                    cur.close();
-                }
-            }
-        }.start();
-    }
-
-    private static void fillFromDir(final List<File> files, final File dir) {
-        files.clear();
-
-        new Thread() {
-            @Override
-            public void run() {
-                files.addAll(Tuils.getSongsInFolder(dir));
-            }
-        }.start();
-    }
-
-    @Override
-    public void onCompletion(MediaPlayer mp) {
-        outputable.onOutput(next());
-    }
-
-    public void onHeadsetUnplugged() {
-        if (mp != null && mp.isPlaying())
-            mp.pause();
-    }
-
-    public void destroy(Context context) {
-        this.stop();
-        context.unregisterReceiver(headsetReceiver);
-    }
-}
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 ccbba647e533e0cc97ed6df9c1c3ec0e9931f102..8b3dcf22e806674c28cceb618125f91c4f4006b3 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
@@ -22,6 +22,7 @@ import java.util.regex.Pattern;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
+import ohi.andre.consolelauncher.BuildConfig;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
@@ -299,9 +300,17 @@ public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
     }
 
     public static boolean match(String pkg, String text, String title) {
+        if(pkg.equals(BuildConfig.APPLICATION_ID)) return true;
+
         for(FilterGroup group : groups) {
-            if(group.pkgs == null || !group.pkgs.contains(pkg)) continue;
-            if(group.check(title, text)) return true;
+
+            if(group.pkgs != null && !group.pkgs.contains(pkg)) {
+                continue;
+            }
+
+            if(group.check(title, text)) {
+                return true;
+            }
         }
         return false;
     }
@@ -413,13 +422,16 @@ public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
 
         public boolean check(String title, String text) {
             boolean matchTitle = false, matchText = false;
+            int titleCount = 0, textCount = 0;
 
             for(Filter filter : brothers) {
                 String s;
                 if(filter.on == TITLE) {
                     s = title;
+                    titleCount++;
                 } else {
                     s = text;
+                    textCount++;
                 }
 
                 boolean b = filter.pattern.matcher(s).find();
@@ -428,6 +440,9 @@ public class NotificationManager implements XMLPrefsManager.XmlPrefsElement {
                 else matchText = matchText || b;
             }
 
+            matchTitle = matchTitle || titleCount == 0;
+            matchText = matchText || textCount == 0;
+
             return matchText && matchTitle;
         }
 
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 b54ffbab1690e8ec0d361ac8747d2deb5f3f5ffc..cbc02dc18bcd993bb9777d3c5faad163655f57d9 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
@@ -22,6 +22,7 @@ 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.XMLPrefsManager;
@@ -87,11 +88,11 @@ public class NotificationService extends NotificationListenerService {
     String format;
     int timeColor;
 
-    final Pattern patternPkg = Pattern.compile("%pkg", Pattern.CASE_INSENSITIVE);
-    final Pattern patternText = Pattern.compile("%txt", Pattern.CASE_INSENSITIVE);
-    final Pattern patternTitle = Pattern.compile("%ttl", Pattern.CASE_INSENSITIVE);
-    final Pattern patternAppname = Pattern.compile("%app", Pattern.CASE_INSENSITIVE);
-    final Pattern patternNewline = Pattern.compile("%n", Pattern.CASE_INSENSITIVE);
+    final Pattern patternPkg = Pattern.compile("%pkg", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    final Pattern patternText = Pattern.compile("%txt", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    final Pattern patternTitle = Pattern.compile("%ttl", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    final Pattern patternAppname = Pattern.compile("%app", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    final Pattern patternNewline = Pattern.compile("%n", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
 
     PackageManager manager;
 
@@ -161,11 +162,11 @@ public class NotificationService extends NotificationListenerService {
         }
 
         String finalText = format;
-        finalText = patternPkg.matcher(finalText).replaceAll(pack);
-        finalText = patternAppname.matcher(finalText).replaceAll(appName);
-        finalText = patternText.matcher(finalText).replaceAll(text);
-        finalText = patternTitle.matcher(finalText).replaceAll(title);
-        finalText = patternNewline.matcher(finalText).replaceAll(Tuils.NEWLINE);
+        finalText = patternPkg.matcher(finalText).replaceAll(Matcher.quoteReplacement(pack));
+        finalText = patternAppname.matcher(finalText).replaceAll(Matcher.quoteReplacement(appName));
+        finalText = patternText.matcher(finalText).replaceAll(Matcher.quoteReplacement(text));
+        finalText = patternTitle.matcher(finalText).replaceAll(Matcher.quoteReplacement(title));
+        finalText = patternNewline.matcher(finalText).replaceAll(Matcher.quoteReplacement(Tuils.NEWLINE));
 
         SpannableString spannableString = new SpannableString(finalText);
         spannableString.setSpan(new ForegroundColorSpan(color), 0, finalText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
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 f55f3717dcb7b9b1fa493b3fb56af4bce05a52a1..29e40c32ba5a5c61e5f202e661487ab8b28c5a18 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
@@ -381,21 +381,14 @@ public class SuggestionsManager {
     }
 
     private void suggestSong(MainPack info, List<Suggestion> suggestions, String prev, String before) {
+        Tuils.log(info.player.getTitles().toString());
         if (prev == null || prev.length() == 0) {
-            for (String s : info.player.getNames())
+            for (String s : info.player.getTitles()) {
                 suggestions.add(new Suggestion(before, s, clickToLaunch, NO_RATE, Suggestion.TYPE_SONG));
+            }
         }
-//        else if(prev.length() <= FIRST_INTERVAL) {
-//            prev = prev.trim().toLowerCase();
-//            List<String> names = info.player.getNames();
-//            for (String n : names) {
-//                if(n.toLowerCase().trim().startsWith(prev)) {
-//                    suggestions.add(new Suggestion(before, n, true, MAX_RATE, Suggestion.TYPE_SONG));
-//                }
-//            }
-//        }
         else {
-            List<SimpleMutableEntry<String, Integer>> infos = Compare.matchesWithRate(info.player.getNames(), prev, true);
+            List<SimpleMutableEntry<String, Integer>> infos = Compare.matchesWithRate(info.player.getTitles(), prev, true);
             for(SimpleMutableEntry<String, Integer> i : infos) {
                 suggestions.add(new Suggestion(before, i.getKey(), clickToLaunch, i.getValue(), Suggestion.TYPE_SONG));
             }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java
index 8b893c006d59644e0a6a534e24341da00196492e..94070c7bdb9652d24b5e56e2da48ecccd38f2df4 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/KeeperService.java
@@ -3,17 +3,19 @@ package ohi.andre.consolelauncher.tuils;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
+import android.os.Build;
 import android.os.IBinder;
 import android.support.v4.app.NotificationCompat;
-import android.util.Log;
+import android.support.v4.app.RemoteInput;
 
 import ohi.andre.consolelauncher.LauncherActivity;
 import ohi.andre.consolelauncher.R;
 
 public class KeeperService extends Service {
 
-    private final int ONGOING_NOTIFICATION_ID = 1001;
+    public static final int ONGOING_NOTIFICATION_ID = 1001;
 
     @Override
     public IBinder onBind(Intent intent) {
@@ -21,33 +23,50 @@ public class KeeperService extends Service {
     }
 
     @Override
-    public void onStart(Intent intent, int startId) {
-        super.onStart(intent, startId);
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        startForeground(ONGOING_NOTIFICATION_ID, buildNotification(getApplicationContext()));
+        return super.onStartCommand(intent, flags, startId);
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        return true;
+    }
 
-        Intent resultIntent = new Intent(this, LauncherActivity.class);
+    public static Notification buildNotification(Context c) {
+        Intent resultIntent = new Intent(c, LauncherActivity.class);
         PendingIntent resultPendingIntent = PendingIntent.getActivity(
-                this,
+                c,
                 0,
                 resultIntent,
                 PendingIntent.FLAG_UPDATE_CURRENT
         );
 
-        Notification notification = new NotificationCompat.Builder(this)
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(c)
                 .setSmallIcon(R.mipmap.ic_launcher)
-                .setTicker(getString(R.string.start_notification))
+                .setTicker(c.getString(R.string.start_notification))
                 .setWhen(System.currentTimeMillis())
-                .setContentTitle(getString(R.string.app_name))
-                .setContentText(getString(R.string.tui_running))
-                .setContentIntent(resultPendingIntent)
-                .build();
+                .setContentTitle(c.getString(R.string.app_name))
+                .setContentText(c.getString(R.string.tui_running))
+                .setContentIntent(resultPendingIntent);
 
-        startForeground(ONGOING_NOTIFICATION_ID, notification);
-    }
+        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            String label = "cmd";
+            RemoteInput remoteInput = new RemoteInput.Builder(InputOutputReceiver.TEXT)
+                    .setLabel(label)
+                    .build();
 
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
+            Intent i = new Intent(InputOutputReceiver.ACTION_CMD);
+            i.putExtra(InputOutputReceiver.WAS_KEY, InputOutputReceiver.WAS_KEEPER_SERVICE);
+
+            NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.mipmap.ic_launcher, label,
+                    PendingIntent.getBroadcast(c.getApplicationContext(), 40, i, PendingIntent.FLAG_UPDATE_CURRENT))
+                    .addRemoteInput(remoteInput)
+                    .build();
+
+            builder.addAction(action);
+        }
 
-        Log.e("andre", "destroying keep");
+        return builder.build();
     }
 }
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 3185a36910212eaf15376a69397f6842081e59e3..6c7e8dcc19c6a2b1c673320c855a7b7454d23313 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
@@ -36,6 +36,7 @@ import java.io.InputStreamReader;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.lang.reflect.Array;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.ArrayList;
@@ -43,13 +44,15 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.List;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import dalvik.system.DexFile;
 import ohi.andre.consolelauncher.BuildConfig;
 import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.managers.XMLPrefsManager;
-import ohi.andre.consolelauncher.managers.music.MusicManager;
+import ohi.andre.consolelauncher.managers.music.MusicManager2;
+import ohi.andre.consolelauncher.managers.music.Song;
 import ohi.andre.consolelauncher.tuils.interfaces.OnBatteryUpdate;
 import ohi.andre.consolelauncher.tuils.stuff.FakeLauncherActivity;
 
@@ -109,23 +112,23 @@ public class Tuils {
         }
     }
 
-    public static List<File> getSongsInFolder(File folder) {
-        List<File> songs = new ArrayList<>();
+    public static List<Song> getSongsInFolder(File folder) {
+        List<Song> songs = new ArrayList<>();
 
         File[] files = folder.listFiles();
         if(files == null || files.length == 0) {
-            return null;
+            return songs;
         }
 
         for (File file : files) {
             if (file.isDirectory()) {
-                List<File> s = getSongsInFolder(file);
+                List<Song> s = getSongsInFolder(file);
                 if(s != null) {
                     songs.addAll(s);
                 }
             }
-            else if (containsExtension(MusicManager.MUSIC_EXTENSIONS, file.getName())) {
-                songs.add(file);
+            else if (containsExtension(MusicManager2.MUSIC_EXTENSIONS, file.getName())) {
+                songs.add(new Song(file));
             }
         }
 
@@ -176,9 +179,10 @@ public class Tuils {
         c.startActivity(intent);
     }
 
-    public static Intent requestAdmin(ComponentName component) {
+    public static Intent requestAdmin(ComponentName component, String explanation) {
         Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
         intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, component);
+        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, explanation);
         return intent;
     }
 
@@ -373,16 +377,16 @@ public class Tuils {
         return -1;
     }
 
-    static Pattern pd = Pattern.compile("%d", Pattern.CASE_INSENSITIVE);
-    static Pattern pu = Pattern.compile("%u", Pattern.CASE_INSENSITIVE);
-    static Pattern pp = Pattern.compile("%p", Pattern.CASE_INSENSITIVE);
+    static Pattern pd = Pattern.compile("%d", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    static Pattern pu = Pattern.compile("%u", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
+    static Pattern pp = Pattern.compile("%p", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
     public static String getHint(SkinManager skinManager, String currentPath) {
         String format = skinManager.ssnInfoFormat;
         if(format.length() == 0) return null;
 
-        format = pd.matcher(format).replaceAll(skinManager.deviceName);
-        format = pu.matcher(format).replaceAll(skinManager.username);
-        format = pp.matcher(format).replaceAll(Tuils.getNicePath(currentPath));
+        format = pd.matcher(format).replaceAll(Matcher.quoteReplacement(skinManager.deviceName));
+        format = pu.matcher(format).replaceAll(Matcher.quoteReplacement(skinManager.username));
+        format = pp.matcher(format).replaceAll(Matcher.quoteReplacement(Tuils.getNicePath(currentPath)));
 
         return format;
     }
@@ -451,6 +455,10 @@ public class Tuils {
         }
     }
 
+    public static <T> T getDefaultValue(Class<T> clazz) {
+        return (T) Array.get(Array.newInstance(clazz, 1), 0);
+    }
+
     public static void toFile(Throwable e) {
         try {
             FileOutputStream out = new FileOutputStream(new File(Tuils.getFolder(), "crash.txt"), true);
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java
index e0d8d0e7052d3dfcee14c46016f56ce0869e8377..d9a82bb289ed2e4e74ee3ce1843c3da87984dd3a 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java
@@ -7,4 +7,5 @@ public interface CommandExecuter {
 
     String exec(String aliasValue, String aliasName);
     String exec(String input);
+    String exec(String input, boolean needWriteInput);
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Outputable.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Outputable.java
index bbefb557a069b9a697f956b59fb63860ced0146b..dd41e2af3383b394eab94e5aad1203a2378f770e 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Outputable.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Outputable.java
@@ -5,5 +5,6 @@ package ohi.andre.consolelauncher.tuils.interfaces;
  */
 public interface Outputable {
     void onOutput(CharSequence output, int category);
+    void onOutput(int color, CharSequence output);
     void onOutput(CharSequence output);
 }
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 73223638d55edf5bab82cedc8be7595dd51d3961..ea69ed0999eecd94376e4273c7f60eb9ce20574f 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -11,6 +11,7 @@
     <string name="start_notification">T-UI started</string>
     <string name="tui_running">T-UI is running</string>
     <string name="anr">t-ui is having some issues. Please send to the developer your file crash.txt in the "t-ui" folder</string>
+    <string name="admin_permission">Lock the screen on double tap</string>
 
     <!-- files -->
     <string name="output_error">An unknown error has occurred</string>
@@ -75,10 +76,7 @@
     <!-- music -->
     <string name="output_playing">Playing:</string>
     <string name="output_stopped">Player stopped</string>
-    <string name="output_nomusic">Player wasn\'t started</string>
-    <string name="output_cantstop">Couldn\'t stop the player. Force stop t-ui from settings</string>
-    <string name="output_musicfoldererror">Music folder doesn\'t exist, or doesn\'t contain audio files.\nYou should set the right path with "config -set songs_path"
-    </string>
+    <string name="output_songnotfound">Song not found</string>
 
     <!-- command/args -->
     <string name="output_commandnotfound">Command not found.\nTry to use \">>help\" or \">>tutorial\"</string>
@@ -138,7 +136,6 @@
     <string name="help_call">Make a call
         \nUsage: call [number] OR [contactName]
     </string>
-    <string name="help_community">Show the t-ui community on Google+</string>
     <string name="help_config">Manage your config files.
         \nUsage:
         \n-set [option] [value] -> set the value of an option
@@ -158,6 +155,15 @@
         \nUsage:
         \n>>listen [songName]
     </string>
+    <string name="help_music">Usage:
+        \n-next -> play the next song in the queue
+        \n-previous -> play the previous song in the queue
+        \n-play -> play/pause
+        \n-stop -> stop the player
+        \n-ls -> list your tracks
+        \n-select [song] -> play the selected song
+        \n-info -> get info about the current song
+        \n-seekto [seconds] -> seek to the selected part of the current song</string>
     <string name="help_previous">Play the last played track</string>
     <string name="help_rate">Leave a feedback on the Play Store page</string>
     <string name="help_refresh">Refresh apps, alias, music, contacts</string>
@@ -191,6 +197,9 @@
         \n-rm -> remove t-ui
         \n-about -> show info about the developer and the current version</string>
         \n-reset -> removes the t-ui folder and resets default settings (restart required)
+        \n-twitter -> show t-ui Twitter page
+        \n-googlep -> show the community on Google+
+        \n-telegram -> open the official Telegram group
         \n-folder -> print the path of the t-ui folder
     <string name="help_tutorial">Open the tutorial page on GitHub</string>
     <string name="help_uninstall">Uninstall an application