diff --git a/public/js/src/hint.js b/public/js/src/hint.js
index b5c2043..8011bee 100644
--- a/public/js/src/hint.js
+++ b/public/js/src/hint.js
@@ -1,64 +1,21 @@
 /**
- * Context aware drop down menu
- * for annotation related query hints.
+ * Hint menu for Kalamar.
  *
  * @author Nils Diewald
  */
 
-// - http://www.cryer.co.uk/resources/javascript/script20_respond_to_keypress.htm
-// - https://developers.google.com/closure/compiler/docs/js-for-compiler
-// TODO:
-// - Add help option that opens the tutorial, e.g. to the foundry
-// - http://en.wikipedia.org/wiki/JSDoc
+// requires menu.js
 
-// The last entry types (foundry, foundry/layer) is remembered and chosen by default
-
-// Show the context at the top as breadcrumbs
-// Highlight the context in the query (probably)
-// Support backspace for removing the last prefix
-
-/*
-Alternative: Use right arrow for temporary context switch and arrow back
-for temporary context removal
-*/
-
-/**
- * The KorAP namespace for project related scripts
- * @namespace
- */
 var KorAP = KorAP || {};
 
-/*
-    this._search.addEventListener(
-      "keyup",
-      function () {
-	that.update();
-      },
-      false
-    );
-*/
-
 (function (KorAP) {
   "use strict";
 
-  // Don't let events bubble up
-  if (Event.halt === undefined) {
-    Event.prototype.halt = function () {
-      this.stopPropagation();
-      this.preventDefault();
-    };
-  };
-
   // Default log message
   KorAP.log = KorAP.log || function (type, msg) {
     console.log(type + ": " + msg);
   };
 
-  /* TODO: Add event listener on windows resize to change that! */
-
-  /** @define {number} Limited view of menu items */
-  KorAP.limit = 8;
-
   /**
    * @define {regex} Regular expression for context
    */
@@ -74,14 +31,12 @@
   // Initialize hint array
   KorAP.hintArray = KorAP.hintArray || {};
 
-
-  KorAP.updateKeyDown = function (event) {
-  };
-
+  // Input field for queries
   KorAP.InputField = {
     create : function (element) {
       return Object.create(KorAP.InputField)._init(element);
     },
+
     _init : function (element) {
       this._element = element;
 
@@ -90,6 +45,7 @@
 	this._mirror = document.createElement("div");
 	this._mirror.setAttribute("id", "searchMirror");
 	this._mirror.appendChild(document.createElement("span"));
+	this._container = this._mirror.appendChild(document.createElement("div"));
 	this._mirror.style.height = "1px";
 	document.getElementsByTagName("body")[0].appendChild(this._mirror);
       };
@@ -99,39 +55,47 @@
       window.resize = function () {
 	that.reposition();
       };
-/*
-      // Add event listener for key down
-      element.addEventListener(
-	"keydown",
-	function (e) {
-//	  KorAP.updateKeyDown(e).bind(that)
-	},
-	false
-      );
-*/
+
+      that.reposition();
+
       return this;
     },
-    get mirror () {
+
+    rightPos : function () {
+      var box = this._mirror.getBoundingClientRect();
+      return box.right - box.left;
+    },
+
+    mirror : function () {
       return this._mirror;
     },
-    get element () {
+
+    container : function () {
+      return this._container;
+    },
+
+    element : function () {
       return this._element;
     },
-    get value () {
+
+    value : function () {
       return this._element.value;
     },
+
     update : function () {
       this._mirror.firstChild.textContent = this.split()[0];
     },
+
     insert : function (text) {
       var splittedText = this.split();
-      var s = this.element;
+      var s = this._element;
       s.value = splittedText[0] + text + splittedText[1];
       s.selectionStart = (splittedText[0] + text).length;
       s.selectionEnd = s.selectionStart;
       this._mirror.firstChild.textContent = splittedText[0] + text;
     },
-    // Return two substrings, splitted at current position
+
+    // Return two substrings, splitted at current cursor position
     split : function () {
       var s = this._element;
       var value = s.value;
@@ -141,13 +105,16 @@
 	value.substring(start, value.length)
       );
     },
+
     // Position the input mirror directly below the input box
     reposition : function () {
       var inputClientRect = this._element.getBoundingClientRect();
       var inputStyle = window.getComputedStyle(this._element, null);
+
+      // Reset position
       var mirrorStyle = this._mirror.style;
       mirrorStyle.left = inputClientRect.left + "px";
-      mirrorStyle.top = inputClientRect.bottom + "px";
+      mirrorStyle.top  = inputClientRect.bottom + "px";
 
       // These may be relevant in case of media depending css
       mirrorStyle.paddingLeft     = inputStyle.getPropertyValue("padding-left");
@@ -157,182 +124,14 @@
       mirrorStyle.fontSize        = inputStyle.getPropertyValue("font-size");
       mirrorStyle.fontFamily      = inputStyle.getPropertyValue("font-family");
     },
-    get context () {
+    context : function () {
       return this.split()[0];
     }
   };
 
-  KorAP.Hint = {
-    _firstTry : true,
-    create : function (param) {
-      return Object.create(KorAP.Hint)._init(param);
-    },
-    _init : function (param) {
-      param = param || {};
-      this._menu = {};
-
-      // Get input field
-      this._inputField = KorAP.InputField.create(
-	param["inputField"] || document.getElementById("q-field")
-      );
-
-      var that = this;
-      var inputFieldElement = this._inputField.element;
-
-      // Add event listener for key pressed down
-      inputFieldElement.addEventListener(
-	"keypress", function (e) {that.updateKeyPress(e)}, false
-      );
-
-      // Set Analyzer for context
-      this._analyzer = KorAP.ContextAnalyzer.create(
-	param["context"]|| KorAP.context
-      );
-
-      return this;
-    },
-    _codeFromEvent : function (e) {
-      if ((e.charCode) && (e.keyCode==0))
-	return e.charCode
-      return e.keyCode;
-    },
-    updateKeyPress : function (e) {
-      if (!this._active)
-	return;
-
-      var character = String.fromCharCode(
-	this._codeFromEvent(e)
-      );
-
-      e.halt(); // No event propagation
-
-      console.log("TODO: filter view");
-    },
-    updateKeyDown : function (e) {
-      var code = this._codeFromEvent(e)
-      
-      /*
-       * keyCodes:
-       * - Down  = 40
-       * - Esc   = 27
-       * - Up    = 38
-       * - Enter = 13
-       * - shift = 16
-       * for characters use e.key
-       */
-      switch (code) {
-      case 27: // 'Esc'
-	// TODO: menu.hide();
-	break;
-      case 40: // 'Down'
-	e.halt(); // No event propagation
-	
-	// Menu is not active
-	if (!this._active)
-	  this.popUp();
-	// Menu is active
-	else {
-	  // TODO: that.removePrefix();
-	  // TODO: menu.next();
-	};
-
-	break;
-      case 38: // "Up"
-	if (!this._active)
-	  break;
-	e.halt(); // No event propagation
-	// TODO: that.removePrefix();
-	// TODO: menu.prev();
-	break;
-      case 13: // "Enter"
-	if (!this._active)
-	  break;
-	e.halt(); // No event propagation
-	// TODO: that.insertText(menu.getActiveItem().getAction());
-	// TODO: that.removePrefix();
-    
-	// Remove menu
-	// TODO: menu.hide();
-
-	// Fill this with the correct value
-	// Todo: This is redundant with click function
-	/*
-	var show;
-	if ((show = that.analyzeContext()) != "-") {
-	  menu.show(show);
-	  menu.update(
-            e.target.getBoundingClientRect().right
-	  );
-	};
-	*/
-    
-	break;
-      default:
-	if (!this._active)
-	  return;
-
-	// Surpress propagation in firefox
-	/*
-	if (e.key !== undefined && e.key.length != 1) {
-	  menu.hide();
-	};
-	*/
-      };
-    },
-
-    getMenuByContext : function () {
-      var context = this._inputField.context;
-      if (context === undefined || context.length == 0)
-	return this.menu("-");
-
-      context = this._analyzer.analyze(context);
-      if (context === undefined || context.length == 0)
-	return this.menu("-");
-
-      return this.menu(context);
-    },
-    // Return and probably init a menu based on an action
-    menu : function (action) {
-      if (this._menu[action] === undefined) {
-	if (KorAP.hintArray[action] === undefined)
-	  return;
-	this._menu[action] = KorAP.menu.create(action, KorAP.hintArray[action]);
-      };
-      return this._menu[action];
-    },
-    get inputField () {
-      return this._inputField;
-    },
-    get active () {
-      return this._active;
-    },
-    popUp : function () {
-      if (this.active)
-	return;
-
-      if (this._firstTry) {
-	this._inputField.reposition();
-	this._firstTry = false;
-      };
-
-      // update
-
-      var menu;
-      if (menu = this.getMenuByContext()) {
-	menu.show();
-// Update bounding box
-      }
-      else {
-//	this.hide();
-      };
-
-      // Focus on input field
-      this.inputField.element.focus();
-    }
-  };
 
   /**
-     Regex object for checking the context of the hint
+   * Regex object for checking the context of the hint
    */
   KorAP.ContextAnalyzer = {
     create : function (regex) {
@@ -357,498 +156,295 @@
 
 
   /**
-   * List of items for drop down menu (complete).
-   * Only a sublist of the menu is filtered (live).
-   * Only a sublist of the filtered menu is visible (shown).
+   * Hint menu item based on MenuItem
    */
-  KorAP.Menu = {
-    _position : 0,  // position in the active list
-    _active   : -1, // active item in the item list
-
-    /**
-     * Create new Menu based on the action prefix
-     * and a list of menu items.
-     *
-     * @this {Menu}
-     * @constructor
-     * @param {string} Context prefix
-     * @param {Array.<Array.<string>>} List of menu items
-     */
-    create : function (context, items) {
-      return Object.create(KorAP.Menu)._init(context, items);
+  KorAP.HintMenuItem = {
+    create : function (params) {
+      return Object.create(KorAP.MenuItem)
+	.upgradeTo(KorAP.HintMenuItem)
+	._init(params);
     },
-
-    /*
-     * Make the previous item in the menu active
-     */
-    prev : function () {
-      if (this._position == -1)
-	return;
-
-      // Set new live item
-      var oldItem = this.liveItem(this._position--);
-      oldItem.active(false);
-      var newItem = this.liveItem(this._position);
-
-      // The previous element is undefined - roll to bottom
-      if (newItem === undefined) {
-	this._position = this.liveLength - 1;
-	newItem = this.liveItem(this._position);
-	this._offset = this.liveLength - this.limit;
-	this._showItems(this._offset);
-      }
-
-      // The previous element is outside the view - roll up
-      else if (this._position < this._offset) {
-	this._removeLast();
-	this._offset--;
-	this._prepend(this._list[this._position]);
+    content : function (content) {
+      if (arguments.length === 1) {
+	this._content = content;
       };
-      newItem.active(true);
+      return this._content;
     },
-
-    /*
-     * Make the next item in the menu active
-     */
-    next : function () {
-      // No active element set
-      if (this._position == -1)
-	return;
-
-      // Set new live item
-      var oldItem = this.liveItem(this._position++);
-      oldItem.active(false);
-      var newItem = this.liveItem(this._position);
-
-      // The next element is undefined - roll to top
-      if (newItem === undefined) {
-	this._offset = 0;
-	this._position = 0;
-	newItem = this.liveItem(0);
-	this._showItems(0);
-      }
-
-      // The next element is outside the view - roll down
-      else if (this._position >= (this.limit + this._offset)) {
-	this._removeFirst();
-	this._offset++;
-	this._append(this._list[this._position]);
-      };
-      newItem.active(true);
-    },
-
-    /**
-     * Delete all visible items from the menu element
-     */
-    delete : function () {
-      var child;
-      for (var i = 0; i <= this.limit; i++)
-	if (child = this.shownItem(i))
-	  child.lowlight();
-      while (child = this._element.firstChild)
-	this._element.removeChild(child);
-    },
-
-    /**
-     * Filter the list and make it visible
-     *
-     * @param {string} Prefix for filtering the list
-     */
-    show : function (prefix) {
-      this._prefix = prefix;
-
-      // Initialize the list
-      if (!this._initList())
-	return;
-
-      // show based on offset
-      this._showItems(0);
-
-      // Set the first element to active
-      this.liveItem(0).active(true);
-      this._position = 0;
-      this._active = this._list[0];
-
-      // Add classes for rolling menus
-      this._boundary(true);
-    },
-
-    /**
-     * Get the prefix for filtering,
-     * e.g. &quot;ve"&quot; for &quot;verb&quot;
-     */
-    get prefix () {
-      return this._prefix || '';
-    },
-
-    /**
-     * Get the numerical value for limit
-     */
-    get limit () {
-      return KorAP.limit;
-    },
-
-    /**
-     * Get the context of the menue,
-     * e.g. &quot;tt/&quot; for the tree tagger menu
-     */
-    get context () {
-      return this._context;
-    },
-
-    /**
-     * Get a specific item from the complete list
-     *
-     * @param {number} index of the list item
-     */
-    item : function (index) {
-      return this._items[index]
-    },
-
-    /**
-     * Get a specific item from the filtered list
-     *
-     * @param {number} index of the list item
-     */
-    liveItem : function (index) {
-      if (this._list === undefined)
-	if (!this._initList())
-	  return;
-
-      return this._items[this._list[index]];
-    },
-    /*
-     * Get a specific item from the visible list
-     *
-     * @param {number} index of the list item
-     */
-    shownItem : function (index) {
-      if (index >= this.limit)
-	return;
-      return this.liveItem(this._offset + index);
-    },
-    get element () {
-      return this._element;
-    },
-    get length () {
-      return this._items.length;
-    },
-    get liveLength () {
-      if (this._list === undefined)
-	this._initList();
-      return this._list.length;
-    },
-    chooseHint : function (e) {
-/*
-      var element = e.target;
-      while (element.nodeName == "STRONG" || element.nodeName == "SPAN")
-	element = element.parentNode;
-
-      if (element === undefined || element.nodeName != "LI")
-	return;
-
-      var action = element.getAttribute('data-action');
-      hint.insertText(action);
-      var menu = hint.menu();
-      menu.hide();
-
-      // Fill this with the correct value
-      var show;
-      if ((show = hint.analyzeContext()) != "-") {
-	menu.show(show);
-	menu.update(
-	  hint._search.getBoundingClientRect().right
-	);
+    _init : function (params) {
+      if (params[0] === undefined ||
+	  params[1] === undefined)
+	throw new Error("Missing parameters");
+      
+      this._name   = params[0];
+      this._action = params[1];
+      this._lcField = ' ' + this._name.toLowerCase();
+      
+      if (params.length > 2) {
+	this._desc = params[2];
+	this._lcField += " " + this._desc.toLowerCase();
       };
 
-      hint._search.focus();
-*/
-    },
-
-    _reset : function () {
-      this._offset = 0;
-      this._pos = 0;
-      this._prefix = undefined;
-    },
-    _boundary : function (bool) {
-      this.item(this._list[0]).noMore(bool);
-      this.item(this._list[this._list.length - 1]).noMore(bool);
-    },
-    _initList : function () {
-
-console.log("..." + this._items.length);
-
-      if (this._list === undefined)
-	this._list = [];
-      else if (this._list.length != 0) {
-	this._boundary(false);
-	this._list.length = 0;
-      };
-
-      this._offset = 0;
-
-      if (this.prefix().length <= 0) {
-	for (var i = 0; i < this._items.length; i++)
-	  this._list.push(i);
-	return true;
-      };
-
-      var pos;
-      var paddedPrefix = " " + this.prefix;
-      for (pos = 0; pos < this._items.length; pos++) {
-	if ((this.item(pos).lcfield.indexOf(paddedPrefix)) >= 0)
-	  this._list.push(pos);
-      };
-      if (this._list.length == 0) {
-	for (pos = 0; pos < this._items.length; pos++) {
-	  if ((this.item(pos).lcfield.indexOf(this.prefix)) >= 0)
-	    this._list.push(pos);
-	};
-      };
-
-      // Filter was successful
-      return this._list.length > 0 ? true : false;
-    },
-
-    _removeFirst : function () {
-      this.item(this._list[this._offset]).lowlight();
-      this._element.removeChild(this._element.firstChild);
-    },
-
-    _removeLast : function () {
-      this.item(this._list[this._offset + this.limit - 1]).lowlight();
-      this._element.removeChild(this._element.lastChild);
-    },
-
-    // Append item to the shown list based on index
-    _append : function (i) {
-      var item = this.item(i);
-
-      // Highlight based on prefix
-      if (this.prefix.length > 0)
-	item.highlight(this.prefix);
-
-      // Append element
-      this.element.appendChild(item.element);
-    },
-
-    // Prepend item to the shown list based on index
-    _prepend : function (i) {
-      var item = this.item(i);
-
-      // Highlight based on prefix
-      if (this.prefix.length > 0)
-	item.highlight(this.prefix);
-
-      // Append element
-      this.element.insertBefore(
-	item.element,
-	this.element.firstChild
-      );
-    },
-    _init : function (context, items) {
-      this._context = context;
-      this._element = document.createElement("ul");
-      this._element.style.opacity = 0;
-      this.active = false;
-/*
-  Todo:
-      this._element.addEventListener("click", chooseHint, false);
-*/
-      this._items = new Array();
-      var i;
-      for (i in items)
-	this._items.push(KorAP.MenuItem.create(items[i]));
-
-      this._reset();
       return this;
     },
+    onclick : function () {
+      var m = this.menu();
+      var h = m.hint();
+      m.hide();
 
-    _showItems : function (offset) {
-      this.delete();
+      h.inputField().insert(this._action);
+      h.active = false;
 
-      // Use list
-      var shown = 0;
-      var i;
-      for (i in this._list) {
-
-	// Don't show - it's before offset
-	if (shown++ < offset)
-	  continue;
-
-	this._append(this._list[i]);
-
-	if (shown >= (this.limit + this._offset))
-	  break;
-      };
-    }
-  };
-
-
-  /**
-   * Item in the Dropdown menu
-   */
-  KorAP.MenuItem = {
-
-    /**
-     * Create a new MenuItem object.
-     *
-     * @constructor
-     * @this {MenuItem}
-     * @param {Array.<string>} An array object of name, action and
-     *   optionally a description
-     */
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)._init(params);
+      h.show(true);
     },
-
-    /**
-     * Get the name of the item
-     */
-    get name () {
+    name : function () {
       return this._name;
     },
-
-    /**
-     * Get the action string
-     */
-    get action () {
+    action : function () {
       return this._action;
     },
-
-    /**
-     * Get the description of the item
-     */
-    get desc () {
+    desc : function () {
       return this._desc;
     },
-
-    /**
-     * Get the lower case field
-     */
-    get lcfield () {
-      return this._lcfield;
-    },
-
-    /**
-     * Check or set if the item is active
-     *
-     * @param {boolean|null} State of activity
-     */
-    active : function (bool) {
-      var cl = this.element.classList;
-      if (bool === undefined)
-	return cl.contains("active");
-      else if (bool)
-	cl.add("active");
-      else
-	cl.remove("active");
-    },
-
-    /**
-     * Check or set if the item is
-     * at the boundary of the menu
-     * list
-     *
-     * @param {boolean|null} State of activity
-     */
-    noMore : function (bool) {
-      var cl = this.element.classList;
-      if (bool === undefined)
-	return cl.contains("no-more");
-      else if (bool)
-	cl.add("no-more");
-      else
-	cl.remove("no-more");
-    },
-
-    /**
-     * Get the document element of the menu item
-     */
-    get element () {
+    element : function () {
       // already defined
       if (this._element !== undefined)
 	return this._element;
 
       // Create list item
       var li = document.createElement("li");
-      li.setAttribute("data-action", this._action);
+
+      if (this.onclick !== undefined) {
+	li["onclick"] = this.onclick.bind(this);
+      };
 
       // Create title
-      var name =  document.createElement("strong");
+      var name =  document.createElement("span");
       name.appendChild(document.createTextNode(this._name));
-
+      
       li.appendChild(name);
 
       // Create description
       if (this._desc !== undefined) {
 	var desc = document.createElement("span");
+	desc.classList.add('desc');
 	desc.appendChild(document.createTextNode(this._desc));
 	li.appendChild(desc);
       };
       return this._element = li;
+    }
+  };
+
+  KorAP.HintMenuPrefix = {
+    create : function (params) {
+      return Object.create(KorAP.MenuPrefix).upgradeTo(KorAP.HintMenuPrefix)._init(params);
     },
+    onclick : function () {
+      var m = this.menu();
+      var h = m.hint();
+      m.hide();
 
-    /**
-     * Highlight parts of the item
-     *
-     * @param {string} Prefix string for highlights
-     */
-    highlight : function (prefix) {
-      var e = this.element;
-      this._highlight(e.firstChild, prefix);
-      if (this._desc !== undefined)
-	this._highlight(e.lastChild, prefix);
-    },
+      h.inputField().insert(this.value());
+      h.active = false;
+    }
+  };
 
-    /**
-     * Remove highlight of the menu item
-     */
-    lowlight : function () {
-      var e = this.element;
-      e.firstChild.innerHTML = this._name;
-      if (this._desc !== undefined)
-	e.lastChild.innerHTML = this._desc;
-    },
+  KorAP.HintMenu = {
+    create : function (hint, context, params) {
+      var obj = Object.create(KorAP.Menu)
+	.upgradeTo(KorAP.HintMenu)
+	._init(KorAP.HintMenuItem, KorAP.HintMenuPrefix, params);
+      obj._context = context;
+      obj._element.classList.add('hint');
+      obj._hint = hint;
 
-    // Initialize menu item
-    _init : function (params) {
-      if (params[0] === undefined || params[1] === undefined)
-	throw new Error("Missing parameters");
+      // This is only domspecific
+      obj.element().addEventListener('blur', function (e) {
+	this.menu.hide();
+      });
 
-      this._name   = params[0];
-      this._action = params[1];
-      this._lcfield = " " + this._name.toLowerCase();
-
-      if (params.length > 2) {
-	this._desc = params[2];
-	this._lcfield += " " + this._desc.toLowerCase();
+      // Focus on input field on hide
+      obj.onHide = function () {
+	var input = this._hint.inputField();
+	input.element().focus();
       };
+
+      return obj;
+    },
+    // Todo: Is this necessary?
+    context : function () {
+      return this._context;
+    },
+    hint : function () {
+      return this._hint;
+    }
+  };
+
+
+  /**
+   * KorAP.Hint.create({
+   *   inputField : node,
+   *   context : context regex
+   * });
+   */
+  KorAP.Hint = {
+
+    // Some variables
+    // _firstTry : true,
+    active : false,
+
+    create : function (param) {
+      return Object.create(KorAP.Hint)._init(param);
+    },
+
+    _init : function (param) {
+      param = param || {};
+
+      // Holds all menus per prefix context
+      this._menu = {};
+
+      // Get input field
+      this._inputField = KorAP.InputField.create(
+	param["inputField"] || document.getElementById("q-field")
+      );
+
+      var inputFieldElement = this._inputField.element();
+
+      var that = this;
+
+      // Add event listener for key pressed down
+      inputFieldElement.addEventListener(
+	"keypress", function (e) {
+	  var code = _codeFromEvent(e);
+	  if (code === 40) {
+	    that.show(false);
+	    e.halt();
+	  };
+	}, false
+      );
+
+      // Move infobox 
+      inputFieldElement.addEventListener(
+	"keyup", function (e) {
+	  var input = that._inputField;
+	  input.update();
+	  input.container().style.left = input.rightPos() + 'px';
+	}
+      );
+
+      // Set Analyzer for context
+      this._analyzer = KorAP.ContextAnalyzer.create(
+	param["context"] || KorAP.context
+      );
       return this;
     },
 
-    // Highlight a certain element of the menu item
-    _highlight : function (elem, prefix) {
-      var text   = elem.firstChild.nodeValue;
-      var textlc = text.toLowerCase();
-      var pos    = textlc.indexOf(prefix);
-      if (pos >= 0) {
+    inputField : function () {
+      return this._inputField;
+    },
 
-	// First element
-	elem.firstChild.nodeValue = pos > 0 ? text.substr(0, pos) : "";
+    /**
+     * A new update by keypress
+     */
+    /*
+updateKeyPress : function (e) {
+      if (!this._active)
+	return;
 
-	// Second element
-	var hl = document.createElement("em");
-	hl.appendChild(
-	  document.createTextNode(text.substr(pos, prefix.length))
+      var character = String.fromCharCode(_codeFromEvent(e));
+
+      e.halt(); // No event propagation
+
+      // Only relevant for key down
+      console.log("TODO: filter view");
+    },
+    */
+
+    // updateKeyDown : function (e) {},
+
+    /**
+     * Return hint menu and probably init based on an action
+     */
+    menu : function (action) {
+
+      if (this._menu[action] === undefined) {
+
+	// No matching hint menu
+	if (KorAP.hintArray[action] === undefined)
+	  return;
+
+	// Create matching hint menu
+	this._menu[action] = KorAP.HintMenu.create(
+	  this, action, KorAP.hintArray[action]
 	);
-	elem.appendChild(hl);
 
-	// Third element
-	elem.appendChild(
-	  document.createTextNode(text.substr(pos + prefix.length))
-	);
+      };
+
+      // Return matching hint menu
+      return this._menu[action];
+    },
+
+    /**
+     * Get the correct menu based on the context
+     */
+    contextMenu : function (ifContext) {
+      var context = this._inputField.context();
+      if (context === undefined || context.length == 0)
+	return ifContext ? undefined : this.menu("-");
+
+      context = this._analyzer.test(context);
+      if (context === undefined || context.length == 0)
+	return ifContext ? undefined : this.menu("-");
+
+      return this.menu(context);
+    },
+
+
+    /**
+     * Show the menu
+     */
+    show : function (ifContext) {
+
+      // Menu is already active
+      if (this.active)
+	return;
+
+      // Initialize the menus position
+      /*
+      if (this._firstTry) {
+	this._inputField.reposition();
+	this._firstTry = false;
+      };
+      */
+
+      // update
+
+      // Get the menu
+      var menu;
+      if (menu = this.contextMenu(ifContext)) {
+	this._inputField.container().appendChild(menu.element());
+	menu.show('');
+	menu.focus();
+// Update bounding box
+/*
+      }
+      else if (!ifContext) {
+	//	this.hide();
+      };
+*/
+      // Focus on input field
+      // this.inputField.element.focus();
       };
     }
   };
+
+
+  /**
+   * Return keycode based on event
+   */
+  function _codeFromEvent (e) {
+    if ((e.charCode) && (e.keyCode==0))
+      return e.charCode
+    return e.keyCode;
+  };
+
 }(this.KorAP));
diff --git a/public/js/src/match.js b/public/js/src/match.js
index f8fdd91..b974031 100644
--- a/public/js/src/match.js
+++ b/public/js/src/match.js
@@ -195,7 +195,7 @@
       // Add information, unless it already exists
       info.addEventListener('click', function (e) {
 	e.halt();
-	that.info();
+	that.info().toggle();
       });
 
       ul.appendChild(close);
@@ -204,7 +204,6 @@
       return true;
     },
 
-
     /**
      * Close info view
      */
@@ -219,7 +218,6 @@
     },
 
 
-
     /**
      * Get and open associated match info.
      */
@@ -235,14 +233,9 @@
 	return this._info;
 
       // Info is already activated
-      if (this._info._elemet !== undefined)
+      if (this._info._element !== undefined)
 	return this._info;
 
-      // Append element to match
-      this._element.children[0].appendChild(
-	this._info.element()
-      );
-
       return this._info;
     },
 
@@ -276,10 +269,10 @@
      */
     _init : function (match) {
       this._match = match;
+      this.opened = false;
       return this;
     },
 
-
     /**
      * Get match object
      */
@@ -287,6 +280,24 @@
       return this._match;
     },
 
+    toggle : function () {
+      if (this.opened == true) {
+	this._match.element().children[0].removeChild(
+	  this.element()
+	);
+	this.opened = false;
+      }
+      else {
+	// Append element to match
+	this._match.element().children[0].appendChild(
+	  this.element()
+	);
+	this.opened = true;
+      };
+
+      return this.opened;
+    },
+
 
     /**
      * Retrieve and parse snippet for table representation
diff --git a/public/js/src/menu.js b/public/js/src/menu.js
index a7271c5..3267b69 100644
--- a/public/js/src/menu.js
+++ b/public/js/src/menu.js
@@ -52,7 +52,7 @@
       for (var i = 0; i < this._items.length; i++) {
 	delete this._items[i]["_menu"];
       };
-      
+      delete this._prefix['_menu'];
     },
 
     focus : function () {
@@ -147,11 +147,13 @@
       else
 	this._prefix = KorAP.MenuPrefix.create();
 
+      this._prefix._menu = this;
+
       var e = document.createElement("ul");
       e.style.opacity = 0;
       e.style.outline = 0;
       e.setAttribute('tabindex', 0);
-      e.setAttribute('class', 'menu');
+      e.classList.add('menu');
       e.appendChild(this._prefix.element());
 
       // This has to be cleaned up later on
@@ -274,9 +276,13 @@
       this.active = false;
       this.delete();
       this._element.style.opacity = 0;
+      this.onHide();
       /* this._element.blur(); */
     },
 
+    // To be override
+    onHide : function () {},
+
     // Initialize the list
     _initList : function () {
 
@@ -676,7 +682,6 @@
       return this;
     },
 
-
     content : function (content) {
       if (arguments.length === 1)
 	this._content = document.createTextNode(content);
@@ -737,8 +742,9 @@
       var li = document.createElement("li");
 
       // Connect action
-      if (this.onclick !== undefined)
+      if (this["onclick"] !== undefined) {
 	li["onclick"] = this.onclick.bind(this);
+      };
 
       // Append template
       li.appendChild(this.content());
@@ -866,7 +872,8 @@
       this._element = document.createElement('span');
       this._element.classList.add('pref');
       // Connect action
-      if (this.onclick !== undefined)
+
+      if (this["onclick"] !== undefined)
 	this._element["onclick"] = this.onclick.bind(this);
 
       return this;
@@ -898,13 +905,16 @@
       else
 	cl.remove("active");
     },
+
     element : function () {
       return this._element;
     },
+
     isSet : function () {
       return this._string.length > 0 ?
 	true : false;
     },
+
     value : function (string) {
       if (arguments.length === 1) {
 	this._string = string;
@@ -912,11 +922,14 @@
       };
       return this._string;
     },
+
     add : function (string) {
       this._string += string;
       this._update();
     },
-    onclick : function (e) {},
+
+    onclick : function () {},
+
     backspace : function () {
       if (this._string.length > 1) {
 	this._string = this._string.substring(
@@ -928,6 +941,13 @@
       };
 
       this._update();
+    },
+
+    /**
+     * Return menu list.
+     */
+    menu : function () {
+      return this._menu;
     }
   };
 
diff --git a/public/js/src/util.js b/public/js/src/util.js
index 0f0f114..3adf5a0 100644
--- a/public/js/src/util.js
+++ b/public/js/src/util.js
@@ -31,35 +31,36 @@
 (function (KorAP) {
   "use strict";
 
+
+  /**
+   * Initialize user interface elements
+   */
   KorAP.init = function () {
 
     /**
      * Add actions to match entries
      */
-    var inactiveLi = document.querySelectorAll('#search > ol > li:not(.active)');
+    var inactiveLi = document.querySelectorAll(
+      '#search > ol > li:not(.active)'
+    );
     var i = 0;
     for (i = 0; i < inactiveLi.length; i++) {
-      inactiveLi[i].addEventListener('click', function () {
-
-	if (this._match !== undefined) {
+      inactiveLi[i].addEventListener('click', function (e) {
+	if (this._match !== undefined)
 	  this._match.open();
-	  console.log('already open');
-	}
-	else {
+	else
 	  KorAP.Match.create(this).open();
-	  console.log('newly open');
-	}
-
-	
+	e.halt();
       });
     };
 
+
     /**
      * Toggle the alignment (left <=> right)
      */
     if (i > 0) {
       var br = document.getElementById('button-right');
-      if (br !== undefined) {
+      if (br !== null) {
 	var toggle = document.createElement('a');
 	toggle.setAttribute('title', 'toggle Alignment');
 	// Todo: Reuse old alignment from cookie!
@@ -78,57 +79,11 @@
 	br.appendChild(toggle);
       };
     };
+
+    /**
+     * Init hint helper
+     */
+    KorAP.Hint.create();
   };
 
-  /*
-  function _openMatch (e) {
-    e.halt();
-    this.classList.add("active");
-    var matchElement = this;
-
-    // Todo: Add object to element
-    var ul = document.createElement('ul');
-    ul.classList.add('action', 'right');
-    matchElement.appendChild(ul);
-
-    // Todo:: Localize!
-    var close = document.createElement('li');
-    close.appendChild(document.createElement('span'))
-      .appendChild(document.createTextNode('Close'));
-    close.classList.add('close');
-    close.setAttribute('title', 'Close');
-
-    close.addEventListener('click', function (ie) {
-      ie.halt();
-      var match = matchElement['_match'];
-      match.destroy();
-      matchElement.classList.remove('active');
-      matchElement.removeChild(ul);
-    });
-
-    // Todo:: Localize!
-    var info = document.createElement('li');
-    info.appendChild(document.createElement('span'))
-      .appendChild(document.createTextNode('Info'));
-    info.classList.add('info');
-    info.setAttribute('title', 'Information');
-
-    // Add information, unless it already exists
-    info.addEventListener('click', function (ie) {
-      ie.halt();
-      KorAP.Match.create(matchElement).addInfo();
-    });
-
-    ul.appendChild(close);
-    ul.appendChild(info);
-  };
-*/
-
-  /**
-  function _closeMatch (e) {
-    e.halt();
-    this.parentNode.parentNode.classList.remove("active");
-  };
-  */
-
 }(this.KorAP));
