From f6f19b63f0d7b78a11b9a8e6807dcae7664d1351 Mon Sep 17 00:00:00 2001
From: Francesco Andreuzzi <andreuzzi.francesco@gmail.com>
Date: Sat, 11 Mar 2017 22:56:52 +0100
Subject: [PATCH] 5.2.1

---
 app/build.gradle                              |   6 +-
 app/src/main/AndroidManifest.xml              |  62 +++++++-
 .../consolelauncher/LauncherActivity.java     |  55 +++-----
 .../andre/consolelauncher/MainManager.java    |  53 ++++++-
 .../ohi/andre/consolelauncher/UIManager.java  |  95 ++++++++++---
 .../consolelauncher/commands/Command.java     |   4 -
 .../commands/CommandAbstraction.java          |   1 +
 .../commands/CommandTuils.java                |  13 +-
 .../consolelauncher/commands/ExecutePack.java |   2 -
 .../commands/main/MainPack.java               |  15 +-
 .../commands/main/raw/apps.java               |  30 +---
 .../commands/main/raw/calc.java               |   2 +-
 .../consolelauncher/commands/main/raw/cp.java |   2 +-
 .../commands/main/raw/data.java               |   3 -
 .../commands/main/raw/flash.java              |  29 ++--
 .../commands/main/raw/hideapp.java            |  76 ++++++++++
 .../consolelauncher/commands/main/raw/mv.java |   2 +-
 .../commands/main/raw/open.java               |   2 +-
 .../consolelauncher/commands/main/raw/rm.java |   2 +-
 .../commands/main/raw/search.java             |   1 -
 .../commands/main/raw/sms.java                | 133 ++++++++++++++++++
 .../commands/main/raw/tuixt.java              |   2 +-
 .../commands/main/raw/unhideapp.java          |  75 ++++++++++
 .../PermanentSuggestionCommand.java           |   4 +-
 .../commands/specific/RedirectCommand.java    |  26 ++++
 .../commands/tuixt/TuixtActivity.java         |  91 ++++++------
 .../managers/AliasManager.java                |   3 -
 .../consolelauncher/managers/AppsManager.java |  89 ++++++++----
 .../managers/MusicManager.java                |   7 +
 .../managers/PreferencesManager.java          |   6 +-
 .../consolelauncher/managers/SkinManager.java |  93 +++---------
 .../managers/TerminalMAnager.java             | 106 ++++++++------
 .../suggestions/SuggestionsManager.java       |  35 ++++-
 .../andre/consolelauncher/tuils/Animator.java |   7 -
 .../andre/consolelauncher/tuils/Tuils.java    |  59 +++++---
 .../interfaces/OnRedirectionListener.java     |  13 ++
 .../tuils/interfaces/Redirectator.java        |  13 ++
 .../tuils/tutorial/TutorialActivity.java      |   2 +
 app/src/main/res/layout/input_down_layout.xml |   1 +
 .../main/res/layout/suggestions_layout.xml    |   5 +-
 app/src/main/res/raw/settings.txt             |   3 +-
 app/src/main/res/values/colors.xml            |   2 +
 app/src/main/res/values/strings.xml           |  59 ++++----
 app/src/main/res/values/styles.xml            |  19 ++-
 build.gradle                                  |   2 +-
 45 files changed, 923 insertions(+), 387 deletions(-)
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java
 rename app/src/main/java/ohi/andre/consolelauncher/commands/{ => specific}/PermanentSuggestionCommand.java (62%)
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/commands/specific/RedirectCommand.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnRedirectionListener.java
 create mode 100644 app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Redirectator.java

