diff --git a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
index 49cc6fd911dea139d31a2889fedfdab352a94dff..1cf6dddb050384ec44e216dab1bd75063ed2f429 100755
--- a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
+++ b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java
@@ -5,7 +5,6 @@ import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.os.Build;
 import android.os.Handler;
@@ -22,17 +21,20 @@ import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
+import android.widget.HorizontalScrollView;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import java.io.File;
+import java.lang.reflect.Field;
 
 import ohi.andre.consolelauncher.commands.ExecInfo;
 import ohi.andre.consolelauncher.managers.PreferencesManager;
 import ohi.andre.consolelauncher.managers.SkinManager;
 import ohi.andre.consolelauncher.managers.SuggestionsManager;
-import ohi.andre.consolelauncher.tuils.TerminalAdapter;
+import ohi.andre.consolelauncher.managers.TerminalManager;
+import ohi.andre.consolelauncher.tuils.SuggestionRunnable;
 import ohi.andre.consolelauncher.tuils.Tuils;
 import ohi.andre.consolelauncher.tuils.interfaces.CommandExecuter;
 import ohi.andre.consolelauncher.tuils.interfaces.OnNewInputListener;
@@ -45,7 +47,6 @@ public class UIManager implements OnTouchListener {
     public Handler handler;
 
     protected Context mContext;
-    protected LinearLayout suggestionsView;
 
     private SkinManager skinManager;
 
@@ -56,7 +57,7 @@ public class UIManager implements OnTouchListener {
 
     private InputMethodManager imm;
     private CommandExecuter trigger;
-    private TerminalAdapter mTerminalAdapter;
+    private TerminalManager mTerminalAdapter;
 
     private int lastMeasuredHeight;
 
@@ -74,9 +75,18 @@ public class UIManager implements OnTouchListener {
         }
     };
 
+    private LinearLayout suggestionsView;
     private SuggestionViewDecorer suggestionViewDecorer;
     private LinearLayout.LayoutParams suggestionViewParams;
     private Thread lastSuggestionThread;
+    private SuggestionRunnable suggestionRunnable;
+    private Handler activityHandler;
+    private Runnable removeAllSuggestions = new Runnable() {
+        @Override
+        public void run() {
+            suggestionsView.removeAllViews();
+        }
+    };
 
     protected TextWatcher textWatcher = new TextWatcher() {
 
@@ -89,10 +99,6 @@ public class UIManager implements OnTouchListener {
             if (suggestionsView == null)
                 return;
 
-            if (lastSuggestionThread != null && lastSuggestionThread.isAlive()) {
-                lastSuggestionThread.interrupt();
-            }
-
             String text = s.toString();
             int lastSpace = text.lastIndexOf(Tuils.SPACE);
 
@@ -115,7 +121,7 @@ public class UIManager implements OnTouchListener {
 
             String inputText = mTerminalAdapter.getInput();
 
-            int lastSpace = inputText.lastIndexOf(" ");
+            int lastSpace = inputText.lastIndexOf(Tuils.SPACE);
             String lastWord = inputText.substring(lastSpace != -1 ? lastSpace + 1 : 0);
             String before = inputText.substring(0, lastSpace + 1);
 
@@ -135,7 +141,7 @@ public class UIManager implements OnTouchListener {
             }
 
             mTerminalAdapter.setInput(builder.toString());
-            if (executeOnSuggestionClick && Tuils.arrayContains(SuggestionsManager.Suggestion.TAP_TO_EXECUTE_TYPES, v.getId())) {
+            if (executeOnSuggestionClick && v.getId() == SuggestionsManager.Suggestion.EXEC_ON_CLICK) {
                 mTerminalAdapter.simulateEnter();
             } else {
                 mTerminalAdapter.focusInputEnd();
@@ -143,8 +149,100 @@ public class UIManager implements OnTouchListener {
         }
     };
 
+    private void requestSuggestion(final String before, final String lastWord) {
+
+        if (suggestionViewParams == null) {
+            suggestionViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            suggestionViewParams.setMargins(SkinManager.SUGGESTION_MARGIN, 0, SkinManager.SUGGESTION_MARGIN, 0);
+            suggestionViewParams.gravity = Gravity.CENTER_VERTICAL;
+        }
+
+        if(suggestionRunnable == null) {
+            suggestionRunnable = new SuggestionRunnable(skinManager, suggestionsView, suggestionViewParams, (HorizontalScrollView) suggestionsView.getParent());
+        }
+
+        if(activityHandler == null) {
+            Field field;
+            try {
+                field = mContext.getClass().getSuperclass().getDeclaredField("mHandler");
+                field.setAccessible(true);
+                activityHandler = (Handler) field.get(mContext);
+            }
+            catch (Exception e) {}
+        }
+
+        if (lastSuggestionThread != null) {
+            lastSuggestionThread.interrupt();
+            suggestionRunnable.interrupt();
+            if(activityHandler != null) {
+                activityHandler.removeCallbacks(suggestionRunnable);
+            }
+        }
+
+        lastSuggestionThread = new Thread() {
+            @Override
+            public void run() {
+                super.run();
+
+                final SuggestionsManager.Suggestion[] suggestions = SuggestionsManager.getSuggestions(info, before, lastWord);
+
+                if(suggestions.length == 0) {
+                    ((Activity) mContext).runOnUiThread(removeAllSuggestions);
+                    return;
+                }
+
+                if (Thread.interrupted()) {
+                    suggestionRunnable.interrupt();
+                    return;
+                }
+
+                final TextView[] existingViews = new TextView[suggestionsView.getChildCount()];
+                for (int count = 0; count < existingViews.length; count++) {
+                    existingViews[count] = (TextView) suggestionsView.getChildAt(count);
+                }
+
+                if (Thread.interrupted()) {
+                    suggestionRunnable.interrupt();
+                    return;
+                }
+
+                int n = suggestions.length - existingViews.length;
+                TextView[] toAdd = null;
+                TextView[] toRecycle = null;
+                if (n == 0) {
+                    toRecycle = existingViews;
+                    toAdd = null;
+                } else if (n > 0) {
+                    toRecycle = existingViews;
+                    toAdd = new TextView[n];
+                    for (int count = 0; count < toAdd.length; count++) {
+                        toAdd[count] = suggestionViewDecorer.getSuggestionView(mContext);
+                    }
+                } else if (n < 0) {
+                    toAdd = null;
+                    toRecycle = new TextView[suggestions.length];
+                    System.arraycopy(existingViews, 0, toRecycle, 0, toRecycle.length);
+                }
+
+                if (Thread.interrupted()) {
+                    suggestionRunnable.interrupt();
+                    return;
+                }
+
+                suggestionRunnable.setN(n);
+                suggestionRunnable.setSuggestions(suggestions);
+                suggestionRunnable.setToAdd(toAdd);
+                suggestionRunnable.setToRecycle(toRecycle);
+                suggestionRunnable.reset();
+                ((Activity) mContext).runOnUiThread(suggestionRunnable);
+            }
+        };
+
+        lastSuggestionThread.start();
+    }
+
     protected UIManager(ExecInfo info, Context context, final ViewGroup rootView, final CommandExecuter tri, DevicePolicyManager mgr, ComponentName name,
-                        PreferencesManager prefsMgr, Resources resources) {
+                        PreferencesManager prefsMgr) {
 
         rootView.setOnTouchListener(this);
 
@@ -257,7 +355,7 @@ public class UIManager implements OnTouchListener {
         } else
             initDetector();
 
-        mTerminalAdapter = new TerminalAdapter(terminalView, inputView, prefixView, submitView, skinManager, getHint(prefsMgr),
+        mTerminalAdapter = new TerminalManager(terminalView, inputView, prefixView, submitView, skinManager, getHint(prefsMgr),
                 Boolean.parseBoolean(prefsMgr.getValue(PreferencesManager.ENTER_PHYSICAL_KEYBOARD)));
         mTerminalAdapter.setInputListener(new OnNewInputListener() {
             @Override
@@ -292,87 +390,6 @@ public class UIManager implements OnTouchListener {
         });
     }
 
-    //    call this to trigger a suggestion change
-    private void requestSuggestion(final String before, final String lastWord) {
-
-        if (suggestionViewParams == null) {
-            suggestionViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-            suggestionViewParams.setMargins(SkinManager.SUGGESTION_MARGIN, 0, SkinManager.SUGGESTION_MARGIN, 0);
-            suggestionViewParams.gravity = Gravity.CENTER_VERTICAL;
-        }
-
-        lastSuggestionThread = new Thread() {
-            @Override
-            public void run() {
-                super.run();
-
-                final SuggestionsManager.Suggestion[] suggestions = SuggestionsManager.getSuggestions(info, before, lastWord);
-
-                if (Thread.interrupted())
-                    return;
-
-                final TextView[] recycledViews = new TextView[suggestionsView.getChildCount()];
-                for (int count = 0; count < recycledViews.length; count++) {
-                    recycledViews[count] = (TextView) suggestionsView.getChildAt(count);
-                }
-
-                if (Thread.interrupted())
-                    return;
-
-                final int n = suggestions.length - recycledViews.length;
-                final TextView[] toAdd;
-                final TextView[] toRecycle;
-                if (n == 0) {
-                    toRecycle = recycledViews;
-                    toAdd = null;
-                } else if (n > 0) {
-                    toRecycle = recycledViews;
-                    toAdd = new TextView[n];
-                    for (int count = 0; count < toAdd.length; count++) {
-                        toAdd[count] = suggestionViewDecorer.getSuggestionView(mContext);
-                    }
-                } else if (n < 0) {
-                    toAdd = null;
-                    toRecycle = new TextView[suggestions.length];
-                    System.arraycopy(recycledViews, 0, toRecycle, 0, toRecycle.length);
-                } else {
-                    return;
-                }
-
-                if (Thread.interrupted())
-                    return;
-
-                ((Activity) mContext).runOnUiThread(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (n < 0) {
-                            for (int count = toRecycle.length; count < suggestionsView.getChildCount(); count++) {
-                                suggestionsView.removeViewAt(count);
-                            }
-                        }
-
-                        for (int count = 0; count < suggestions.length; count++) {
-                            String s = suggestions[count].text;
-                            if (count < toRecycle.length) {
-                                toRecycle[count].setId(suggestions[count].id);
-                                toRecycle[count].setBackgroundDrawable(null);
-                                toRecycle[count].setBackgroundDrawable(skinManager.getSuggestionBg(suggestions[count].id));
-                                toRecycle[count].setText(s);
-                            } else if (toAdd != null && count < toAdd.length) {
-                                toAdd[count].setText(s);
-                                toAdd[count].setId(suggestions[count].id);
-                                toAdd[count].setBackgroundDrawable(skinManager.getSuggestionBg(suggestions[count].id));
-                                suggestionsView.addView(toAdd[count], suggestionViewParams);
-                            }
-                        }
-                    }
-                });
-            }
-        };
-
-        lastSuggestionThread.start();
-    }
-
     private void openKeyboard() {
         mTerminalAdapter.requestInputFocus();
         imm.showSoftInput(mTerminalAdapter.getInputView(), InputMethodManager.SHOW_IMPLICIT);
@@ -389,7 +406,7 @@ public class UIManager implements OnTouchListener {
 
     //   accessor for input
     public void setInput(String s) {
-        if (s == null || s.length() == 0)
+        if (s == null)
             return;
 
         mTerminalAdapter.setInput(s);