diff --git a/app/build.gradle b/app/build.gradle
index c9f423f..8c55618 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@ android {
         minSdkVersion 8
         targetSdkVersion 23
 
-        versionCode 86
-        versionName "5.1"
+        versionCode 88
+        versionName "5.2.1"
     }
 
     buildTypes {
@@ -28,7 +28,7 @@ android {
     }
 
     dependencies {
-        compile 'com.android.support:appcompat-v7:23.2.0'
+        compile 'com.android.support:appcompat-v7:23.4.0'
         compile 'com.github.Andre1299:CompareString:1.4.2'
     }
 
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f4d1dba..6ccc615 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,6 +17,7 @@
     <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.CALL_PHONE" />
+    <uses-permission android:name="android.permission.SEND_SMS" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@@ -94,10 +95,69 @@
         <activity
             android:name=".commands.tuixt.TuixtActivity"
             android:theme="@style/Custom.Solid"
-            android:windowSoftInputMode="stateAlwaysVisible|adjustResize">
+            android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
+            android:label="@string/tuixt_label">
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value=".LauncherActivity" />
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <action android:name="android.intent.action.EDIT"/>
+                <data android:mimeType="text/*"/>
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.EDIT" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.js"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.htm"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.html"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.xhtml"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.php"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.ini"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.sh"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.log"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.db"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.conf"
+                    android:scheme="file" />
+                <data
+                    android:host="*"
+                    android:pathPattern=".*\\.cfg"
+                    android:scheme="file" />
+            </intent-filter>
+
         </activity>
 
         <activity android:name=".tuils.tutorial.TutorialActivity"
diff --git a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
index ee319a7..bac18e8 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java
@@ -2,7 +2,6 @@ package ohi.andre.consolelauncher;
 
 import android.Manifest;
 import android.annotation.TargetApi;
-import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -11,10 +10,13 @@ import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -36,10 +38,9 @@ import ohi.andre.consolelauncher.tuils.interfaces.Reloadable;
 import ohi.andre.consolelauncher.tuils.stuff.PolicyReceiver;
 import ohi.andre.consolelauncher.tuils.tutorial.TutorialActivity;
 
-public class LauncherActivity extends Activity implements Reloadable {
+public class LauncherActivity extends AppCompatActivity implements Reloadable {
 
     private final String FIRSTACCESS_KEY = "x1";
-    private final int FILEUPDATE_DELAY = 300;
 
     public static final int COMMAND_REQUEST_PERMISSION = 10;
     public static final int STARTING_PERMISSION = 11;
@@ -47,8 +48,6 @@ public class LauncherActivity extends Activity implements Reloadable {
 
     public static final int TUIXT_REQUEST = 10;
 
-    View decorView;
-
     private UIManager ui;
     private MainManager main;
 
@@ -111,8 +110,6 @@ public class LauncherActivity extends Activity implements Reloadable {
             editor.commit();
 
             startActivity(new Intent(this, TutorialActivity.class));
-            this.finish();
-            return;
         }
 
         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@@ -130,7 +127,7 @@ public class LauncherActivity extends Activity implements Reloadable {
 
     private void finishOnCreate() {
 
-        File tuiFolder = getFolder();
+        File tuiFolder = Tuils.getFolder();
         Resources res = getResources();
         starterIntent = getIntent();
 
@@ -139,6 +136,7 @@ public class LauncherActivity extends Activity implements Reloadable {
         } catch (IOException e) {
             this.startActivity(new Intent(this, LauncherActivity.class));
             this.finish();
+            return;
         }
 
         boolean showNotification = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.NOTIFICATION));
@@ -152,16 +150,26 @@ public class LauncherActivity extends Activity implements Reloadable {
         DevicePolicyManager policy = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
         ComponentName component = new ComponentName(this, PolicyReceiver.class);
 
+        fullscreen = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.FULLSCREEN));
+
         boolean useSystemWP = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.USE_SYSTEMWP));
         if (useSystemWP) {
-            setTheme(R.style.Custom_SystemWP);
+            if(fullscreen) {
+                setTheme(R.style.Custom_SystemWP_Fullscreen);
+            } else {
+                setTheme(R.style.Custom_SystemWP);
+            }
         } else {
-            setTheme(R.style.Custom_Solid);
+            if(fullscreen) {
+                setTheme(R.style.Custom_Solid_Fullscreen);
+            } else {
+                setTheme(R.style.Custom_Solid);
+            }
         }
 
         openKeyboardOnStart = Boolean.parseBoolean(preferencesManager.getValue(PreferencesManager.OPEN_KEYBOARD));
         if (!openKeyboardOnStart) {
-            this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+            this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
         }
 
         setContentView(R.layout.base_view);
@@ -169,6 +177,7 @@ public class LauncherActivity extends Activity implements Reloadable {
         ViewGroup mainView = (ViewGroup) findViewById(R.id.mainview);
         main = new MainManager(this, in, out, preferencesManager, policy, component);
         ui = new UIManager(main.getMainPack(), this, mainView, ex, policy, component, preferencesManager, main.getMainPack());
+        main.setRedirectionListener(ui.buildRedirectionListener());
 
         in.in(Tuils.EMPTYSTRING);
         ui.focusTerminal();
@@ -176,28 +185,10 @@ public class LauncherActivity extends Activity implements Reloadable {
         System.gc();
     }
 
-    private File getFolder() {
-        final File tuiFolder = Tuils.getTuiFolder();
-
-        while (true) {
-            if (tuiFolder != null && (tuiFolder.isDirectory() || tuiFolder.mkdir())) {
-                break;
-            }
-
-            try {
-                Thread.sleep(FILEUPDATE_DELAY);
-            } catch (InterruptedException e) {}
-        }
-
-        return tuiFolder;
-    }
-
     @Override
     protected void onStart() {
         super.onStart();
 
-        overridePendingTransition(0,0);
-
         if (ui != null && openKeyboardOnStart) {
             ui.onStart();
         }
@@ -207,8 +198,6 @@ public class LauncherActivity extends Activity implements Reloadable {
     protected void onPause() {
         super.onPause();
 
-        overridePendingTransition(0,0);
-
         if (ui != null && main != null) {
             ui.pause();
             main.dispose();
@@ -293,6 +282,7 @@ public class LauncherActivity extends Activity implements Reloadable {
                         main.onCommand(info.lastCommand, null);
                     } else {
                         ui.setOutput(getString(R.string.output_nopermissions));
+                        main.sendPermissionNotGrantedWarning();
                     }
                     break;
                 case STARTING_PERMISSION:
@@ -321,6 +311,7 @@ public class LauncherActivity extends Activity implements Reloadable {
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
-        ui.scrollToEnd();
+        if(ui != null) ui.scrollToEnd();
     }
+
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
index 534ba75..d60f8c6 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java
@@ -4,6 +4,7 @@ import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Looper;
 import android.util.Log;
 
 import ohi.andre.consolelauncher.commands.Command;
@@ -11,6 +12,7 @@ import ohi.andre.consolelauncher.commands.CommandGroup;
 import ohi.andre.consolelauncher.commands.CommandTuils;
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.specific.RedirectCommand;
 import ohi.andre.consolelauncher.managers.AliasManager;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
@@ -20,7 +22,9 @@ import ohi.andre.consolelauncher.tuils.ShellUtils;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
 import ohi.andre.consolelauncher.tuils.interfaces.Inputable;
+import ohi.andre.consolelauncher.tuils.interfaces.OnRedirectionListener;
 import ohi.andre.consolelauncher.tuils.interfaces.Outputable;
+import ohi.andre.consolelauncher.tuils.interfaces.Redirectator;
 
 /*Copyright Francesco Andreuzzi
 
@@ -38,6 +42,36 @@ limitations under the License.*/
 
 public class MainManager {
 
+    private RedirectCommand redirect;
+    private Redirectator redirectator = new Redirectator() {
+        @Override
+        public void prepareRedirection(RedirectCommand cmd) {
+            redirect = cmd;
+
+            if(redirectionListener != null) {
+                redirectionListener.onRedirectionRequest(cmd);
+            }
+        }
+
+        @Override
+        public void cleanup() {
+            if(redirect != null) {
+                redirect.beforeObjects.clear();
+                redirect.afterObjects.clear();
+
+                if(redirectionListener != null) {
+                    redirectionListener.onRedirectionEnd(redirect);
+                }
+
+                redirect = null;
+            }
+        }
+    };
+    private OnRedirectionListener redirectionListener;
+    public void setRedirectionListener(OnRedirectionListener redirectionListener) {
+        this.redirectionListener = redirectionListener;
+    }
+
     private final String COMMANDS_PKG = "ohi.andre.consolelauncher.commands.main.raw";
 
     private CmdTrigger[] triggers = new CmdTrigger[]{
@@ -84,7 +118,7 @@ public class MainManager {
         AppsManager appsMgr = new AppsManager(c, Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.COMPARESTRING_APPS)), out);
         AliasManager aliasManager = new AliasManager(prefsMgr);
 
-        mainPack = new MainPack(mContext, prefsMgr, group, aliasManager, appsMgr, music, cont, devicePolicyManager, componentName, c, executer, out);
+        mainPack = new MainPack(mContext, prefsMgr, group, aliasManager, appsMgr, music, cont, devicePolicyManager, componentName, c, executer, out, redirectator);
     }
 
     //    command manager
@@ -92,6 +126,16 @@ public class MainManager {
 
         input = Tuils.removeUnncesarySpaces(input);
 
+        if(redirect != null) {
+            if(!redirect.isWaitingPermission()) {
+                redirect.afterObjects.add(input);
+            }
+            String output = redirect.onRedirect(mainPack);
+            out.onOutput(output);
+
+            return;
+        }
+
         if(alias != null && showAliasValue) {
             out.onOutput(alias + " --> " + "[" + input + "]");
         }
@@ -114,6 +158,10 @@ public class MainManager {
         in.in(Tuils.EMPTYSTRING);
     }
 
+    public void sendPermissionNotGrantedWarning() {
+        redirectator.cleanup();
+    }
+
     //    dispose
     public void dispose() {
         mainPack.dispose();
@@ -225,6 +273,8 @@ public class MainManager {
                 public void run() {
                     super.run();
 
+                    Looper.prepare();
+
                     mainPack.lastCommand = input;
 
                     try {
@@ -243,6 +293,7 @@ public class MainManager {
                             }
                         }
                     } catch (Exception e) {
+                        Log.e("andre", "", e);
                         out.onOutput(e.toString());
                     }
                 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
index 95359dd..118646d 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
@@ -30,15 +30,16 @@ import java.lang.reflect.Field;
 
 import ohi.andre.consolelauncher.commands.ExecutePack;
 import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.specific.RedirectCommand;
 import ohi.andre.consolelauncher.managers.PreferencesManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
-import ohi.andre.consolelauncher.managers.suggestions.SuggestionsManager;
 import ohi.andre.consolelauncher.managers.TerminalManager;
-import ohi.andre.consolelauncher.tuils.ShellUtils;
 import ohi.andre.consolelauncher.managers.suggestions.SuggestionRunnable;
+import ohi.andre.consolelauncher.managers.suggestions.SuggestionsManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
 import ohi.andre.consolelauncher.tuils.interfaces.OnNewInputListener;
+import ohi.andre.consolelauncher.tuils.interfaces.OnRedirectionListener;
 import ohi.andre.consolelauncher.tuils.interfaces.SuggestionViewDecorer;
 import ohi.andre.consolelauncher.tuils.stuff.TrashInterfaces;
 
@@ -74,6 +75,7 @@ public class UIManager implements OnTouchListener {
         }
     };
 
+    private boolean showSuggestions;
     private LinearLayout suggestionsView;
     private SuggestionViewDecorer suggestionViewDecorer;
     private SuggestionRunnable suggestionRunnable;
@@ -100,7 +102,7 @@ public class UIManager implements OnTouchListener {
 
         @Override
         public void onTextChanged(CharSequence s, int st, int b, int c) {
-            if (suggestionsView == null || suggestionsManager == null) {
+            if (suggestionsView == null || suggestionsManager == null || !showSuggestions) {
                 return;
             }
 
@@ -114,8 +116,7 @@ public class UIManager implements OnTouchListener {
         }
 
         @Override
-        public void afterTextChanged(Editable s) {
-        }
+        public void afterTextChanged(Editable s) {}
     };
 
     private boolean executeOnSuggestionClick;
@@ -253,17 +254,17 @@ public class UIManager implements OnTouchListener {
 
         this.info.skinManager = skinManager;
 
-        if (!skinManager.getUseSystemWp()) {
-            rootView.setBackgroundColor(skinManager.getBgColor());
+        if (!skinManager.useSystemWp) {
+            rootView.setBackgroundColor(skinManager.bgColor);
         }
 
         ram = (TextView) rootView.findViewById(R.id.ram_tv);
         TextView deviceInfo = (TextView) rootView.findViewById(R.id.deviceinfo_tv);
         boolean showRam = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOWRAM));
         if (showRam) {
-            ram.setTextColor(skinManager.getRamColor());
+            ram.setTextColor(skinManager.ramColor);
             ram.setTextSize(skinManager.getRamSize());
-            ram.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
+            ram.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
 
             memory = new ActivityManager.MemoryInfo();
             activityManager = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
@@ -277,16 +278,15 @@ public class UIManager implements OnTouchListener {
 
         boolean showDevice = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.SHOWDEVICE));
         if (showDevice) {
-            String deviceName = getDeviceName(prefsMgr);
+            String deviceName = skinManager.deviceName;
 
             deviceInfo.setText(deviceName);
-            deviceInfo.setTextColor(skinManager.getDeviceColor());
+            deviceInfo.setTextColor(skinManager.deviceColor);
             deviceInfo.setTextSize(skinManager.getDeviceSize());
 
-            deviceInfo.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
+            deviceInfo.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
         } else {
             deviceInfo.setVisibility(View.GONE);
-            deviceInfo = null;
         }
 
         final boolean inputBottom = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.INPUTFIELD_BOTTOM));
@@ -328,10 +328,24 @@ public class UIManager implements OnTouchListener {
             pasteView = (ImageButton) inputOutputView.findViewById(R.id.paste_view);
         }
 
-        if (skinManager.getShowSuggestions()) {
+        if (skinManager.showSuggestions) {
+            showSuggestions = true;
+
+            HorizontalScrollView sv = (HorizontalScrollView) rootView.findViewById(R.id.suggestions_container);
+            sv.setFocusable(false);
+            sv.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+                @Override
+                public void onFocusChange(View v, boolean hasFocus) {
+                    if(hasFocus) {
+                        v.clearFocus();
+                    }
+                }
+            });
+
             executeOnSuggestionClick = Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.EXECUTE_ON_SUGGESTION_CLICK));
 
             suggestionsView = (LinearLayout) rootView.findViewById(R.id.suggestions_group);
+
             inputView.addTextChangedListener(textWatcher);
 
             suggestionsManager = new SuggestionsManager(prefsMgr);
@@ -342,8 +356,12 @@ public class UIManager implements OnTouchListener {
                     TextView textView = new TextView(mContext);
                     textView.setOnClickListener(clickListener);
 
-                    textView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
-                    textView.setTextColor(skinManager.getSuggestionTextColor());
+                    textView.setFocusable(false);
+                    textView.setLongClickable(false);
+                    textView.setClickable(true);
+
+                    textView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
+                    textView.setTextColor(skinManager.suggestionTextColor);
                     textView.setTextSize(skinManager.getSuggestionSize());
 
                     textView.setPadding(SkinManager.SUGGESTION_PADDING_HORIZONTAL, SkinManager.SUGGESTION_PADDING_VERTICAL,
@@ -355,6 +373,7 @@ public class UIManager implements OnTouchListener {
                 }
             };
         } else {
+            showSuggestions = false;
             rootView.findViewById(R.id.suggestions_group).setVisibility(View.GONE);
             this.textWatcher = null;
             this.clickListener = null;
@@ -412,13 +431,17 @@ public class UIManager implements OnTouchListener {
         mTerminalAdapter.setOutput(string);
     }
 
-    //    get device name
-    private String getDeviceName(PreferencesManager preferencesManager) {
-        String name = preferencesManager.getValue(PreferencesManager.DEVICENAME);
-        if (name == null || name.length() == 0 || name.equals("null")) {
-            return Build.MODEL;
-        } else {
-            return name;
+    public void disableSuggestions() {
+        if(suggestionsView != null) {
+            showSuggestions = false;
+            suggestionsView.setVisibility(View.GONE);
+        }
+    }
+
+    public void enableSuggestions() {
+        if(suggestionsView != null) {
+            showSuggestions = true;
+            suggestionsView.setVisibility(View.VISIBLE);
         }
     }
 
@@ -508,5 +531,31 @@ public class UIManager implements OnTouchListener {
             return v.onTouchEvent(event);
     }
 
+    public OnRedirectionListener buildRedirectionListener() {
+        return new OnRedirectionListener() {
+            @Override
+            public void onRedirectionRequest(final RedirectCommand cmd) {
+                ((Activity) mContext).runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mTerminalAdapter.setHint(mContext.getString(cmd.getHint()));
+                        disableSuggestions();
+                    }
+                });
+            }
+
+            @Override
+            public void onRedirectionEnd(RedirectCommand cmd) {
+                ((Activity) mContext).runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mTerminalAdapter.setDefaultHint();
+                        enableSuggestions();
+                    }
+                });
+            }
+        };
+    }
+
 }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java b/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
index a518fa4..1ea1f24 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/Command.java
@@ -1,10 +1,6 @@
 package ohi.andre.consolelauncher.commands;
 
-import android.content.Context;
 import android.content.res.Resources;
-import android.util.Log;
-
-import java.util.Arrays;
 
 import ohi.andre.consolelauncher.R;
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
index cbeeedd..3dc22dc 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandAbstraction.java
@@ -11,6 +11,7 @@ public interface CommandAbstraction {
     int PLAIN_TEXT = 10;
     int FILE = 11;
     int PACKAGE = 12;
+    int HIDDEN_PACKAGE = 20;
     int CONTACTNUMBER = 13;
     int TEXTLIST = 14;
     int SONG = 15;
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 9efde31..0e9b02d 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java
@@ -1,13 +1,11 @@
 package ohi.andre.consolelauncher.commands;
 
 import android.annotation.SuppressLint;
-import android.util.Log;
 
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Objects;
 
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.managers.AppsManager;
@@ -38,7 +36,6 @@ public class CommandTuils {
         }
 
         String name = CommandTuils.findName(input);
-        Log.e("andre", name);
         if (!Tuils.isAlpha(name))
             return null;
 
@@ -116,6 +113,9 @@ public class CommandTuils {
         else if (type == CommandAbstraction.PACKAGE && info instanceof MainPack) {
             MainPack pack = (MainPack) info;
             return packageName(input, pack.appsManager);
+        } else if (type == CommandAbstraction.HIDDEN_PACKAGE && info instanceof MainPack) {
+            MainPack pack = (MainPack) info;
+            return hiddenPackage(input, pack.appsManager);
         }
 //        will always find a textlist
         else if (type == CommandAbstraction.TEXTLIST) {
@@ -318,7 +318,12 @@ public class CommandTuils {
     }
 
     private static ArgInfo packageName(String input, AppsManager apps) {
-        String packageName = apps.findPackage(input);
+        String packageName = apps.findPackage(input, AppsManager.SHOWN_APPS);
+        return new ArgInfo(packageName, null, packageName != null, 1);
+    }
+
+    private static ArgInfo hiddenPackage(String input, AppsManager apps) {
+        String packageName = apps.findPackage(input, AppsManager.HIDDEN_APPS);
         return new ArgInfo(packageName, null, packageName != null, 1);
     }
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java b/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java
index eb5fa4a..890189e 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/ExecutePack.java
@@ -1,7 +1,5 @@
 package ohi.andre.consolelauncher.commands;
 
-import java.util.Objects;
-
 @SuppressWarnings("deprecation")
 public abstract class ExecutePack {
 
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 b89dec5..99104a2 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/MainPack.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/MainPack.java
@@ -11,9 +11,11 @@ import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.os.Parcel;
+import android.util.Size;
 
 import java.io.File;
 import java.lang.reflect.Method;
+import java.util.List;
 import java.util.Objects;
 
 import ohi.andre.consolelauncher.commands.CommandGroup;
@@ -29,6 +31,7 @@ import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
 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;
 
 /**
@@ -92,9 +95,11 @@ public class MainPack extends ExecutePack {
 
     public String lastCommand;
 
+    public Redirectator redirectator;
+
     public MainPack(Context context, PreferencesManager prefsMgr, CommandGroup commandGroup, AliasManager alMgr, AppsManager appmgr, MusicManager p,
-                       ContactManager c, DevicePolicyManager devicePolicyManager, ComponentName componentName,
-                       Reloadable r, CommandExecuter executeCommand, Outputable outputable) {
+                    ContactManager c, DevicePolicyManager devicePolicyManager, ComponentName componentName,
+                    Reloadable r, CommandExecuter executeCommand, Outputable outputable, Redirectator redirectator) {
         super(commandGroup);
 
         this.outputable = outputable;
@@ -122,6 +127,8 @@ public class MainPack extends ExecutePack {
         this.component = componentName;
 
         this.reloadable = r;
+
+        this.redirectator = redirectator;
     }
 
     public boolean getSu() {
@@ -138,6 +145,10 @@ public class MainPack extends ExecutePack {
         try {
             this.camera = Camera.open();
             this.parameters = this.camera.getParameters();
+            List<Camera.Size> sizes = this.parameters.getSupportedPreviewSizes();
+            if(sizes != null && sizes.size() > 0) {
+                this.parameters.setPreviewSize(sizes.get(0).width, sizes.get(0).height);
+            }
         } catch (Exception e) {
             this.camera = null;
             this.parameters = null;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java
index 8855dbc..ac3ba63 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/apps.java
@@ -15,8 +15,6 @@ import ohi.andre.consolelauncher.tuils.Tuils;
 
 public class apps implements CommandAbstraction {
 
-    private final String HIDE_PARAM = "-h";
-    private final String UNHIDE_PARAM = "-uh";
     private final String SHOWHIDDEN_PARAM = "-sh";
     private final String PLAYSTORE_PARAM = "-ps";
     private final String SETTINGS_PARAM = "-st";
@@ -31,11 +29,7 @@ public class apps implements CommandAbstraction {
             return info.res.getString(helpRes());
         }
 
-        if (param.equals(HIDE_PARAM)) {
-            return hideApp(info, app);
-        } else if (param.equals(UNHIDE_PARAM)) {
-            return unHideApp(info, app);
-        } else if (param.equals(PLAYSTORE_PARAM)) {
+        if (param.equals(PLAYSTORE_PARAM)) {
             openPlaystore(info.context, app);
         } else if (param.equals(SETTINGS_PARAM)) {
             openSettings(info.context, app);
@@ -49,26 +43,6 @@ public class apps implements CommandAbstraction {
         return Tuils.EMPTYSTRING;
     }
 
-    private String hideApp(MainPack info, String app) {
-        SharedPreferences.Editor editor = ((Activity) info.context).getPreferences(0).edit();
-        String result = info.appsManager.hideApp(app);
-        if (result != null) {
-            editor.commit();
-            return result + Tuils.SPACE + info.res.getString(R.string.output_hideapp);
-        } else
-            return info.res.getString(R.string.output_appnotfound);
-    }
-
-    private String unHideApp(MainPack info, String app) {
-        SharedPreferences.Editor editor = ((Activity) info.context).getPreferences(0).edit();
-        String result = info.appsManager.unhideApp(app);
-        if (result != null) {
-            editor.commit();
-            return result + Tuils.SPACE + info.res.getString(R.string.output_unhideapp);
-        } else
-            return info.res.getString(R.string.output_appnotfound);
-    }
-
     private String showHiddenApps(MainPack info) {
         return info.appsManager.printApps(AppsManager.HIDDEN_APPS);
     }
@@ -113,8 +87,6 @@ public class apps implements CommandAbstraction {
     @Override
     public String[] parameters() {
         return new String[]{
-                HIDE_PARAM,
-                UNHIDE_PARAM,
                 SHOWHIDDEN_PARAM,
                 SETTINGS_PARAM,
                 PLAYSTORE_PARAM,
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java
index 3d992e9..a6ab77f 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/calc.java
@@ -3,7 +3,7 @@ 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.PermanentSuggestionCommand;
+import ohi.andre.consolelauncher.commands.specific.PermanentSuggestionCommand;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.tuils.Tuils;
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java
index b03414e..8435e94 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/cp.java
@@ -29,7 +29,7 @@ public class cp implements CommandAbstraction {
             case FileManager.ISFILE:
                 return info.res.getString(R.string.output_isfile);
             case FileManager.IOERROR:
-                return info.res.getString(R.string.output_ioerror);
+                return info.res.getString(R.string.output_error);
             case FileManager.NOT_READABLE:
                 return info.res.getString(R.string.output_noreadable);
             case FileManager.NOT_WRITEABLE:
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java
index 9a2f60e..f58a830 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/data.java
@@ -6,11 +6,8 @@ import android.net.NetworkInfo;
 import android.net.NetworkInfo.State;
 import android.net.wifi.WifiManager;
 import android.os.Build;
-import android.telephony.TelephonyManager;
-import android.util.Log;
 
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java
index 6ce5244..0f8195c 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/flash.java
@@ -25,17 +25,14 @@ public class flash implements CommandAbstraction {
             return info.res.getString(R.string.output_flashlightnotavailable);
         }
 
-        if (info.camera == null) {
+        final boolean flashOn = info.isFlashOn;
+        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
             info.initCamera();
-        }
-
-        if(info.camera == null) {
-            return info.res.getString(R.string.output_problemcamera);
-        }
 
-        final boolean flashOn = info.isFlashOn;
+            if(info.camera == null) {
+                return info.res.getString(R.string.output_problemcamera);
+            }
 
-        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
             new Thread() {
                 @Override
                 public void run() {
@@ -49,7 +46,11 @@ public class flash implements CommandAbstraction {
                             setSurfaceTexture(info.camera);
                         }
 
-                        info.camera.startPreview();
+                        try {
+                            info.camera.startPreview();
+                        } catch (Exception e) {
+                            info.camera.release();
+                        }
                     } else {
                         info.parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
                         info.camera.setParameters(info.parameters);
@@ -58,7 +59,11 @@ public class flash implements CommandAbstraction {
                             detachSurfaceTexture(info.camera);
                         }
 
-                        info.camera.stopPreview();
+                        try {
+                            info.camera.stopPreview();
+                        } catch (Exception e) {
+                            info.camera.release();
+                        }
                     }
                 }
             }.start();
@@ -82,14 +87,14 @@ public class flash implements CommandAbstraction {
     public static void setSurfaceTexture(Camera camera) {
         try {
             camera.setPreviewTexture(new SurfaceTexture(0));
-        } catch (IOException e) {}
+        } catch (Exception e) {}
     }
 
     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
     public static void detachSurfaceTexture(Camera camera) {
         try {
             camera.setPreviewTexture(null);
-        } catch (IOException e) {}
+        } catch (Exception e) {}
     }
 
     @TargetApi(Build.VERSION_CODES.M)
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java
new file mode 100644
index 0000000..a156725
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/hideapp.java
@@ -0,0 +1,76 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+
+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 francescoandreuzzi on 04/03/2017.
+ */
+
+public class hideapp implements CommandAbstraction {
+
+    @Override
+    public String exec(ExecutePack pack) throws Exception {
+        String app = pack.get(String.class, 0);
+        hideApp((MainPack) pack, app);
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 1;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 1;
+    }
+
+    @Override
+    public int[] argType() {
+        return new int[] {CommandAbstraction.PACKAGE};
+    }
+
+    @Override
+    public int priority() {
+        return 2;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_appshide;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack) {
+        MainPack info = (MainPack) pack;
+        return info.res.getString(R.string.output_appnotfound);
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        MainPack info = (MainPack) pack;
+        return info.res.getString(helpRes());
+    }
+
+    @Override
+    public String[] parameters() {
+        return null;
+    }
+
+    private String hideApp(MainPack info, String app) {
+        SharedPreferences.Editor editor = ((Activity) info.context).getPreferences(0).edit();
+        String result = info.appsManager.hideApp(app);
+        if (result != null) {
+            editor.commit();
+            return result + Tuils.SPACE + info.res.getString(R.string.output_hideapp);
+        } else
+            return info.res.getString(R.string.output_appnotfound);
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java
index 24a950e..0b372b8 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/mv.java
@@ -29,7 +29,7 @@ public class mv implements CommandAbstraction {
             case FileManager.ISFILE:
                 return info.res.getString(R.string.output_isfile);
             case FileManager.IOERROR:
-                return info.res.getString(R.string.output_ioerror);
+                return info.res.getString(R.string.output_error);
             case FileManager.NOT_READABLE:
                 return info.res.getString(R.string.output_noreadable);
             case FileManager.NOT_WRITEABLE:
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java
index 6ce4a15..46a5093 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/open.java
@@ -21,7 +21,7 @@ public class open implements CommandAbstraction {
         if (result == FileManager.ISDIRECTORY)
             return info.res.getString(R.string.output_isdirectory);
         if (result == FileManager.IOERROR)
-            return info.res.getString(R.string.output_ioerror);
+            return info.res.getString(R.string.output_error);
 
         return Tuils.EMPTYSTRING;
     }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java
index d8c8c1c..b077c8b 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/rm.java
@@ -27,7 +27,7 @@ public class rm implements CommandAbstraction {
             case FileManager.ISFILE:
                 return info.res.getString(R.string.output_isfile);
             case FileManager.IOERROR:
-                return info.res.getString(R.string.output_ioerror);
+                return info.res.getString(R.string.output_error);
             case FileManager.NOT_WRITEABLE:
                 return info.res.getString(R.string.output_nowriteable);
         }
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 a6c5635..73dbe6f 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
@@ -4,7 +4,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.net.Uri;
-import android.util.Log;
 
 import java.io.File;
 import java.util.ArrayList;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java
new file mode 100644
index 0000000..e2a0a4f
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/sms.java
@@ -0,0 +1,133 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.telephony.SmsManager;
+
+import java.util.List;
+
+import ohi.andre.consolelauncher.LauncherActivity;
+import ohi.andre.consolelauncher.R;
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+import ohi.andre.consolelauncher.commands.main.MainPack;
+import ohi.andre.consolelauncher.commands.specific.RedirectCommand;
+import ohi.andre.consolelauncher.tuils.Tuils;
+
+/**
+ * Created by francescoandreuzzi on 02/03/2017.
+ */
+
+public class sms extends RedirectCommand {
+
+    @Override
+    public String exec(ExecutePack pack) throws Exception {
+        MainPack info = (MainPack) pack;
+        if (ContextCompat.checkSelfPermission(info.context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+
+            ActivityCompat.requestPermissions((Activity) info.context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
+            return info.context.getString(R.string.output_waitingpermission);
+        }
+
+        beforeObjects.add(pack.get(String.class, 0));
+
+        if(afterObjects.size() == 0) {
+            info.redirectator.prepareRedirection(this);
+        } else {
+            return onRedirect(info);
+        }
+
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 1;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 1;
+    }
+
+    @Override
+    public int[] argType() {
+        return new int[] {CommandAbstraction.CONTACTNUMBER};
+    }
+
+    @Override
+    public int priority() {
+        return 3;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_sms;
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack info, int nArgs) {
+        MainPack pack = (MainPack) info;
+        if (ContextCompat.checkSelfPermission(pack.context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions((Activity) pack.context, new String[]{Manifest.permission.READ_CONTACTS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
+            return pack.context.getString(R.string.output_waitingpermission);
+        }
+
+        List<String> contacts = pack.contacts.listNamesAndNumbers();
+        Tuils.addPrefix(contacts, Tuils.DOUBLE_SPACE);
+        Tuils.insertHeaders(contacts, false);
+        return Tuils.toPlanString(contacts);
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack) {
+        MainPack info = (MainPack) pack;
+        return info.res.getString(R.string.output_numbernotfound);
+    }
+
+    @Override
+    public String[] parameters() {
+        return null;
+    }
+
+    @Override
+    public String onRedirect(ExecutePack pack) {
+        MainPack info = (MainPack) pack;
+
+        String number = (String) beforeObjects.get(0);
+        String message = (String) afterObjects.get(0);
+        if(message.length() == 0) {
+            info.redirectator.cleanup();
+            return info.res.getString(R.string.output_smsnotsent);
+        }
+
+        if (ContextCompat.checkSelfPermission(info.context, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions((Activity) info.context, new String[]{Manifest.permission.SEND_SMS}, LauncherActivity.COMMAND_REQUEST_PERMISSION);
+            return info.context.getString(R.string.output_waitingpermission);
+        }
+
+        info.redirectator.cleanup();
+
+        try {
+            SmsManager smsManager = SmsManager.getDefault();
+            smsManager.sendTextMessage(number, null, message, null, null);
+
+            return info.res.getString(R.string.output_smssent);
+        } catch (Exception ex) {
+            return info.res.getString(R.string.output_error);
+        }
+    }
+
+    @Override
+    public int getHint() {
+        return R.string.sms_hint;
+    }
+
+    @Override
+    public boolean isWaitingPermission() {
+        return beforeObjects.size() == 1 && afterObjects.size() == 1;
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java
index a349295..d3fa775 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/tuixt.java
@@ -75,7 +75,7 @@ public class tuixt implements CommandAbstraction {
 
         File file = new File(dirInfo.getCompletePath());
         if(!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
-            return info.res.getString(R.string.output_ioerror);
+            return info.res.getString(R.string.output_error);
         }
 
         try {
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java
new file mode 100644
index 0000000..a3eb3e6
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/unhideapp.java
@@ -0,0 +1,75 @@
+package ohi.andre.consolelauncher.commands.main.raw;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+
+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 francescoandreuzzi on 04/03/2017.
+ */
+
+public class unhideapp implements CommandAbstraction {
+    @Override
+    public String exec(ExecutePack pack) throws Exception {
+        String app = pack.get(String.class, 0);
+        unHideApp((MainPack) pack, app);
+        return null;
+    }
+
+    @Override
+    public int minArgs() {
+        return 1;
+    }
+
+    @Override
+    public int maxArgs() {
+        return 1;
+    }
+
+    @Override
+    public int[] argType() {
+        return new int[] {CommandAbstraction.HIDDEN_PACKAGE};
+    }
+
+    @Override
+    public int priority() {
+        return 2;
+    }
+
+    @Override
+    public int helpRes() {
+        return R.string.help_appsunhide;
+    }
+
+    @Override
+    public String onArgNotFound(ExecutePack pack) {
+        MainPack info = (MainPack) pack;
+        return info.res.getString(R.string.output_appnotfound);
+    }
+
+    @Override
+    public String onNotArgEnough(ExecutePack pack, int nArgs) {
+        MainPack info = (MainPack) pack;
+        return info.res.getString(helpRes());
+    }
+
+    @Override
+    public String[] parameters() {
+        return null;
+    }
+
+    private String unHideApp(MainPack info, String app) {
+        SharedPreferences.Editor editor = ((Activity) info.context).getPreferences(0).edit();
+        String result = info.appsManager.unhideApp(app);
+        if (result != null) {
+            editor.commit();
+            return result + Tuils.SPACE + info.res.getString(R.string.output_unhideapp);
+        } else
+            return info.res.getString(R.string.output_appnotfound);
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/PermanentSuggestionCommand.java b/app/src/main/java/ohi/andre/consolelauncher/commands/specific/PermanentSuggestionCommand.java
similarity index 62%
rename from app/src/main/java/ohi/andre/consolelauncher/commands/PermanentSuggestionCommand.java
rename to app/src/main/java/ohi/andre/consolelauncher/commands/specific/PermanentSuggestionCommand.java
index e620f2f..91c4351 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/PermanentSuggestionCommand.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/specific/PermanentSuggestionCommand.java
@@ -1,4 +1,6 @@
-package ohi.andre.consolelauncher.commands;
+package ohi.andre.consolelauncher.commands.specific;
+
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
 
 /**
  * Created by francescoandreuzzi on 29/01/2017.
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/specific/RedirectCommand.java b/app/src/main/java/ohi/andre/consolelauncher/commands/specific/RedirectCommand.java
new file mode 100644
index 0000000..e7e85bf
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/specific/RedirectCommand.java
@@ -0,0 +1,26 @@
+package ohi.andre.consolelauncher.commands.specific;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ohi.andre.consolelauncher.commands.CommandAbstraction;
+import ohi.andre.consolelauncher.commands.ExecutePack;
+
+/**
+ * Created by francescoandreuzzi on 03/03/2017.
+ */
+
+public abstract class RedirectCommand implements CommandAbstraction {
+
+    public List<Object> beforeObjects = new ArrayList<>();
+    public List<Object> afterObjects = new ArrayList<>();
+
+    public abstract String onRedirect(ExecutePack pack);
+    public abstract int getHint();
+    public abstract boolean isWaitingPermission();
+
+    public void cleanup() {
+        beforeObjects.clear();
+        afterObjects.clear();
+    }
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java
index 3c0ae93..9de3caf 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/commands/tuixt/TuixtActivity.java
@@ -1,54 +1,38 @@
 package ohi.andre.consolelauncher.commands.tuixt;
 
 import android.app.Activity;
-import android.app.ActivityManager;
-import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.graphics.Color;
+import android.content.res.Resources;
 import android.graphics.Typeface;
-import android.os.Build;
+import android.net.Uri;
 import android.os.Bundle;
-import android.os.Handler;
 import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
 import android.text.InputType;
 import android.text.method.ScrollingMovementMethod;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.ScrollView;
 import android.widget.TextView;
 
-import org.w3c.dom.Text;
-
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileReader;
+import java.io.IOException;
 
+import ohi.andre.consolelauncher.LauncherActivity;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.commands.Command;
 import ohi.andre.consolelauncher.commands.CommandGroup;
 import ohi.andre.consolelauncher.commands.CommandTuils;
-import ohi.andre.consolelauncher.commands.tuixt.TuixtPack;
 import ohi.andre.consolelauncher.managers.PreferencesManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
-import ohi.andre.consolelauncher.managers.TerminalManager;
 import ohi.andre.consolelauncher.tuils.Tuils;
-import ohi.andre.consolelauncher.tuils.interfaces.OnNewInputListener;
-import ohi.andre.consolelauncher.tuils.interfaces.SuggestionViewDecorer;
 
 /**
  * Created by francescoandreuzzi on 19/01/2017.
@@ -60,6 +44,8 @@ public class TuixtActivity extends Activity {
 
     public static final int BACK_PRESSED = 2;
 
+    private long lastEnter;
+
     public static String PATH = "path";
     public static String SKIN = "skin";
 
@@ -80,29 +66,35 @@ public class TuixtActivity extends Activity {
 
         final Intent intent = getIntent();
 
-
         String path = intent.getStringExtra(PATH);
         if(path == null) {
-            setResult(0);
-            finish();
-            return;
+            Uri uri = intent.getData();
+            File file = new File(uri.getPath());
+            path = file.getAbsolutePath();
         }
 
         final File file = new File(path);
 
         CommandGroup group = new CommandGroup(this, "ohi.andre.consolelauncher.commands.tuixt.raw");
 
-
         SkinManager skinManager = intent.getParcelableExtra(SKIN);
+        if(skinManager == null) {
+            try {
+                Resources res = getResources();
+                PreferencesManager preferencesManager = new PreferencesManager(res.openRawResource(R.raw.settings), res.openRawResource(R.raw.alias), Tuils.getFolder());
+                skinManager = new SkinManager(preferencesManager);
+            } catch (IOException e) {
+                return;
+            }
+        }
 
-
-        if (!skinManager.getUseSystemWp()) {
-            rootView.setBackgroundColor(skinManager.getBgColor());
+        if (!skinManager.useSystemWp) {
+            rootView.setBackgroundColor(skinManager.bgColor);
         } else {
             setTheme(R.style.Custom_SystemWP);
         }
 
-        final boolean inputBottom = skinManager.getInputBottom();
+        final boolean inputBottom = skinManager.inputBottom;
         int layoutId = inputBottom ? R.layout.tuixt_view_input_down : R.layout.tuixt_view_input_up;
 
         LayoutInflater inflater = getLayoutInflater();
@@ -116,26 +108,26 @@ public class TuixtActivity extends Activity {
         TextView prefixView = (TextView) inputOutputView.findViewById(R.id.prefix_view);
 
         ImageButton submitView = (ImageButton) inputOutputView.findViewById(R.id.submit_tv);
-        boolean showSubmit = skinManager.getShowSubmit();
+        boolean showSubmit = skinManager.showSubmit;
         if (!showSubmit) {
             submitView.setVisibility(View.GONE);
             submitView = null;
         }
 
         String prefix;
-        if(skinManager.linuxAppearence()) {
+        if(skinManager.linuxAppearence) {
             prefix = "$ ";
         } else {
             prefix = ">>";
         }
-        prefixView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
-        prefixView.setTextColor(skinManager.getInputColor());
+        prefixView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
+        prefixView.setTextColor(skinManager.inputColor);
         prefixView.setTextSize(skinManager.getTextSize());
         prefixView.setText(prefix);
 
 
         if (submitView != null) {
-            submitView.setColorFilter(skinManager.getInputColor());
+            submitView.setColorFilter(skinManager.inputColor);
             submitView.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -144,9 +136,9 @@ public class TuixtActivity extends Activity {
             });
         }
 
-        fileView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
+        fileView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
         fileView.setTextSize(skinManager.getTextSize());
-        fileView.setTextColor(skinManager.getOutputColor());
+        fileView.setTextColor(skinManager.outputColor);
         fileView.setOnTouchListener(new View.OnTouchListener() {
             @Override
             public boolean onTouch(View v, MotionEvent event) {
@@ -159,27 +151,38 @@ public class TuixtActivity extends Activity {
             }
         });
 
-        outputView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
+        outputView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
         outputView.setTextSize(skinManager.getTextSize());
-        outputView.setTextColor(skinManager.getOutputColor());
+        outputView.setTextColor(skinManager.outputColor);
         outputView.setMovementMethod(new ScrollingMovementMethod());
         outputView.setVisibility(View.GONE);
 
-        inputView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
+        inputView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
         inputView.setTextSize(skinManager.getTextSize());
-        inputView.setTextColor(skinManager.getInputColor());
+        inputView.setTextColor(skinManager.inputColor);
         inputView.setHint(Tuils.getHint(skinManager, path));
 
         inputView.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
         inputView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
             @Override
             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+//                physical enter
+                if(actionId == KeyEvent.ACTION_DOWN) {
+                    if(lastEnter == 0) {
+                        lastEnter = System.currentTimeMillis();
+                    } else {
+                        long difference = System.currentTimeMillis() - lastEnter;
+                        lastEnter = System.currentTimeMillis();
+                        if(difference < 350) {
+                            return true;
+                        }
+                    }
+                }
 
-                if (actionId == EditorInfo.IME_ACTION_GO || actionId == EditorInfo.IME_ACTION_DONE) {
+                if (actionId == EditorInfo.IME_ACTION_GO || actionId == EditorInfo.IME_ACTION_DONE || actionId == KeyEvent.ACTION_DOWN) {
                     onNewInput();
-                    return true;
-                } else
-                    return false;
+                }
+                return true;
             }
         });
 
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 433603d..aad0aab 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java
@@ -1,12 +1,9 @@
 package ohi.andre.consolelauncher.managers;
 
-import android.util.Log;
-
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.Reloadable;
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 217bef0..c4069e0 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java
@@ -11,10 +11,10 @@ import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.os.Build;
+import android.os.Handler;
 import android.util.Log;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -40,7 +40,6 @@ public class AppsManager {
 
     private Context context;
     private SharedPreferences.Editor prefsEditor;
-    private PackageManager mgr;
 
     private AppsHolder appsHolder;
     private List<AppInfo> hiddenApps;
@@ -63,7 +62,6 @@ public class AppsManager {
 
     public AppsManager(Context context, boolean useCompareString, Outputable outputable) {
         this.context = context;
-        this.mgr = context.getPackageManager();
         this.useCompareString = useCompareString;
 
         this.outputable = outputable;
@@ -85,7 +83,7 @@ public class AppsManager {
     }
 
     public void fill(SharedPreferences preferences) {
-        Map<String, AppInfo> map = createAppMap(mgr);
+        Map<String, AppInfo> map = createAppMap(context.getPackageManager());
         List<AppInfo> shownApps = new ArrayList<>();
         hiddenApps = new ArrayList<>();
 
@@ -143,8 +141,9 @@ public class AppsManager {
 
     private void add(String packageName) {
         try {
-            ApplicationInfo info = mgr.getApplicationInfo(packageName, 0);
-            AppInfo app = new AppInfo(packageName, info.loadLabel(mgr).toString(), 0);
+            PackageManager manager = context.getPackageManager();
+            ApplicationInfo info = manager.getApplicationInfo(packageName, 0);
+            AppInfo app = new AppInfo(packageName, info.loadLabel(manager).toString(), 0);
             appsHolder.add(app);
             outputable.onOutput(context.getString(R.string.app_installed) + Tuils.SPACE + packageName);
         } catch (NameNotFoundException e) {}
@@ -158,13 +157,28 @@ public class AppsManager {
         }
     }
 
-    public String findPackage(String name) {
-        List<AppInfo> apps = appsHolder.getApps();
-        if(apps != null) {
-            apps.addAll(hiddenApps);
-            return findPackage(apps, null, name);
+//    this looks EVERYWHERE!
+//    public String findPackage(String name) {
+//        List<AppInfo> apps = appsHolder.getApps();
+//        if(apps != null) {
+//            apps.addAll(hiddenApps);
+//            return findPackage(apps, null, name);
+//        }
+//        return null;
+//    }
+
+    public String findPackage(String name, int type) {
+        List<AppInfo> appList;
+        List<String> labelList;
+        if(type == SHOWN_APPS) {
+            appList = appsHolder.getApps();
+            labelList = appsHolder.getAppLabels();
+        } else {
+            appList = hiddenApps;
+            labelList = AppUtils.labelList(appList);
         }
-        return null;
+
+        return findPackage(appList, labelList, name);
     }
 
     public String findPackage(List<AppInfo> appList, List<String> labels, String name) {
@@ -195,20 +209,6 @@ public class AppsManager {
         return null;
     }
 
-    public String findPackage(String name, int type) {
-        List<AppInfo> appList;
-        List<String> labelList;
-        if(type == SHOWN_APPS) {
-            appList = appsHolder.getApps();
-            labelList = appsHolder.getAppLabels();
-        } else {
-            appList = hiddenApps;
-            labelList = AppUtils.labelList(appList);
-        }
-
-        return findPackage(appList, labelList, name);
-    }
-
     public Intent getIntent(String packageName) {
         AppInfo info = AppUtils.findAppInfo(packageName, appsHolder.getApps());
         if(info == null) {
@@ -225,7 +225,7 @@ public class AppsManager {
             prefsEditor.commit();
         }
 
-        return mgr.getLaunchIntentForPackage(packageName);
+        return context.getPackageManager().getLaunchIntentForPackage(packageName);
     }
 
     public String hideApp(String packageName) {
@@ -273,6 +273,10 @@ public class AppsManager {
         return appsHolder.getAppLabels();
     }
 
+    public List<String> getHiddenAppsLabels() {
+        return AppUtils.labelList(hiddenApps);
+    }
+
     public String[] getSuggestedApps() {
         return appsHolder.getSuggestedApps();
     }
@@ -351,9 +355,33 @@ public class AppsManager {
             }
         };
 
+//        workaround to check if in suggested apps there are duplicates
+        private Handler handler = new Handler();
+        private Runnable runnable = new Runnable() {
+            @Override
+            public void run() {
+                if(suggestedApps != null) {
+                    if(duplicates()) {
+                        fillSuggestions();
+                    }
+                }
+                handler.postDelayed(runnable, 1000 * 60 * 2);
+            }
+
+            private boolean duplicates() {
+                for (int count =0; count < suggestedApps.length; count++)
+                    for (int count2 = count+1 ; count2 < suggestedApps.length; count2++)
+                        if (count != count2 && suggestedApps[count] == suggestedApps[count2])
+                            return true;
+                return false;
+            }
+        };
+
         public AppsHolder(List<AppInfo> infos) {
             this.infos = infos;
             update(true);
+
+            handler.postDelayed(runnable, 1000 * 60 * 5);
         }
 
         public void add(AppInfo info) {
@@ -413,6 +441,7 @@ public class AppsManager {
         }
 
         private void fillSuggestions() {
+            suggestedApps = new AppInfo[SUGGESTED_APPS_LENGTH];
             for(AppInfo info : infos) {
                 attemptInsertSuggestion(info);
             }
@@ -424,10 +453,8 @@ public class AppsManager {
             }
             for(int count = 0; count < suggestedApps.length; count++) {
                 if(suggestedApps[count] == null) {
-                    if(count == lastNull()) {
-                        suggestedApps[count] = info;
-                        return;
-                    }
+                    suggestedApps[count] = info;
+                    return;
                 } else {
                     if(info.launchedTimes > suggestedApps[count].launchedTimes) {
                         System.arraycopy(suggestedApps, count, suggestedApps, count + 1, suggestedApps.length - (count + 1));
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java
index 85161da..5d83448 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/MusicManager.java
@@ -91,6 +91,10 @@ public class MusicManager implements OnCompletionListener {
 
     //	return names
     public List<String> getNames() {
+        if(files == null) {
+            return new ArrayList<>(0);
+        }
+
         List<String> names = new ArrayList<>();
 
         for (File file : files) {
@@ -104,6 +108,9 @@ public class MusicManager implements OnCompletionListener {
 
     //	return paths
     public List<String> getPaths() {
+        if(files == null) {
+            return new ArrayList<>();
+        }
 
         List<String> paths = new ArrayList<>();
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java
index b5e3c27..35e4608 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/PreferencesManager.java
@@ -1,7 +1,6 @@
 package ohi.andre.consolelauncher.managers;
 
 import android.annotation.SuppressLint;
-import android.util.Log;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -39,6 +38,7 @@ public class PreferencesManager {
     public static final String SHOWUSERNAMEWHENINPUTEMPTY = "showSessionInfoWhenInputEmpty";
     public static final String LINUXAPPERARENCE = "linuxAppearance";
     public static final String SHOWPATH_SESSIONINFO = "showPathInSessionInfo";
+    public static final String SHOWDEVICENAMEINSESSIONINFO = "showDeviceNameInSessionInfo";
 
     public static final String SUGGESTIONTEXT_COLOR = "suggestionTextColor";
     public static final String TRANSPARENT_SUGGESTIONS = "transparentSuggestions";
@@ -67,6 +67,7 @@ public class PreferencesManager {
     public static final String FROM_MEDIASTORE = "fromMediastore";
 
     public static final String USE_SYSTEMWP = "useSystemWallpaper";
+    public static final String FULLSCREEN = "fullscreen";
     public static final String NOTIFICATION = "keepAliveWithNotification";
     public static final String OPEN_KEYBOARD = "openKeyboardOnStart";
     public static final String COMPARESTRING_APPS = "compareStringForApps";
@@ -100,6 +101,9 @@ public class PreferencesManager {
         List<String> list = new ArrayList<>();
 
         File f = open(n);
+        if(f == null) {
+            return new ArrayList<>();
+        }
         FileInputStream fis = new FileInputStream(f);
         BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
 
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
index 6d1f01b..4b2bb37 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/SkinManager.java
@@ -2,6 +2,7 @@ package ohi.andre.consolelauncher.managers;
 
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -30,23 +31,24 @@ public class SkinManager implements Parcelable {
     public static final int fileSuggestionBgDeafult = 0xff03A9F4;
     public static final int defaultSuggestionBgDefault = 0xffFFFFFF;
 
-    public static final int defaultSize = 15;
+    private static final int defaultSize = 15;
     private static final int deviceScale = 3;
     private static final int textScale = 2;
     private static final int ramScale = 3;
     private static final int suggestionScale = 0;
 
-    private int globalFontSize;
+    public int globalFontSize;
 
-    private int deviceColor, inputColor, outputColor, ramColor, bgColor;
+    public String deviceName;
+    public int deviceColor, inputColor, outputColor, ramColor, bgColor;
 
-    private boolean useSystemWp, showSuggestions, systemFont, inputBottom, showSubmit;
+    public boolean useSystemWp, showSuggestions, systemFont, inputBottom, showSubmit;
 
-    private String username = null;
-    private boolean showUsernameAndDeviceWhenEmpty = true, showUsername = false, linuxAppearence = true, showPath = true;
+    public String username = null;
+    public boolean showUsernameAndDeviceWhenEmpty = true, showUsername = false, showDeviceInSessionInfo = false, linuxAppearence = true, showPath = true;
 
-    private int suggestionTextColor, defaulSuggestionColor, appSuggestionColor, aliasSuggestionColor, musicSuggestionColor, contactsSuggestionColor, commandSuggestionColor, fileSuggestionColor;
-    private boolean multicolorSuggestions, transparentSuggestions;
+    public int suggestionTextColor, defaulSuggestionColor, appSuggestionColor, aliasSuggestionColor, musicSuggestionColor, contactsSuggestionColor, commandSuggestionColor, fileSuggestionColor;
+    public boolean multicolorSuggestions, transparentSuggestions;
 
     public SkinManager(PreferencesManager prefs) {
         systemFont = Boolean.parseBoolean(prefs.getValue(PreferencesManager.USE_SYSTEMFONT));
@@ -93,6 +95,15 @@ public class SkinManager implements Parcelable {
             ramColor = ramDefault;
         }
 
+        try {
+            deviceName = prefs.getValue(PreferencesManager.DEVICENAME);
+            if (deviceName == null || deviceName.length() == 0 || deviceName.equals("null")) {
+                deviceName = Build.DEVICE;
+            }
+        } catch (Exception e) {
+            deviceName = Build.DEVICE;
+        }
+
         try {
             showUsernameAndDeviceWhenEmpty = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWUSERNAMEWHENINPUTEMPTY));
             if(showUsernameAndDeviceWhenEmpty) {
@@ -101,6 +112,8 @@ public class SkinManager implements Parcelable {
                     username = prefs.getValue(PreferencesManager.USERNAME);
                 }
 
+                showDeviceInSessionInfo = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWDEVICENAMEINSESSIONINFO));
+
                 showPath = Boolean.parseBoolean(prefs.getValue(PreferencesManager.SHOWPATH_SESSIONINFO));
             }
         } catch (Exception e) {
@@ -188,46 +201,6 @@ public class SkinManager implements Parcelable {
         }
     }
 
-    public boolean getUseSystemFont() {
-        return systemFont;
-    }
-
-    public int getDeviceColor() {
-        return deviceColor;
-    }
-
-    public int getInputColor() {
-        return inputColor;
-    }
-
-    public int getOutputColor() {
-        return outputColor;
-    }
-
-    public int getRamColor() {
-        return ramColor;
-    }
-
-    public int getBgColor() {
-        return bgColor;
-    }
-
-    public boolean getUseSystemWp() {
-        return useSystemWp;
-    }
-
-    public boolean getShowSuggestions() {
-        return showSuggestions;
-    }
-
-    public boolean getInputBottom() {
-        return inputBottom;
-    }
-
-    public boolean getShowSubmit() {
-        return showSubmit;
-    }
-
     public ColorDrawable getSuggestionBg(Integer type) {
         if(transparentSuggestions) {
             type = 0;
@@ -257,10 +230,6 @@ public class SkinManager implements Parcelable {
         }
     }
 
-    public int getSuggestionTextColor() {
-        return suggestionTextColor;
-    }
-
     public int getDeviceSize() {
         return globalFontSize - deviceScale;
     }
@@ -277,26 +246,6 @@ public class SkinManager implements Parcelable {
         return globalFontSize - suggestionScale;
     }
 
-    public String getUsername() {
-        return username;
-    }
-
-    public boolean showUsernameAndDeviceWhenEmpty() {
-        return showUsernameAndDeviceWhenEmpty;
-    }
-
-    public boolean linuxAppearence() {
-        return linuxAppearence;
-    }
-
-    public boolean showUsername() {
-        return showUsername;
-    }
-
-    public boolean showPath() {
-        return showPath;
-    }
-
     @Override
     public int describeContents() {
         return 0;
diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
index 5b70bdd..b986aa0 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/TerminalMAnager.java
@@ -1,12 +1,9 @@
 package ohi.andre.consolelauncher.managers;
 
-import android.content.ClipboardManager;
 import android.content.Context;
 import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
 import android.os.IBinder;
 import android.text.InputType;
-import android.text.Layout;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.method.ScrollingMovementMethod;
@@ -15,21 +12,16 @@ import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageButton;
-import android.widget.ImageView;
 import android.widget.ScrollView;
 import android.widget.TextView;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.commands.main.raw.clear;
-import ohi.andre.consolelauncher.tuils.SimpleMutableEntry;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.OnNewInputListener;
 
@@ -55,11 +47,10 @@ public class TerminalManager {
     public static final int INPUT = 10;
     public static final int OUTPUT = 11;
 
-//    private int globalId = 0;
-//    private int mCurrentOutputId = 0;
-
     private int cmds = 0;
 
+    private long lastEnter;
+
     private CharSequence prefix;
 
     private ScrollView mScrollView;
@@ -85,6 +76,7 @@ public class TerminalManager {
 
     private MainPack mainPack;
 
+    private boolean defaultHint = true;
 
     public TerminalManager(TextView terminalView, EditText inputView, TextView prefixView, ImageButton submitView, final ImageButton backView, ImageButton nextView, ImageButton deleteView,
                            ImageButton pasteView, SkinManager skinManager, final Context context, MainPack mainPack) {
@@ -97,18 +89,18 @@ public class TerminalManager {
         this.mainPack = mainPack;
 
 
-        if(skinManager.linuxAppearence()) {
+        if(skinManager.linuxAppearence) {
             prefix = "$ ";
         } else {
             prefix = ">> ";
         }
-        prefixView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
-        prefixView.setTextColor(this.mSkinManager.getInputColor());
+        prefixView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
+        prefixView.setTextColor(this.mSkinManager.inputColor);
         prefixView.setTextSize(this.mSkinManager.getTextSize());
         prefixView.setText(prefix);
 
         if (submitView != null) {
-            submitView.setColorFilter(mSkinManager.getInputColor());
+            submitView.setColorFilter(mSkinManager.inputColor);
             submitView.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -118,7 +110,7 @@ public class TerminalManager {
         }
 
         if (backView != null) {
-            backView.setColorFilter(this.mSkinManager.getInputColor());
+            backView.setColorFilter(this.mSkinManager.inputColor);
             backView.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -128,7 +120,7 @@ public class TerminalManager {
         }
 
         if (nextView != null) {
-            nextView.setColorFilter(this.mSkinManager.getInputColor());
+            nextView.setColorFilter(this.mSkinManager.inputColor);
             nextView.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -138,7 +130,7 @@ public class TerminalManager {
         }
 
         if (pasteView != null) {
-            pasteView.setColorFilter(this.mSkinManager.getInputColor());
+            pasteView.setColorFilter(this.mSkinManager.inputColor);
             pasteView.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -151,7 +143,7 @@ public class TerminalManager {
         }
 
         if (deleteView != null) {
-            deleteView.setColorFilter(this.mSkinManager.getInputColor());
+            deleteView.setColorFilter(this.mSkinManager.inputColor);
             deleteView.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -161,7 +153,7 @@ public class TerminalManager {
         }
 
         this.mTerminalView = terminalView;
-        this.mTerminalView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
+        this.mTerminalView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
         this.mTerminalView.setTextSize(mSkinManager.getTextSize());
         this.mTerminalView.setFocusable(false);
         setupScroller();
@@ -170,20 +162,30 @@ public class TerminalManager {
 
         this.mInputView = inputView;
         this.mInputView.setTextSize(mSkinManager.getTextSize());
-        this.mInputView.setTextColor(mSkinManager.getInputColor());
-        this.mInputView.setTypeface(skinManager.getUseSystemFont() ? Typeface.DEFAULT : lucidaConsole);
+        this.mInputView.setTextColor(mSkinManager.inputColor);
+        this.mInputView.setTypeface(skinManager.systemFont ? Typeface.DEFAULT : lucidaConsole);
         this.mInputView.setHint(Tuils.getHint(skinManager, mainPack.currentDirectory.getAbsolutePath()));
         this.mInputView.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
         this.mInputView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
             @Override
             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+//                physical enter
+                if(actionId == KeyEvent.ACTION_DOWN) {
+                    if(lastEnter == 0) {
+                        lastEnter = System.currentTimeMillis();
+                    } else {
+                        long difference = System.currentTimeMillis() - lastEnter;
+                        lastEnter = System.currentTimeMillis();
+                        if(difference < 350) {
+                            return true;
+                        }
+                    }
+                }
 
-//                physical enter is temporary ignored
-                if (actionId == EditorInfo.IME_ACTION_GO || actionId == EditorInfo.IME_ACTION_DONE) {
+                if (actionId == EditorInfo.IME_ACTION_GO || actionId == EditorInfo.IME_ACTION_DONE || actionId == KeyEvent.ACTION_DOWN) {
                     onNewInput();
-                    return true;
-                } else
-                    return false;
+                }
+                return true;
             }
         });
     }
@@ -195,7 +197,7 @@ public class TerminalManager {
     private void setupNewInput() {
         mInputView.setText(Tuils.EMPTYSTRING);
 
-        if(mSkinManager.showPath()) {
+        if(defaultHint && mSkinManager.showPath) {
             mInputView.setHint(Tuils.getHint(mSkinManager, mainPack.currentDirectory.getAbsolutePath()));
         }
 
@@ -207,18 +209,19 @@ public class TerminalManager {
             return false;
         }
 
-        String input = mInputView.getText().toString();
-        if (input.length() == 0) {
-            return false;
-        }
-        writeToView((input.startsWith("su ") ? "# " : prefix) + input, INPUT);
+        String input = mInputView.getText().toString().trim();
+
+        if(input.length() > 0) {
+            writeToView((input.startsWith("su ") ? "# " : prefix) + input, INPUT);
 
-        cmds++;
-        if(cmdList.size() == CMD_LIST_SIZE) {
-            cmdList.remove(0);
+            cmds++;
+            if(cmdList.size() == CMD_LIST_SIZE) {
+                cmdList.remove(0);
+            }
+            cmdList.add(cmdList.size(), input);
+            howBack = -1;
         }
-        cmdList.add(cmdList.size(), input);
-        howBack = -1;
+
 
         if (mInputListener != null) {
             mInputListener.onNewInput(input);
@@ -230,7 +233,12 @@ public class TerminalManager {
     }
 
     public void setOutput(String output) {
-        if (output == null || output.trim().equals(Tuils.EMPTYSTRING)) {
+        if (output == null) {
+            return;
+        }
+
+        output = output.trim();
+        if(output.equals(Tuils.EMPTYSTRING)) {
             return;
         }
 
@@ -304,9 +312,9 @@ public class TerminalManager {
         SpannableString spannableString = new SpannableString(text);
         int color;
         if(type == INPUT) {
-            color = mSkinManager.getInputColor();
+            color = mSkinManager.inputColor;
         } else if(type == OUTPUT) {
-            color = mSkinManager.getOutputColor();
+            color = mSkinManager.outputColor;
         } else {
             return null;
         }
@@ -323,6 +331,22 @@ public class TerminalManager {
         focusInputEnd();
     }
 
+    public void setHint(String hint) {
+        defaultHint = false;
+
+        if(mInputView != null) {
+            mInputView.setHint(hint);
+        }
+    }
+
+    public void setDefaultHint() {
+        defaultHint = true;
+
+        if(mInputView != null) {
+            mInputView.setHint(Tuils.getHint(mSkinManager, mainPack.currentDirectory.getAbsolutePath()));
+        }
+    }
+
     public void setInputListener(OnNewInputListener listener) {
         this.mInputListener = listener;
     }
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 97974bb..55d471c 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/managers/suggestions/SuggestionsManager.java
@@ -1,7 +1,5 @@
 package ohi.andre.consolelauncher.managers.suggestions;
 
-import android.util.Log;
-
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -12,7 +10,7 @@ import ohi.andre.comparestring.Compare;
 import ohi.andre.consolelauncher.commands.Command;
 import ohi.andre.consolelauncher.commands.CommandAbstraction;
 import ohi.andre.consolelauncher.commands.CommandTuils;
-import ohi.andre.consolelauncher.commands.PermanentSuggestionCommand;
+import ohi.andre.consolelauncher.commands.specific.PermanentSuggestionCommand;
 import ohi.andre.consolelauncher.commands.main.MainPack;
 import ohi.andre.consolelauncher.managers.AppsManager;
 import ohi.andre.consolelauncher.managers.ContactManager;
@@ -205,6 +203,9 @@ public class SuggestionsManager {
             case CommandAbstraction.BOOLEAN:
                 suggestBoolean(suggestions, before);
                 break;
+            case CommandAbstraction.HIDDEN_PACKAGE:
+                suggestHiddenApp(info, suggestions, prev, before);
+                break;
         }
     }
 
@@ -372,20 +373,42 @@ public class SuggestionsManager {
     }
 
     private void suggestApp(MainPack info, List<Suggestion> suggestions, String prev, String before) {
+        List<String> names = info.appsManager.getAppLabels();
+        if (prev == null || prev.length() == 0) {
+            for (String s : names) {
+                suggestions.add(new Suggestion(before, s, true, NO_RATE, Suggestion.TYPE_APP));
+            }
+        } else if(prev.length() <= FIRST_INTERVAL) {
+            prev = prev.trim().toLowerCase();
+            for (String n : names) {
+                if(n.toLowerCase().trim().startsWith(prev)) {
+                    suggestions.add(new Suggestion(before, n, true, MAX_RATE, Suggestion.TYPE_APP));
+                }
+            }
+        } else {
+            List<Compare.CompareInfo> infos = Compare.compareInfo(names, prev, min_apps_rate,
+                    AppsManager.USE_SCROLL_COMPARE);
+            for(Compare.CompareInfo i : infos) {
+                suggestions.add(new Suggestion(before, i.s, true, i.rate, Suggestion.TYPE_APP));
+            }
+        }
+    }
+
+    private void suggestHiddenApp(MainPack info, List<Suggestion> suggestions, String prev, String before) {
+        List<String> names = info.appsManager.getHiddenAppsLabels();
         if (prev == null || prev.length() == 0) {
-            for (String s : info.appsManager.getAppLabels()) {
+            for (String s : names) {
                 suggestions.add(new Suggestion(before, s, true, NO_RATE, Suggestion.TYPE_APP));
             }
         } else if(prev.length() <= FIRST_INTERVAL) {
             prev = prev.trim().toLowerCase();
-            List<String> names = info.appsManager.getAppLabels();
             for (String n : names) {
                 if(n.toLowerCase().trim().startsWith(prev)) {
                     suggestions.add(new Suggestion(before, n, true, MAX_RATE, Suggestion.TYPE_APP));
                 }
             }
         } else {
-            List<Compare.CompareInfo> infos = Compare.compareInfo(info.appsManager.getAppLabels(), prev, min_apps_rate,
+            List<Compare.CompareInfo> infos = Compare.compareInfo(names, prev, min_apps_rate,
                     AppsManager.USE_SCROLL_COMPARE);
             for(Compare.CompareInfo i : infos) {
                 suggestions.add(new Suggestion(before, i.s, true, i.rate, Suggestion.TYPE_APP));
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Animator.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Animator.java
index 4c1e6e4..8550079 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Animator.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Animator.java
@@ -1,17 +1,10 @@
 package ohi.andre.consolelauncher.tuils;
 
-import android.app.Application;
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.util.Log;
 import android.view.View;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.widget.TextView;
 
-import ohi.andre.consolelauncher.R;
-import ohi.andre.consolelauncher.commands.Command;
-
 /**
  * Created by francescoandreuzzi on 17/02/2017.
  */
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 5c1b9f1..8346f75 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java
@@ -1,7 +1,5 @@
 package ohi.andre.consolelauncher.tuils;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -16,10 +14,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Environment;
@@ -27,9 +21,6 @@ import android.provider.MediaStore;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.Patterns;
-import android.util.TypedValue;
-import android.view.View;
 
 import java.io.DataOutputStream;
 import java.io.File;
@@ -39,7 +30,6 @@ import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
-import java.util.regex.Pattern;
 
 import dalvik.system.DexFile;
 import ohi.andre.consolelauncher.managers.MusicManager;
@@ -157,31 +147,36 @@ public class Tuils {
 
     public static String getHint(SkinManager skinManager, String currentPath) {
 
-        if(!skinManager.showUsernameAndDeviceWhenEmpty()) {
+        if(!skinManager.showUsernameAndDeviceWhenEmpty) {
             return null;
         }
 
-        boolean showUsername = skinManager.showUsername();
-
-        String username = null;
-        if (showUsername) {
-            username = skinManager.getUsername();
+        String username = Tuils.EMPTYSTRING;
+        if (skinManager.showUsername) {
+            username = skinManager.username;
             if (username == null || username.length() == 0) {
-                username = null;
+                username = Tuils.EMPTYSTRING;
             }
         }
 
-        String deviceName = Build.DEVICE;
+        String deviceName = Tuils.EMPTYSTRING;
+        if(skinManager.showDeviceInSessionInfo) {
+            deviceName = skinManager.deviceName;
+        }
 
         String path = Tuils.EMPTYSTRING;
-        if(skinManager.showPath()) {
+        if(skinManager.showPath) {
             path = ":" + getNicePath(currentPath);
         }
 
-        if(username == null) {
+        if(username == Tuils.EMPTYSTRING) {
             return deviceName + path;
         } else {
-            return username + "@" + deviceName + path;
+            if(deviceName == Tuils.EMPTYSTRING) {
+                return username + path;
+            } else {
+                return username + "@" + deviceName + path;
+            }
         }
     }
 
@@ -431,7 +426,11 @@ public class Tuils {
             if(count > 0) {
                 while(cur.moveToNext()) {
                     String data = cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.DATA));
-                    paths.add(new File(data));
+                    if(data != null) {
+                        try {
+                            paths.add(new File(data));
+                        } catch (Exception e) {}
+                    }
                 }
 
             }
@@ -536,4 +535,20 @@ public class Tuils {
         return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
     }
 
+    private static final int FILEUPDATE_DELAY = 300;
+    public static File getFolder() {
+        final File tuiFolder = Tuils.getTuiFolder();
+
+        while (true) {
+            if (tuiFolder != null && (tuiFolder.isDirectory() || tuiFolder.mkdir())) {
+                break;
+            }
+
+            try {
+                Thread.sleep(FILEUPDATE_DELAY);
+            } catch (InterruptedException e) {}
+        }
+
+        return tuiFolder;
+    }
 }
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnRedirectionListener.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnRedirectionListener.java
new file mode 100644
index 0000000..8b487e1
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/OnRedirectionListener.java
@@ -0,0 +1,13 @@
+package ohi.andre.consolelauncher.tuils.interfaces;
+
+import ohi.andre.consolelauncher.commands.specific.RedirectCommand;
+
+/**
+ * Created by francescoandreuzzi on 03/03/2017.
+ */
+
+public interface OnRedirectionListener {
+
+    void onRedirectionRequest(RedirectCommand cmd);
+    void onRedirectionEnd(RedirectCommand cmd);
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Redirectator.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Redirectator.java
new file mode 100644
index 0000000..5bbb98b
--- /dev/null
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/Redirectator.java
@@ -0,0 +1,13 @@
+package ohi.andre.consolelauncher.tuils.interfaces;
+
+import ohi.andre.consolelauncher.commands.specific.RedirectCommand;
+
+/**
+ * Created by francescoandreuzzi on 03/03/2017.
+ */
+
+public interface Redirectator {
+
+    void prepareRedirection(RedirectCommand cmd);
+    void cleanup();
+}
diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/tutorial/TutorialActivity.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/tutorial/TutorialActivity.java
index 5ae91fa..ed1cb2f 100644
--- a/app/src/main/java/ohi/andre/consolelauncher/tuils/tutorial/TutorialActivity.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/tutorial/TutorialActivity.java
@@ -18,6 +18,7 @@ import android.widget.ScrollView;
 import android.widget.TextView;
 
 import ohi.andre.consolelauncher.BuildConfig;
+import ohi.andre.consolelauncher.LauncherActivity;
 import ohi.andre.consolelauncher.R;
 import ohi.andre.consolelauncher.tuils.Animator;
 import ohi.andre.consolelauncher.tuils.Tuils;
@@ -50,6 +51,7 @@ public class TutorialActivity extends AppCompatActivity {
                 update();
             } else {
                 TutorialActivity.this.finish();
+                startActivity(new Intent(TutorialActivity.this, LauncherActivity.class));
             }
         }
     };
diff --git a/app/src/main/res/layout/input_down_layout.xml b/app/src/main/res/layout/input_down_layout.xml
index 3d1b156..ea654e2 100644
--- a/app/src/main/res/layout/input_down_layout.xml
+++ b/app/src/main/res/layout/input_down_layout.xml
@@ -7,6 +7,7 @@
     <HorizontalScrollView android:id="@+id/suggestions_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:focusable="false"
 
         android:layout_alignParentBottom="true">
         <LinearLayout
diff --git a/app/src/main/res/layout/suggestions_layout.xml b/app/src/main/res/layout/suggestions_layout.xml
index 9e41230..dcd5ff7 100644
--- a/app/src/main/res/layout/suggestions_layout.xml
+++ b/app/src/main/res/layout/suggestions_layout.xml
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
-<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@id/suggestions_container"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:focusable="false">
 
     <LinearLayout
         android:id="@+id/suggestions_group"
diff --git a/app/src/main/res/raw/settings.txt b/app/src/main/res/raw/settings.txt
index d5f062f..784d05e 100755
--- a/app/src/main/res/raw/settings.txt
+++ b/app/src/main/res/raw/settings.txt
@@ -1,5 +1,5 @@
 // do not edit the settingsVersion property!
-settingsVersion=88
+settingsVersion=89
 
 // when you are ready go back to t-ui and type "restart" to see changes
 
@@ -22,6 +22,7 @@ showToolbar=true
 showSessionInfoWhenInputEmpty=true
 linuxAppearance=true
 showPathInSessionInfo=true
+showDeviceNameInSessionInfo=true
 
 // suggestions
 suggestionTextColor=#ff000000
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index e844fb5..bae677b 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -5,4 +5,6 @@
     <color name="default_output_color">#fff</color>
     <color name="default_bg_color">#000</color>
 
+    <color name="hint_color">#AAA</color>
+
 </resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index cafc352..96ace6f 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -8,6 +8,7 @@
     <string name="nosu">Your device isn\'t rooted</string>
     <string name="permissions_toast">You have to grant Storage permission</string>
     <string name="version_label">Version:</string>
+    <string name="output_error">An unknown error has occurred</string>
 
     <string name="rate_donate_text">\nDo you like my work? Rate on Play Store (command: >>rate) or offer me a coffee (command: >>donate). Thank you for using T-UI.\n\nYou can disable this message in >>tuisettings</string>
 
@@ -43,6 +44,7 @@
     <string name="tuixt_back_pressed">You pressed back key</string>
     <string name="tuixt_saved">Saved</string>
     <string name="tuixt_reading">Reading</string>
+    <string name="tuixt_label">TUIXT</string>
 
     <!-- search-->
     <string name="output_nothing_found">Nothing was found</string>
@@ -52,14 +54,12 @@
     <string name="output_data">Mobile Data active:</string>
     <string name="output_bluetooth">Bluetooth active:</string>
     <string name="output_airplane">Airplane Mode active:</string>
-    <string name="output_numbernotfound">Contact not found</string>
     <string name="output_nofeature">Can\'t use this feature on your Android version</string>
 
     <!-- files -->
     <string name="output_isfile">Cant\'t write here. It\'s a file</string>
     <string name="output_isdirectory">This is a directory</string>
     <string name="output_filenotfound">File not found</string>
-    <string name="output_ioerror">An unknown I/O error has occurred</string>
     <string name="output_noreadable">This file is not readable</string>
     <string name="output_nowriteable">You can\'t write or delete this file</string>
 
@@ -92,15 +92,20 @@
     <string name="wifi">WiFi:</string>
 
     <!-- infos -->
-    <string name="output_about">Francesco Andreuzzi (Italy)\n\t-> andreuzzi.francesco@gmail.com
-        \n\nLuke Winward, Design &amp; Testing
+    <string name="output_about">Francesco Andreuzzi (Italy)\n\t-> Programmer
+        \n\nLuke Winward\n\t-> Design &amp; Testing
         \n\n\nOpen Source Libraries:
-        \n(Francesco Andreuzzi) - CompareString
-        \nApache commons-io
+        \nCompareString
     </string>
     <string name="output_refresh">Refresh: apps, alias, music, contacts</string>
     <string name="output_rate">Thank you!</string>
 
+    <!-- contacts -->
+    <string name="sms_hint">write your SMS or nothing to abort</string>
+    <string name="output_numbernotfound">Contact not found</string>
+    <string name="output_smsnotsent">SMS not sent</string>
+    <string name="output_smssent">SMS sent</string>
+
 
     <string name="help_about">Informations about the app</string>
     <string name="help_airplane">Toggle Airplane Mode</string>
@@ -110,16 +115,24 @@
         \n\nUsage:
         \n>>apps [option] [app name]
         \n\n[option] can be:
-        \n-h [app name] -> hide the app
-        \n-uh [app name] -> unhide the app
         \n-sh -> show hidden apps
         \n-ps [app name] -> show Google Play Store page for this app
         \n-st [app name] -> show Settings details for this app
         \n-f [app name] -> force t-ui to open this app
         \nno option -> list your apps
         \n\nExample:
-        \n>>apps -h whatsapp
+        \n>>apps -st T-UI
     </string>
+    <string name="help_appshide">Hide an app
+        \n\nUsage:
+        \n>>apps_hide [app]
+        \n\nExample:
+        \n>>apps_hide Settings</string>
+    <string name="help_appsunhide">Unhide an hidden app
+        \n\nUsage:
+        \n>>apps_unhide [app]
+        \n\nExample:
+        \n>>apps_unhide Settings</string>
     <string name="help_bluetooth">Toggle Bluetooth</string>
     <string name="help_clear">Clear the screen</string>
     <string name="help_calc" formatted="false">Perform basic operations (+ - * / % ^ sqrt)
@@ -233,31 +246,17 @@
         \n\nExample:
         \n>>ls Downloads
     </string>
+    <string name="help_sms">Send an SMS.
+        \nUsage:
+        \n>>sms [contact name] OR [phone number] {newline}
+        \n>>[text]
+        \n\nExample:
+        \n>>sms John Smith
+        \n>>Hi John, I need to talk you about T-UI, it\'s a fantastic launcher!</string>
 
     <string name="start_notification">T-UI started</string>
     <string name="tui_running">T-UI is running</string>
 
-    <string name="tutorial_actionbar">T-UI Tutorial</string>
-    <string name="tutorial_header">Tap anywhere to learn how to use T-UI</string>
-    <string-array name="tutorial_index">
-        <item>Launch Applications</item>
-        <item>Commands</item>
-        <item>Settings</item>
-        <item>Alias</item>
-        <item>Playing music</item>
-    </string-array>
-
-    <string name="tutorial">Hi, I\'m T-UI, an Android launcher inspired by Linux Shell. You can see again this tutorial whenever you want, just type \"tutorial\" and hit enter.
-        \n\nThe first command you will want to use is "help". It will show you the command you can use. You should take a look.\nIf you want to know something about a command: \"help [command]\" (this is like
-        Linux\'s man).
-        \n\nYou can launch your apps just typing their name and clicking on one of those colorful rect below (they\'re called \"suggestions\").
-        \n\nIf you want to change some settings type "tuisettings" and edit the file which appears (but this is for advanced users only, I think..).
-        \n\nYou can also create \"alias\", which are sequences of characters that means a longer sequence. You can change them using \"aliasfile\".
-        \n\nDo you want to go back to your previous launcher? Just use "remove", this will uninstall T-UI from your phone.
-        \n\nThis is all, have fun!
-        \n\n\t- Francesco Andreuzzi
-    </string>
-
     <!-- tutorial -->
     <string name="tutorial_title">A brief introduction</string>
 
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index dc5cbde..db370fe 100755
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,7 +1,22 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <style name="Custom.Solid" parent="android:Theme.Light.NoTitleBar" />
-    <style name="Custom.SystemWP" parent="android:Theme.Wallpaper.NoTitleBar" />
+    <style name="Custom.Solid" parent="Theme.AppCompat.Light.NoActionBar">
+        <item name="android:textColorHint">@color/hint_color</item>
+        <item name="android:statusBarColor">@android:color/black</item>
+    </style>
+    <style name="Custom.Solid.Fullscreen" parent="Custom.Solid">
+        <item name="android:windowFullscreen">true</item>
+    </style>
+
+    <style name="Custom.SystemWP" parent="Theme.AppCompat.Light.NoActionBar">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowShowWallpaper">true</item>
+        <item name="android:textColorHint">@color/hint_color</item>
+        <item name="android:statusBarColor">@android:color/black</item>
+    </style>
+    <style name="Custom.SystemWP.Fullscreen" parent="Custom.SystemWP">
+        <item name="android:windowFullscreen">true</item>
+    </style>
 
     <style name="Theme.AppCompat.Light.NoActionBar.FullScreen" parent="@style/Theme.AppCompat.Light">
         <item name="windowNoTitle">true</item>
diff --git a/build.gradle b/build.gradle
index 6193afb..6ac76f7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.3.0-beta4'
+        classpath 'com.android.tools.build:gradle:2.3.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
-- 
GitLab