diff --git a/dev/js/src/api.js b/dev/js/src/api.js
index ed33cc2..f9058bc 100644
--- a/dev/js/src/api.js
+++ b/dev/js/src/api.js
@@ -1,15 +1,4 @@
-var KorAP = KorAP || {};
-
-(function (KorAP) {
-  "use strict";
-
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
-
-  KorAP.URL = KorAP.URL || 'http://korap.ids-mannheim.de/kalamar';
-
+define(['util'], function () {
   // TODO: https://github.com/honza/140medley/blob/master/140medley.js
   // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
   // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
@@ -17,6 +6,8 @@
   // http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
   // http://stackoverflow.com/questions/6112744/load-javascript-on-demand
 
+  KorAP.URL = KorAP.URL || 'http://korap.ids-mannheim.de/kalamar';
+
   KorAP.API = {
     getMatchInfo : function (match, param, cb) {
       // match is a KorAP.Match object
@@ -44,14 +35,11 @@
 
       this.getJSON(url, cb);
     },
+
     getJSON : function (url, onload) {
       var req = new XMLHttpRequest();
 
-      console.log('Request url: ' + url);
-
       req.open("GET", url, true);
-
-
       req.setRequestHeader("Accept", "application/json");
       req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
       req.onreadystatechange = function () {
@@ -62,7 +50,7 @@
 	  2 - headers received
 	  3 - loading (responseText has partial data)
 	  4 - done
-	 */
+	*/
 	if (this.readyState == 4) {
 	  if (this.status === 200)
 	    onload(JSON.parse(this.responseText));
@@ -76,5 +64,4 @@
       req.send();
     }
   };
-
-}(this.KorAP));
+});
diff --git a/dev/js/src/hint.js b/dev/js/src/hint.js
index 11c3e1e..6aed544 100644
--- a/dev/js/src/hint.js
+++ b/dev/js/src/hint.js
@@ -3,23 +3,20 @@
  *
  * @author Nils Diewald
  */
-
-// requires menu.js
-
-var KorAP = KorAP || {};
-
-(function (KorAP) {
+define([
+  'hint/input',
+  'hint/menu',
+  'hint/contextanalyzer',
+  'util'
+], function (inputClass, 
+	     menuClass, 
+	     analyzerClass) {
   "use strict";
 
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
-
   /**
    * @define {regex} Regular expression for context
    */
-  KorAP.context =
+  KorAP.context = KorAP.context ||
     "(?:^|[^-_a-zA-Z0-9])" +   // Anchor
     "((?:[-_a-zA-Z0-9]+?)\/" + // Foundry
     "(?:" +
@@ -27,10 +24,18 @@
     "(?:(?:[^:=\/ ]+?):)?" +   // Key
     ")?" +
     ")$";
-
-  // Initialize hint array
   KorAP.hintArray = KorAP.hintArray || {};
 
+  /**
+   * Return keycode based on event
+   */
+  function _codeFromEvent (e) {
+    if ((e.charCode) && (e.keyCode==0))
+      return e.charCode
+    return e.keyCode;
+  };
+
+  // Initialize hint array
 
   /**
    * KorAP.Hint.create({
@@ -38,16 +43,20 @@
    *   context : context regex
    * });
    */
-  KorAP.Hint = {
+  return {
 
     // Some variables
     // _firstTry : true,
     active : false,
 
+    /**
+     * Create new hint helper.
+     */
     create : function (param) {
-      return Object.create(KorAP.Hint)._init(param);
+      return Object.create(this)._init(param);
     },
 
+    // Initialize hint helper
     _init : function (param) {
       param = param || {};
 
@@ -55,9 +64,11 @@
       this._menu = {};
 
       // Get input field
-      this._inputField = KorAP.InputField.create(
-	param["inputField"] || document.getElementById("q-field")
-      );
+      var qfield = param["inputField"] || document.getElementById("q-field");
+      if (!qfield)
+	return null;
+
+      this._inputField = inputClass.create(qfield);
 
       var inputFieldElement = this._inputField.element();
 
@@ -83,7 +94,7 @@
       );
 
       // Set Analyzer for context
-      this._analyzer = KorAP.ContextAnalyzer.create(
+      this._analyzer = analyzerClass.create(
 	param["context"] || KorAP.context
       );
       return this;
@@ -124,10 +135,9 @@
 	  return;
 
 	// Create matching hint menu
-	this._menu[action] = KorAP.HintMenu.create(
+	this._menu[action] = menuClass.create(
 	  this, action, KorAP.hintArray[action]
 	);
-
       };
 
       // Return matching hint menu
@@ -189,278 +199,4 @@
       };
     }
   };
-
-
-  // Input field for queries
-  KorAP.InputField = {
-    create : function (element) {
-      return Object.create(KorAP.InputField)._init(element);
-    },
-
-    _init : function (element) {
-      this._element = element;
-
-      // Create mirror for searchField
-      if ((this._mirror = document.getElementById("searchMirror")) === null) {
-	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 = "0px";
-	document.getElementsByTagName("body")[0].appendChild(this._mirror);
-      };
-
-      // Update position of the mirror
-      var that = this;
-      var repos = function () {
-	that.reposition();
-      };
-      window.addEventListener('resize', repos);
-      this._element.addEventListener('onfocus', repos);
-      that.reposition();
-
-      return this;
-    },
-
-    rightPos : function () {
-      var box = this._mirror.firstChild.getBoundingClientRect();
-      return box.right - box.left;
-    },
-
-    mirror : function () {
-      return this._mirror;
-    },
-
-    container : function () {
-      return this._container;
-    },
-
-    element : function () {
-      return this._element;
-    },
-
-    value : function () {
-      return this._element.value;
-    },
-
-    update : function () {
-      this._mirror.firstChild.textContent = this.split()[0];
-      this._container.style.left = this.rightPos() + 'px';
-    },
-
-    insert : function (text) {
-      var splittedText = this.split();
-      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 cursor position
-    split : function () {
-      var s = this._element;
-      var value = s.value;
-      var start = s.selectionStart;
-      return new Array(
-	value.substring(0, start),
-	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);
-
-      var bodyClientRect = 
-	document.getElementsByTagName('body')[0].getBoundingClientRect();
-
-      // Reset position
-      var mirrorStyle = this._mirror.style;
-      mirrorStyle.left = inputClientRect.left + "px";
-      mirrorStyle.top  = (inputClientRect.bottom - bodyClientRect.top) + "px";
-      mirrorStyle.width = inputStyle.getPropertyValue("width");
-
-      // These may be relevant in case of media depending css
-      mirrorStyle.paddingLeft     = inputStyle.getPropertyValue("padding-left");
-      mirrorStyle.marginLeft      = inputStyle.getPropertyValue("margin-left");
-      mirrorStyle.borderLeftWidth = inputStyle.getPropertyValue("border-left-width");
-      mirrorStyle.borderLeftStyle = inputStyle.getPropertyValue("border-left-style");
-      mirrorStyle.fontSize        = inputStyle.getPropertyValue("font-size");
-      mirrorStyle.fontFamily      = inputStyle.getPropertyValue("font-family");
-    },
-    context : function () {
-      return this.split()[0];
-    }
-  };
-
-
-  /**
-   * Regex object for checking the context of the hint
-   */
-  KorAP.ContextAnalyzer = {
-    create : function (regex) {
-      return Object.create(KorAP.ContextAnalyzer)._init(regex);
-    },
-    _init : function (regex) {
-      try {
-	this._regex = new RegExp(regex);
-      }
-      catch (e) {
-	KorAP.log(0, e);
-	return;
-      };
-      return this;
-    },
-    test : function (text) {
-      if (!this._regex.exec(text))
-	return;
-      return RegExp.$1;
-    }
-  };
-
-
-  /**
-   * Hint menu
-   */
-  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;
-
-      // This is only domspecific
-      obj.element().addEventListener('blur', function (e) {
-	this.menu.hide();
-      });
-
-      // Focus on input field on hide
-      obj.onHide = function () {
-	var input = this._hint.inputField();
-	input.container().classList.remove('active');
-	input.element().focus();
-      };
-
-      return obj;
-    },
-    // Todo: Is this necessary?
-    context : function () {
-      return this._context;
-    },
-    hint : function () {
-      return this._hint;
-    }
-  };
-
-
-  /**
-   * Hint menu item based on MenuItem
-   */
-  KorAP.HintMenuItem = {
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)
-	.upgradeTo(KorAP.HintMenuItem)
-	._init(params);
-    },
-    _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();
-      };
-
-      return this;
-    },
-    content : function (content) {
-      if (arguments.length === 1) {
-	this._content = content;
-      };
-      return this._content;
-    },
-    onclick : function () {
-      var m = this.menu();
-      var h = m.hint();
-      m.hide();
-
-      // Update input field
-      var input = h.inputField();
-      input.insert(this._action);
-      input.update();
-
-      h.active = false;
-      h.show(true);
-    },
-    name : function () {
-      return this._name;
-    },
-    action : function () {
-      return this._action;
-    },
-    desc : function () {
-      return this._desc;
-    },
-    element : function () {
-      // already defined
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create list item
-      var li = document.createElement("li");
-
-      if (this.onclick !== undefined) {
-	li["onclick"] = this.onclick.bind(this);
-      };
-
-      // Create title
-      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();
-
-      h.inputField().insert(this.value());
-      h.active = false;
-    }
-  };
-
-
-  /**
-   * 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/dev/js/src/hint/contextanalyzer.js b/dev/js/src/hint/contextanalyzer.js
new file mode 100644
index 0000000..bdbf885
--- /dev/null
+++ b/dev/js/src/hint/contextanalyzer.js
@@ -0,0 +1,23 @@
+/**
+ * Regex object for checking the context of the hint
+ */
+define({
+  create : function (regex) {
+    return Object.create(this)._init(regex);
+  },
+  _init : function (regex) {
+    try {
+      this._regex = new RegExp(regex);
+    }
+    catch (e) {
+      KorAP.log(0, e);
+      return;
+    };
+    return this;
+  },
+  test : function (text) {
+    if (!this._regex.exec(text))
+      return;
+    return RegExp.$1;
+  }
+});
diff --git a/dev/js/src/hint/input.js b/dev/js/src/hint/input.js
new file mode 100644
index 0000000..b1c6632
--- /dev/null
+++ b/dev/js/src/hint/input.js
@@ -0,0 +1,103 @@
+// Input field for queries
+define({
+  create : function (element) {
+    return Object.create(this)._init(element);
+  },
+    
+  _init : function (element) {
+    this._element = element;
+
+    // Create mirror for searchField
+    if ((this._mirror = document.getElementById("searchMirror")) === null) {
+      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 = "0px";
+      document.getElementsByTagName("body")[0].appendChild(this._mirror);
+    };
+
+    // Update position of the mirror
+    var that = this;
+    var repos = function () {
+      that.reposition();
+    };
+    window.addEventListener('resize', repos);
+    this._element.addEventListener('onfocus', repos);
+    that.reposition();
+
+    return this;
+  },
+
+  rightPos : function () {
+    var box = this._mirror.firstChild.getBoundingClientRect();
+    return box.right - box.left;
+  },
+
+  mirror : function () {
+    return this._mirror;
+  },
+
+  container : function () {
+    return this._container;
+  },
+
+  element : function () {
+    return this._element;
+  },
+
+  value : function () {
+    return this._element.value;
+  },
+
+  update : function () {
+    this._mirror.firstChild.textContent = this.split()[0];
+    this._container.style.left = this.rightPos() + 'px';
+  },
+
+  insert : function (text) {
+    var splittedText = this.split();
+    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 cursor position
+  split : function () {
+    var s = this._element;
+    var value = s.value;
+    var start = s.selectionStart;
+    return new Array(
+      value.substring(0, start),
+      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);
+
+    var bodyClientRect = 
+      document.getElementsByTagName('body')[0].getBoundingClientRect();
+
+    // Reset position
+    var mirrorStyle = this._mirror.style;
+    mirrorStyle.left = inputClientRect.left + "px";
+    mirrorStyle.top  = (inputClientRect.bottom - bodyClientRect.top) + "px";
+    mirrorStyle.width = inputStyle.getPropertyValue("width");
+    
+    // These may be relevant in case of media depending css
+    mirrorStyle.paddingLeft     = inputStyle.getPropertyValue("padding-left");
+    mirrorStyle.marginLeft      = inputStyle.getPropertyValue("margin-left");
+    mirrorStyle.borderLeftWidth = inputStyle.getPropertyValue("border-left-width");
+    mirrorStyle.borderLeftStyle = inputStyle.getPropertyValue("border-left-style");
+    mirrorStyle.fontSize        = inputStyle.getPropertyValue("font-size");
+    mirrorStyle.fontFamily      = inputStyle.getPropertyValue("font-family");
+  },
+  context : function () {
+    return this.split()[0];
+  }
+});
diff --git a/dev/js/src/hint/item.js b/dev/js/src/hint/item.js
new file mode 100644
index 0000000..f23cabc
--- /dev/null
+++ b/dev/js/src/hint/item.js
@@ -0,0 +1,85 @@
+/**
+ * Hint menu item based on MenuItem
+ */
+define(['menu/item'], function (itemClass) {
+  return {
+    create : function (params) {
+      return Object.create(itemClass)
+	.upgradeTo(this)
+	._init(params);
+    },
+    _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();
+      };
+
+      return this;
+    },
+
+    content : function (content) {
+      if (arguments.length === 1) {
+	this._content = content;
+      };
+      return this._content;
+    },
+    
+    onclick : function () {
+      var m = this.menu();
+      var h = m.hint();
+      m.hide();
+
+      // Update input field
+      var input = h.inputField();
+      input.insert(this._action);
+      input.update();
+
+      h.active = false;
+      h.show(true);
+    },
+    name : function () {
+      return this._name;
+    },
+    action : function () {
+      return this._action;
+    },
+    desc : function () {
+      return this._desc;
+    },
+    element : function () {
+      // already defined
+      if (this._element !== undefined)
+	return this._element;
+
+      // Create list item
+      var li = document.createElement("li");
+
+      if (this.onclick !== undefined) {
+	li["onclick"] = this.onclick.bind(this);
+      };
+
+      // Create title
+      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;
+    }
+  };
+});
diff --git a/dev/js/src/hint/menu.js b/dev/js/src/hint/menu.js
new file mode 100644
index 0000000..c579945
--- /dev/null
+++ b/dev/js/src/hint/menu.js
@@ -0,0 +1,36 @@
+/**
+ * Hint menu
+ */
+define(['menu', 'hint/item', 'hint/prefix'], function (menuClass, itemClass, prefixClass) {
+  return {
+    create : function (hint, context, params) {
+      var obj = Object.create(menuClass)
+	.upgradeTo(this)
+	._init(itemClass, prefixClass, params);
+      obj._context = context;
+      obj._element.classList.add('hint');
+      obj._hint = hint;
+
+      // This is only domspecific
+      obj.element().addEventListener('blur', function (e) {
+	this.menu.hide();
+      });
+
+      // Focus on input field on hide
+      obj.onHide = function () {
+	var input = this._hint.inputField();
+	input.container().classList.remove('active');
+	input.element().focus();
+      };
+
+      return obj;
+    },
+    // Todo: Is this necessary?
+    context : function () {
+      return this._context;
+    },
+    hint : function () {
+      return this._hint;
+    }
+  };
+});
diff --git a/dev/js/src/hint/prefix.js b/dev/js/src/hint/prefix.js
new file mode 100644
index 0000000..84f785a
--- /dev/null
+++ b/dev/js/src/hint/prefix.js
@@ -0,0 +1,15 @@
+define(['menu/prefix'], function (prefixClass) {
+  return {
+    create : function (params) {
+      return Object.create(prefixClass).upgradeTo(this)._init(params);
+    },
+    onclick : function () {
+      var m = this.menu();
+      var h = m.hint();
+      m.hide();
+
+      h.inputField().insert(this.value());
+      h.active = false;
+    }
+  };
+});
diff --git a/dev/js/src/init.js b/dev/js/src/init.js
index ecaad6f..66bc081 100644
--- a/dev/js/src/init.js
+++ b/dev/js/src/init.js
@@ -1,42 +1,17 @@
-/**
- * These are utility functions for the frontend
- */
-
-// Add toggleClass method similar to jquery
-HTMLElement.prototype.toggleClass = function (c1, c2) {
-  var cl = this.classList;
-  if (cl.contains(c1)) {
-    cl.add(c2);
-    cl.remove(c1);
-  }
-  else {
-    cl.remove(c2);
-    cl.add(c1);
-  };
-};
-
-
-// Don't let events bubble up
-if (Event.halt === undefined) {
-  // Don't let events bubble up
-  Event.prototype.halt = function () {
-    this.stopPropagation();
-    this.preventDefault();
-  };
-};
-
-var KorAP = KorAP || {};
-
-
-(function (KorAP) {
-  "use strict";
-
-
-  /**
-   * Initialize user interface elements
-   */
-  KorAP.init = function () {
-    var obj = Object.create(KorAP.init);
+define([
+  'match',
+  'hint',
+  'vc',
+  'tutorial',
+  'lib/domReady',
+  'util'
+], function (matchClass,
+	     hintClass,
+	     vcClass,
+	     tutClass,
+	     domReady) {
+  domReady(function (event) {
+    var obj = {};
 
     /**
      * Add actions to match entries
@@ -49,13 +24,13 @@
       inactiveLi[i].addEventListener('click', function (e) {
 	if (this._match !== undefined)
 	  this._match.open();
-	else
-	  KorAP.Match.create(this).open();
+	else {
+	  matchClass.create(this).open();
+	};
 	e.halt();
       });
     };
 
-
     /**
      * Toggle the alignment (left <=> right)
      */
@@ -97,28 +72,29 @@
       input.parentNode.insertBefore(vcname, input);
       
       vcname.onclick = function () {
-	var vc = KorAP.VirtualCollection.render(vcExample);
+	var vc = vcClass.render(vcExample);
 	var view = document.getElementById('vc-view');
 	view.appendChild(vc.element());
       };
     };
 
+  
     /**
      * Init Tutorial view
      */
-    obj.tutorial = KorAP.Tutorial.create(
+    obj.tutorial = tutClass.create(
       document.getElementById('view-tutorial')
     );
 
+  
     /**
      * Init hint helper
      * has to be final because of
      * reposition
      */
-// Todo: Pass an element, so this works with
-// tutorial pages as well!
-    obj.hint = KorAP.Hint.create();
+    // Todo: Pass an element, so this works with
+    // tutorial pages as well!
+    obj.hint = hintClass.create();
     return obj;
-  };
-
-}(this.KorAP));
+  });
+});
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index 4e3786b..beb4bca 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -4,46 +4,31 @@
  *
  * @author Nils Diewald
  */
-// require menu.js, dagre
 /*
  * - Highlight (at least mark as bold) the match
  * - Scroll to match vertically per default
  */
-var KorAP = KorAP || {};
-
-(function (KorAP) {
-  "use strict";
-
-  var svgXmlns = "http://www.w3.org/2000/svg";
-
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
+define([
+  'match/infolayer',
+  'match/info',
+  'util'
+], function (infoLayerClass,
+	     infoClass) {
 
   // Localization values
-  var loc   = (KorAP.Locale = KorAP.Locale || {} );
+  var loc   = KorAP.Locale;
   loc.ADDTREE  = loc.ADDTREE  || 'Add tree view';
   loc.SHOWINFO = loc.SHOWINFO || 'Show information';
   loc.CLOSE    = loc.CLOSE    || 'Close';
-
-  KorAP._AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
-  KorAP._TermRE      = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
-  KorAP._matchTerms  = ['corpusID', 'docID', 'textID', 'matchID', 'available'];
-
-  // API requests
-  KorAP.API = KorAP.API || {};
-
-  // TODO: Make this async
-  KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
-    KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
-    return {};
-  };
+  
+  // KorAP._AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
+  // KorAP._TermRE      = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
+  var _matchTerms  = ['corpusID', 'docID', 'textID', 'matchID', 'available'];
 
   /**
    * Match object
    */
-  KorAP.Match = {
+  return {
 
     /**
      * Create a new annotation object.
@@ -51,7 +36,7 @@
      * Supported types are 'spans', 'tokens' and 'rels'.
      */
     create : function (match) {
-      return Object.create(KorAP.Match)._init(match);
+      return Object.create(this)._init(match);
     },
 
     /**
@@ -87,8 +72,8 @@
       else {
 
 	// Iterate over allowed match terms
-	for (var i in KorAP._matchTerms) {
-	  var term = KorAP._matchTerms[i];
+	for (var i in _matchTerms) {
+	  var term = _matchTerms[i];
 	  if (match[term] !== undefined) {
 	    this[term] = match[term];
 	  }
@@ -97,7 +82,7 @@
 	  }
 	};
       };
-
+      
       this._available = {
 	tokens : [],
 	spans  : [],
@@ -110,7 +95,7 @@
 
 	// Create info layer objects
 	try {
-	  var layer = KorAP.InfoLayer.create(term);
+	  var layer = infoLayerClass.create(term);
 	  this._available[layer.type].push(layer);
 	}
 	catch (e) {
@@ -178,7 +163,7 @@
 	.appendChild(document.createTextNode(loc.CLOSE));
       close.classList.add('close');
       close.setAttribute('title', loc.CLOSE);
-
+      
       // Add info button
       var info = document.createElement('li');
       info.appendChild(document.createElement('span'))
@@ -227,7 +212,7 @@
 
       // Create match info
       if (this._info === undefined)
-	this._info = KorAP.MatchInfo.create(this);
+	this._info = infoClass.create(this);
 
       // There is an element to append
       if (this._element === undefined ||
@@ -251,812 +236,4 @@
       return this._element;
     }
   };
-
-
-
-  /**
-   * Information about a match.
-   */
-  KorAP.MatchInfo = {
-
-    /**
-     * Create new object
-     */
-    create : function (match) {
-      return Object.create(KorAP.MatchInfo)._init(match);
-    },
-
-    /**
-     * Initialize object
-     */
-    _init : function (match) {
-      this._match = match;
-      this.opened = false;
-      return this;
-    },
-
-    /**
-     * Get match object
-     */
-    match : function () {
-      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
-     */
-    getTable : function (tokens, cb) {
-      var focus = [];
-
-      // Get all tokens
-      if (tokens === undefined) {
-	focus = this._match.getTokens();
-      } 
-
-      // Get only some tokens
-      else {
-
-	// Push newly to focus array
-	for (var i = 0; i < tokens.length; i++) {
-	  var term = tokens[i];
-	  try {
-	    // Create info layer objects
-	    var layer = KorAP.InfoLayer.create(term);
-	    layer.type = "tokens";
-	    focus.push(layer);
-	  }
-	  catch (e) {
-	    continue;
-	  };
-	};
-      };
-
-      // No tokens chosen
-      if (focus.length == 0)
-	cb(null);
-
-      // Get info (may be cached)
-      // TODO: Async
-      KorAP.API.getMatchInfo(
-	this._match,
-	{ 'spans' : false, 'layer' : focus },
-
-	// Callback for retrieval
-	function (matchResponse) {
-	  // Get snippet from match info
-	  if (matchResponse["snippet"] !== undefined) {
-	    this._table = KorAP.MatchTable.create(matchResponse["snippet"]);
-	    cb(this._table);
-	  };
-	}.bind(this)
-      );
-
-/*
-      // Todo: Store the table as a hash of the focus
-      return null;
-*/
-    },
-
-
-    /**
-     * Retrieve and parse snippet for tree representation
-     */
-    getTree : function (foundry, layer, cb) {
-      var focus = [];
-
-      // TODO: Support and cache multiple trees
-
-      KorAP.API.getMatchInfo(
-	this._match, {
-	  'spans' : true,
-	  'foundry' : foundry,
-	  'layer' : layer
-	},
-	function (matchResponse) {
-	  // Get snippet from match info
-	  if (matchResponse["snippet"] !== undefined) {
-	    // Todo: This should be cached somehow
-	    cb(KorAP.MatchTree.create(matchResponse["snippet"]));
-	  }
-	  else {
-	    cb(null);
-	  };
-	}.bind(this)
-      );
-    },
-
-    /**
-     * Destroy this match information view.
-     */
-    destroy : function () {
-
-      // Remove circular reference
-      if (this._treeMenu !== undefined)
-	delete this._treeMenu["info"];
-
-      this._treeMenu.destroy();
-      this._treeMenu = undefined;
-      this._match = undefined;
-
-      // Element destroy
-    },
-
-
-    /**
-     * Add a new tree view to the list
-     */
-    addTree : function (foundry, layer, cb) {
-      var matchtree = document.createElement('div');
-      matchtree.classList.add('matchtree');
-
-      var h6 = matchtree.appendChild(document.createElement('h6'));
-      h6.appendChild(document.createElement('span'))
-	.appendChild(document.createTextNode(foundry));
-      h6.appendChild(document.createElement('span'))
-	.appendChild(document.createTextNode(layer));
-
-      var tree = matchtree.appendChild(
-	document.createElement('div')
-      );
-
-      this._element.insertBefore(matchtree, this._element.lastChild);
-
-      var close = tree.appendChild(document.createElement('em'));
-      close.addEventListener(
-	'click', function (e) {
-	  matchtree.parentNode.removeChild(matchtree);
-	  e.halt();
-	}
-      );
-
-      // Get tree data async
-      this.getTree(foundry, layer, function (treeObj) {
-	// Something went wrong - probably log!!!
-	if (treeObj === null) {
-	  tree.appendChild(document.createTextNode('No data available.'));
-	}
-	else {
-	  tree.appendChild(treeObj.element());
-	  // Reposition the view to the center
-	  // (This may in a future release be a reposition
-	  // to move the root into the center or the actual
-	  // match)
-	  treeObj.center();
-	}
-
-	if (cb !== undefined)
-	  cb(treeObj);
-      });
-    },
-
-    /**
-     * Create match information view.
-     */
-    element : function () {
-
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create info table
-      var info = document.createElement('div');
-      info.classList.add('matchinfo');
-
-      // Append default table
-      var matchtable = document.createElement('div');
-      matchtable.classList.add('matchtable');
-      info.appendChild(matchtable);
-
-      // Create the table asynchronous
-      this.getTable(undefined, function (table) {
-	if (table !== null) {
-	  matchtable.appendChild(table.element());
-	};
-      });
-
-      // Get spans
-      var spanLayers = this._match.getSpans().sort(
-	function (a, b) {
-	  if (a.foundry < b.foundry) {
-	    return -1;
-	  }
-	  else if (a.foundry > b.foundry) {
-	    return 1;
-	  }
-	  else if (a.layer < b.layer) {
-	    return -1;
-	  }
-	  else if (a.layer > b.layer) {
-	    return 1;
-	  };
-	  return 0;
-	});
-
-      var menuList = [];
-
-      // Show tree views
-      for (var i = 0; i < spanLayers.length; i++) {
-	var span = spanLayers[i];
-	
-	// Add foundry/layer to menu list
-	menuList.push([
-	  span.foundry + '/' + span.layer,
-	  span.foundry,
-	  span.layer
-	]);
-      };
-
-      // Create tree menu
-      var treemenu = this.treeMenu(menuList);
-      var span = info.appendChild(document.createElement('p'));
-      span.classList.add('addtree');
-      span.appendChild(document.createTextNode(loc.ADDTREE));
-
-      var treeElement = treemenu.element();
-      span.appendChild(treeElement);
-
-      span.addEventListener('click', function (e) {
-	treemenu.show('');
-	treemenu.focus();
-      });
-      
-      this._element = info;
-
-      return info;
-
-    },
-
-
-    /**
-     * Get tree menu.
-     * There is only one menu rendered
-     * - no matter how many trees exist
-     */
-    treeMenu : function (list) {
-      if (this._treeMenu !== undefined)
-	return this._treeMenu;
-
-      return this._treeMenu = KorAP.MatchTreeMenu.create(this, list);
-    }
-  };
-
-
-
-  /**
-   *
-   * Alternatively pass a string as <tt>base/s=span</tt>
-   *
-   * @param foundry
-   */
-  KorAP.InfoLayer = {
-    create : function (foundry, layer, type) {
-      return Object.create(KorAP.InfoLayer)._init(foundry, layer, type);
-    },
-    _init : function (foundry, layer, type) {
-      if (foundry === undefined)
-	throw new Error("Missing parameters");
-
-      if (layer === undefined) {
-	if (KorAP._AvailableRE.exec(foundry)) {
-	  this.foundry = RegExp.$1;
-	  this.layer = RegExp.$2;
-	  this.type = RegExp.$3;
-	}
-	else {
-	  throw new Error("Missing parameters");
-	};
-      }
-      else {
-	this.foundry = foundry;
-	this.layer = layer;
-	this.type = type;
-      };
-
-      if (this.type === undefined)
-	this.type = 'tokens';
-
-      return this;
-    }
-  };
-
-
-  KorAP.MatchTable = {
-    create : function (snippet) {
-      return Object.create(KorAP.MatchTable)._init(snippet);
-    },
-    _init : function (snippet) {
-      // Create html for traversal
-      var html = document.createElement("div");
-      html.innerHTML = snippet;
-
-      this._pos = 0;
-      this._token = [];
-      this._info = [];
-      this._foundry = {};
-      this._layer = {};
-
-      // Parse the snippet
-      this._parse(html.childNodes);      
-
-      html.innerHTML = '';
-      return this;
-    },
-
-    length : function () {
-      return this._pos;
-    },
-
-    getToken : function (pos) {
-      if (pos === undefined)
-	return this._token;
-      return this._token[pos];
-    },
-
-    getValue : function (pos, foundry, layer) {
-      return this._info[pos][foundry + '/' + layer]
-    },
-
-    getLayerPerFoundry : function (foundry) {
-      return this._foundry[foundry]
-    },
-
-    getFoundryPerLayer : function (layer) {
-      return this._layer[layer];
-    },
-
-    // Parse the snippet
-    _parse : function (children) {
-
-      // Get all children
-      for (var i in children) {
-	var c = children[i];
-
-	// Create object on position unless it exists
-	if (this._info[this._pos] === undefined)
-	  this._info[this._pos] = {};
-
-	// Store at position in foundry/layer as array
-	var found = this._info[this._pos];
-
-	// Element with title
-	if (c.nodeType === 1) {
-	  if (c.getAttribute("title") &&
-	      KorAP._TermRE.exec(c.getAttribute("title"))) {
-
-	    // Fill position with info
-	    var foundry, layer, value;
-	    if (RegExp.$2) {
-	      foundry = RegExp.$1;
-	      layer   = RegExp.$2;
-	    }
-	    else {
-	      foundry = "base";
-	      layer   = RegExp.$1
-	    };
-
-	    value = RegExp.$3;
-
-	    if (found[foundry + "/" + layer] === undefined)
-	      found[foundry + "/" + layer] = [];
-
-	    // Push value to foundry/layer at correct position
-	    found[foundry + "/" + layer].push(RegExp.$3);
-
-	    // Set foundry
-	    if (this._foundry[foundry] === undefined)
-	      this._foundry[foundry] = {};
-	    this._foundry[foundry][layer] = 1;
-
-	    // Set layer
-	    if (this._layer[layer] === undefined)
-	      this._layer[layer] = {};
-	    this._layer[layer][foundry] = 1;
-	  };
-
-	  // depth search
-	  if (c.hasChildNodes())
-	    this._parse(c.childNodes);
-	}
-
-	// Leaf node
-	// store string on position and go to next string
-	else if (c.nodeType === 3) {
-	  if (c.nodeValue.match(/[a-z0-9]/i))
-	    this._token[this._pos++] = c.nodeValue;
-	};
-      };
-
-      delete this._info[this._pos];
-    },
-
-
-    /**
-     * Get HTML table view of annotations.
-     */
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      // First the legend table
-      var d = document;
-      var table = d.createElement('table');
-
-      // Single row in head
-      var tr = table.appendChild(d.createElement('thead'))
-	.appendChild(d.createElement('tr'));
-
-      // Add cell to row
-      var addCell = function (type, name) {
-	var c = this.appendChild(d.createElement(type))
-	if (name === undefined)
-	  return c;
-
-	if (name instanceof Array) {
-	  for (var n = 0; n < name.length; n++) {
-	    c.appendChild(d.createTextNode(name[n]));
-	    if (n !== name.length - 1) {
-	      c.appendChild(d.createElement('br'));
-	    };
-	  };
-	}
-	else {
-	  c.appendChild(d.createTextNode(name));
-	};
-      };
-
-      tr.addCell = addCell;
-
-      // Add header information
-      tr.addCell('th', 'Foundry');
-      tr.addCell('th', 'Layer');
-
-      // Add tokens
-      for (var i in this._token) {
-	tr.addCell('th', this.getToken(i));
-      };
-
-      var tbody = table.appendChild(
-	d.createElement('tbody')
-      );
-
-      var foundryList = Object.keys(this._foundry).sort();
-
-      for (var f = 0; f < foundryList.length; f++) {
-	var foundry = foundryList[f];
-	var layerList =
-	  Object.keys(this._foundry[foundry]).sort();
-
-	for (var l = 0; l < layerList.length; l++) {
-	  var layer = layerList[l];
-	  tr = tbody.appendChild(
-	    d.createElement('tr')
-	  );
-	  tr.setAttribute('tabindex', 0);
-	  tr.addCell = addCell;
-
-	  tr.addCell('th', foundry);
-	  tr.addCell('th', layer);
-
-	  for (var v = 0; v < this.length(); v++) {
-	    tr.addCell(
-	      'td',
-	      this.getValue(v, foundry, layer) 
-	    );
-	  };
-	};
-      };
-
-      return this._element = table;
-    }
-  };
-
-
-  /**
-   * Visualize span annotations as a tree using Dagre.
-   */
-  KorAP.MatchTree = {
-
-    create : function (snippet) {
-      return Object.create(KorAP.MatchTree)._init(snippet);
-    },
-
-    nodes : function () {
-      return this._next;
-    },
-
-    _addNode : function (id, obj) {
-      obj["width"] = 55;
-      obj["height"] = 20;
-      this._graph.setNode(id, obj)
-    },
-
-    _addEdge : function (src, target) {
-      this._graph.setEdge(src, target);
-    },
-
-    _init : function (snippet) {
-      this._next = new Number(0);
-
-      // Create html for traversal
-      var html = document.createElement("div");
-      html.innerHTML = snippet;
-      var g = new dagre.graphlib.Graph({
-	"directed" : true	
-      });
-      g.setGraph({
-	"nodesep" : 35,
-	"ranksep" : 15,
-	"marginx" : 40,
-	"marginy" : 10
-      });
-      g.setDefaultEdgeLabel({});
-
-      this._graph = g;
-
-      // This is a new root
-      this._addNode(
-	this._next++,
-	{ "class" : "root" }
-      );
-
-      // Parse nodes from root
-      this._parse(0, html.childNodes);
-
-      // Root node has only one child - remove
-      if (g.outEdges(0).length === 1)
-	g.removeNode(0);
-
-      html = undefined;
-      return this;
-    },
-
-    // Remove foundry and layer for labels
-    _clean : function (title) {
-      return title.replace(KorAP._TermRE, "$3");
-    },
-
-    // Parse the snippet
-    _parse : function (parent, children) {
-      for (var i in children) {
-	var c = children[i];
-
-	// Element node
-	if (c.nodeType == 1) {
-
-	  // Get title from html
-	  if (c.getAttribute("title")) {
-	    var title = this._clean(c.getAttribute("title"));
-
-	    // Add child node
-	    var id = this._next++;
-
-	    this._addNode(id, {
-	      "class" : "middle",
-	      "label" : title
-	    });
-	    this._addEdge(parent, id);
-
-	    // Check for next level
-	    if (c.hasChildNodes())
-	      this._parse(id, c.childNodes);
-	  }
-
-	  // Step further
-	  else if (c.hasChildNodes())
-	    this._parse(parent, c.childNodes);
-	}
-
-	// Text node
-	else if (c.nodeType == 3)
-
-	  if (c.nodeValue.match(/[-a-z0-9]/i)) {
-
-	    // Add child node
-	    var id = this._next++;
-	    this._addNode(id, {
-	      "class" : "leaf",
-	      "label" : c.nodeValue
-	    });
-
-	    this._addEdge(parent, id);
-	  };
-      };
-      return this;
-    },
-
-    /**
-     * Center the viewport of the canvas
-     */
-    center : function () {
-      if (this._element === undefined)
-	return;
-
-      var treeDiv = this._element.parentNode;
-
-      var cWidth = parseFloat(window.getComputedStyle(this._element).width);
-      var treeWidth = parseFloat(window.getComputedStyle(treeDiv).width);
-      // Reposition:
-      if (cWidth > treeWidth) {
-	var scrollValue = (cWidth - treeWidth) / 2;
-	treeDiv.scrollLeft = scrollValue;
-      };
-    },
-
-    // Get element
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      var g = this._graph;
-
-      dagre.layout(g);
-
-      var canvas = document.createElementNS(svgXmlns, 'svg');
-      this._element = canvas;
-
-      canvas.setAttribute('height', g.graph().height);
-      canvas.setAttribute('width', g.graph().width);
-
-      // Create edges
-      g.edges().forEach(
-	function (e) {
-	  var src = g.node(e.v);
-	  var target = g.node(e.w);
-	  var p = document.createElementNS(svgXmlns, 'path');
-	  p.setAttributeNS(null, "d", _line(src, target));
-	  p.classList.add('edge');
-	  canvas.appendChild(p);
-	});
-
-      // Create nodes
-      g.nodes().forEach(
-	function (v) {
-	  v = g.node(v);
-	  var group = document.createElementNS(svgXmlns, 'g');
-	  group.classList.add(v.class);
-
-	  // Add node box
-	  var rect = group.appendChild(document.createElementNS(svgXmlns, 'rect'));
-	  rect.setAttributeNS(null, 'x', v.x - v.width / 2);
-	  rect.setAttributeNS(null, 'y', v.y - v.height / 2);
-	  rect.setAttributeNS(null, 'rx', 5);
-	  rect.setAttributeNS(null, 'ry', 5);
-	  rect.setAttributeNS(null, 'width', v.width);
-	  rect.setAttributeNS(null, 'height', v.height);
-
-	  if (v.class === 'root' && v.label === undefined) {
-	    rect.setAttributeNS(null, 'width', v.height);
-	    rect.setAttributeNS(null, 'x', v.x - v.height / 2);
-	    rect.setAttributeNS(null, 'class', 'empty');
-	  };
-
-	  // Add label
-	  if (v.label !== undefined) {
-	    var text = group.appendChild(document.createElementNS(svgXmlns, 'text'));
-	    text.setAttributeNS(null, 'x', v.x - v.width / 2);
-	    text.setAttributeNS(null, 'y', v.y - v.height / 2);
-	    text.setAttributeNS(
-	      null,
-	      'transform',
-	      'translate(' + v.width/2 + ',' + ((v.height / 2) + 5) + ')'
-	    );
-
-	    var tspan = document.createElementNS(svgXmlns, 'tspan');
-	    tspan.appendChild(document.createTextNode(v.label));
-	    text.appendChild(tspan);
-	  };
-
-	  canvas.appendChild(group);
-	}
-      );
-
-      return this._element;
-    }
-  };
-
-  /**
-   * Menu item for tree view choice.
-   */
-  KorAP.MatchTreeItem = {
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)
-	.upgradeTo(KorAP.MatchTreeItem)._init(params);
-    },
-    content : function (content) {
-      if (arguments.length === 1) {
-	this._content = content;
-      };
-      return this._content;
-    },
-
-    // The foundry attribute
-    foundry : function () {
-      return this._foundry;
-    },
-
-    // The layer attribute
-    layer : function () {
-      return this._layer;
-    },
-
-    // enter or click
-    onclick : function (e) {
-      var menu = this.menu();
-      menu.hide();
-      e.halt();
-      if (menu.info() !== undefined)
-	menu.info().addTree(this._foundry, this._layer);
-    },
-    
-    _init : function (params) {
-      if (params[0] === undefined)
-	throw new Error("Missing parameters");
-
-      this._name    = params[0];
-      this._foundry = params[1];
-      this._layer   = params[2];
-      this._content = document.createTextNode(this._name);
-      this._lcField = ' ' + this.content().textContent.toLowerCase();
-      return this;
-    }
-  };
-
-
-  /**
-   * Menu to choose from for tree views.
-   */
-  KorAP.MatchTreeMenu = {
-    create : function (info, params) {
-      var obj = Object.create(KorAP.Menu)
-	.upgradeTo(KorAP.MatchTreeMenu)
-	._init(KorAP.MatchTreeItem, undefined, params);
-      obj.limit(6);
-
-      obj._info = info;
-
-      // This is only domspecific
-      obj.element().addEventListener('blur', function (e) {
-	this.menu.hide();
-      });
-
-      return obj;
-    },
-    info :function () {
-      return this._info;
-    }
-  };
-
-
-  // Create path for node connections 
-  function _line (src, target) {
-    var x1 = src.x,
-        y1 = src.y,
-        x2 = target.x,
-        y2 = target.y - target.height / 2;
-
-    // c 0,0 -10,0
-    return 'M ' + x1 + ',' + y1 + ' ' + 
-      'C ' + x1 + ',' + y1 + ' ' + 
-      x2 + ',' + (y2 - (y2 - y1) / 2)  + ' ' + 
-      x2 + ',' + y2;
-  };
-
-}(this.KorAP));
+});
diff --git a/dev/js/src/match/info.js b/dev/js/src/match/info.js
new file mode 100644
index 0000000..b24bed5
--- /dev/null
+++ b/dev/js/src/match/info.js
@@ -0,0 +1,290 @@
+  /**
+   * Information about a match.
+   */
+define(['match/infolayer','match/table','match/tree', 'match/treemenu', 'util'], function (infoLayerClass, matchTableClass, matchTreeClass, matchTreeMenuClass) {
+
+  // TODO: Make this async
+  KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
+    KorAP.log(0, 'KorAP.API.getMatchInfo() not implemented')
+    return {};
+  };
+
+  var loc = KorAP.Locale;
+
+  /**
+   * Create new object
+   */
+  return {
+    create : function (match) {
+      return Object.create(this)._init(match);
+    },
+
+    /**
+     * Initialize object
+     */
+    _init : function (match) {
+      this._match = match;
+      this.opened = false;
+      return this;
+    },
+
+    /**
+     * Get match object
+     */
+    match : function () {
+      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
+     */
+    getTable : function (tokens, cb) {
+      var focus = [];
+
+      // Get all tokens
+      if (tokens === undefined) {
+	focus = this._match.getTokens();
+      } 
+
+      // Get only some tokens
+      else {
+
+	// Push newly to focus array
+	for (var i = 0; i < tokens.length; i++) {
+	  var term = tokens[i];
+	  try {
+	    // Create info layer objects
+	    var layer = infoLayerClass.create(term);
+	    layer.type = "tokens";
+	    focus.push(layer);
+	  }
+	  catch (e) {
+	    continue;
+	  };
+	};
+      };
+      
+      // No tokens chosen
+      if (focus.length == 0)
+	cb(null);
+
+      // Get info (may be cached)
+      // TODO: Async
+      KorAP.API.getMatchInfo(
+	this._match,
+	{ 'spans' : false, 'layer' : focus },
+
+	// Callback for retrieval
+	function (matchResponse) {
+	  // Get snippet from match info
+	  if (matchResponse["snippet"] !== undefined) {
+	    this._table = matchTableClass.create(matchResponse["snippet"]);
+	    cb(this._table);
+	  };
+	}.bind(this)
+      );
+
+      /*
+      // Todo: Store the table as a hash of the focus
+      return null;
+      */
+    },
+    
+
+    /**
+     * Retrieve and parse snippet for tree representation
+     */
+    getTree : function (foundry, layer, cb) {
+      var focus = [];
+      
+      // TODO: Support and cache multiple trees
+      KorAP.API.getMatchInfo(
+	this._match, {
+	  'spans' : true,
+	  'foundry' : foundry,
+	  'layer' : layer
+	},
+	function (matchResponse) {
+	  // Get snippet from match info
+	  if (matchResponse["snippet"] !== undefined) {
+	    // Todo: This should be cached somehow
+	    cb(matchTreeClass.create(matchResponse["snippet"]));
+	  }
+	  else {
+	    cb(null);
+	  };
+	}.bind(this)
+      );
+    },
+
+    /**
+     * Destroy this match information view.
+     */
+    destroy : function () {
+
+      // Remove circular reference
+      if (this._treeMenu !== undefined)
+	delete this._treeMenu["info"];
+      
+      this._treeMenu.destroy();
+      this._treeMenu = undefined;
+      this._match = undefined;
+      
+      // Element destroy
+    },
+
+    /**
+     * Add a new tree view to the list
+     */
+    addTree : function (foundry, layer, cb) {
+      var matchtree = document.createElement('div');
+      matchtree.classList.add('matchtree');
+      
+      var h6 = matchtree.appendChild(document.createElement('h6'));
+      h6.appendChild(document.createElement('span'))
+	.appendChild(document.createTextNode(foundry));
+      h6.appendChild(document.createElement('span'))
+	.appendChild(document.createTextNode(layer));
+      
+      var tree = matchtree.appendChild(
+	document.createElement('div')
+      );
+      
+      this._element.insertBefore(matchtree, this._element.lastChild);
+
+      var close = tree.appendChild(document.createElement('em'));
+      close.addEventListener(
+	'click', function (e) {
+	  matchtree.parentNode.removeChild(matchtree);
+	  e.halt();
+	}
+      );
+
+      // Get tree data async
+      this.getTree(foundry, layer, function (treeObj) {
+	// Something went wrong - probably log!!!
+	if (treeObj === null) {
+	  tree.appendChild(document.createTextNode('No data available.'));
+	}
+	else {
+	  tree.appendChild(treeObj.element());
+	  // Reposition the view to the center
+	  // (This may in a future release be a reposition
+	  // to move the root into the center or the actual
+	  // match)
+	  treeObj.center();
+	}
+	
+	if (cb !== undefined)
+	  cb(treeObj);
+      });
+    },
+    
+    /**
+     * Create match information view.
+     */
+    element : function () {
+      
+      if (this._element !== undefined)
+	return this._element;
+      
+      // Create info table
+      var info = document.createElement('div');
+      info.classList.add('matchinfo');
+
+      // Append default table
+      var matchtable = document.createElement('div');
+      matchtable.classList.add('matchtable');
+      info.appendChild(matchtable);
+
+      // Create the table asynchronous
+      this.getTable(undefined, function (table) {
+	if (table !== null) {
+	  matchtable.appendChild(table.element());
+	};
+      });
+
+      // Get spans
+      var spanLayers = this._match.getSpans().sort(
+	function (a, b) {
+	  if (a.foundry < b.foundry) {
+	    return -1;
+	  }
+	  else if (a.foundry > b.foundry) {
+	    return 1;
+	  }
+	  else if (a.layer < b.layer) {
+	    return -1;
+	  }
+	  else if (a.layer > b.layer) {
+	    return 1;
+	  };
+	  return 0;
+	});
+      
+      var menuList = [];
+      
+      // Show tree views
+      for (var i = 0; i < spanLayers.length; i++) {
+	var span = spanLayers[i];
+	
+	// Add foundry/layer to menu list
+	menuList.push([
+	  span.foundry + '/' + span.layer,
+	  span.foundry,
+	  span.layer
+	]);
+      };
+
+      // Create tree menu
+      var treemenu = this.treeMenu(menuList);
+      var span = info.appendChild(document.createElement('p'));
+      span.classList.add('addtree');
+      span.appendChild(document.createTextNode(loc.ADDTREE));
+
+      var treeElement = treemenu.element();
+      span.appendChild(treeElement);
+
+      span.addEventListener('click', function (e) {
+	treemenu.show('');
+	treemenu.focus();
+      });
+      
+      this._element = info;
+
+      return info;
+    },
+
+    
+    /**
+     * Get tree menu.
+     * There is only one menu rendered
+     * - no matter how many trees exist
+     */
+    treeMenu : function (list) {
+      if (this._treeMenu !== undefined)
+	return this._treeMenu;
+      
+      return this._treeMenu = matchTreeMenuClass.create(this, list);
+    }
+  };
+});
diff --git a/dev/js/src/match/infolayer.js b/dev/js/src/match/infolayer.js
new file mode 100644
index 0000000..dbd93f9
--- /dev/null
+++ b/dev/js/src/match/infolayer.js
@@ -0,0 +1,41 @@
+/**
+ *
+ * Alternatively pass a string as <tt>base/s=span</tt>
+ *
+ * @param foundry
+ */
+define(function () {
+  var _AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
+
+  return {
+    create : function (foundry, layer, type) {
+      return Object.create(this)._init(foundry, layer, type);
+    },
+    _init : function (foundry, layer, type) {
+      if (foundry === undefined)
+	throw new Error("Missing parameters");
+      
+      if (layer === undefined) {
+	if (_AvailableRE.exec(foundry)) {
+	  this.foundry = RegExp.$1;
+	  this.layer = RegExp.$2;
+	  this.type = RegExp.$3;
+	}
+	else {
+	  throw new Error("Missing parameters");
+	};
+      }
+      else {
+	this.foundry = foundry;
+	this.layer = layer;
+	this.type = type;
+      };
+      
+      if (this.type === undefined)
+	this.type = 'tokens';
+
+      return this;
+    }
+  };
+});
+
diff --git a/dev/js/src/match/table.js b/dev/js/src/match/table.js
new file mode 100644
index 0000000..7eba8a0
--- /dev/null
+++ b/dev/js/src/match/table.js
@@ -0,0 +1,193 @@
+define(function () {
+  var _TermRE = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
+  
+  return {
+    create : function (snippet) {
+      return Object.create(this)._init(snippet);
+    },
+    _init : function (snippet) {
+      // Create html for traversal
+      var html = document.createElement("div");
+      html.innerHTML = snippet;
+      
+      this._pos = 0;
+      this._token = [];
+      this._info = [];
+      this._foundry = {};
+      this._layer = {};
+    
+      // Parse the snippet
+      this._parse(html.childNodes);      
+    
+      html.innerHTML = '';
+      return this;
+    },
+    
+    length : function () {
+      return this._pos;
+    },
+
+    getToken : function (pos) {
+      if (pos === undefined)
+	return this._token;
+      return this._token[pos];
+    },
+    
+    getValue : function (pos, foundry, layer) {
+      return this._info[pos][foundry + '/' + layer]
+    },
+    
+    getLayerPerFoundry : function (foundry) {
+      return this._foundry[foundry]
+    },
+    
+    getFoundryPerLayer : function (layer) {
+      return this._layer[layer];
+    },
+
+    // Parse the snippet
+    _parse : function (children) {
+
+      // Get all children
+      for (var i in children) {
+	var c = children[i];
+
+	// Create object on position unless it exists
+	if (this._info[this._pos] === undefined)
+	  this._info[this._pos] = {};
+
+	// Store at position in foundry/layer as array
+	var found = this._info[this._pos];
+
+	// Element with title
+	if (c.nodeType === 1) {
+	  if (c.getAttribute("title") &&
+	      _TermRE.exec(c.getAttribute("title"))) {
+
+	    // Fill position with info
+	    var foundry, layer, value;
+	    if (RegExp.$2) {
+	      foundry = RegExp.$1;
+	      layer   = RegExp.$2;
+	    }
+	    else {
+	      foundry = "base";
+	      layer   = RegExp.$1
+	    };
+
+	    value = RegExp.$3;
+	    
+	    if (found[foundry + "/" + layer] === undefined)
+	      found[foundry + "/" + layer] = [];
+
+	    // Push value to foundry/layer at correct position
+	    found[foundry + "/" + layer].push(RegExp.$3);
+
+	    // Set foundry
+	    if (this._foundry[foundry] === undefined)
+	      this._foundry[foundry] = {};
+	    this._foundry[foundry][layer] = 1;
+
+	    // Set layer
+	    if (this._layer[layer] === undefined)
+	      this._layer[layer] = {};
+	    this._layer[layer][foundry] = 1;
+	  };
+
+	  // depth search
+	  if (c.hasChildNodes())
+	    this._parse(c.childNodes);
+	}
+
+	// Leaf node
+	// store string on position and go to next string
+	else if (c.nodeType === 3) {
+	  if (c.nodeValue.match(/[a-z0-9]/i))
+	    this._token[this._pos++] = c.nodeValue;
+	};
+      };
+
+      delete this._info[this._pos];
+    },
+
+
+    /**
+     * Get HTML table view of annotations.
+     */
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      // First the legend table
+      var d = document;
+      var table = d.createElement('table');
+
+      // Single row in head
+      var tr = table.appendChild(d.createElement('thead'))
+	.appendChild(d.createElement('tr'));
+
+      // Add cell to row
+      var addCell = function (type, name) {
+	var c = this.appendChild(d.createElement(type))
+	if (name === undefined)
+	  return c;
+
+	if (name instanceof Array) {
+	  for (var n = 0; n < name.length; n++) {
+	    c.appendChild(d.createTextNode(name[n]));
+	    if (n !== name.length - 1) {
+	      c.appendChild(d.createElement('br'));
+	    };
+	  };
+	}
+	else {
+	  c.appendChild(d.createTextNode(name));
+	};
+      };
+
+      tr.addCell = addCell;
+
+      // Add header information
+      tr.addCell('th', 'Foundry');
+      tr.addCell('th', 'Layer');
+
+      // Add tokens
+      for (var i in this._token) {
+	tr.addCell('th', this.getToken(i));
+      };
+
+      var tbody = table.appendChild(
+	d.createElement('tbody')
+      );
+
+      var foundryList = Object.keys(this._foundry).sort();
+
+      for (var f = 0; f < foundryList.length; f++) {
+	var foundry = foundryList[f];
+	var layerList =
+	  Object.keys(this._foundry[foundry]).sort();
+
+	for (var l = 0; l < layerList.length; l++) {
+	  var layer = layerList[l];
+	  tr = tbody.appendChild(
+	    d.createElement('tr')
+	  );
+	  tr.setAttribute('tabindex', 0);
+	  tr.addCell = addCell;
+
+	  tr.addCell('th', foundry);
+	  tr.addCell('th', layer);
+
+	  for (var v = 0; v < this.length(); v++) {
+	    tr.addCell(
+	      'td',
+	      this.getValue(v, foundry, layer) 
+	    );
+	  };
+	};
+      };
+
+      return this._element = table;
+    }
+  };
+});
diff --git a/dev/js/src/match/tree.js b/dev/js/src/match/tree.js
new file mode 100644
index 0000000..b379b37
--- /dev/null
+++ b/dev/js/src/match/tree.js
@@ -0,0 +1,222 @@
+/**
+ * Visualize span annotations as a tree using Dagre.
+ */
+define(['lib/dagre'], function (dagre) {
+  "use strict";
+
+  var svgXmlns = "http://www.w3.org/2000/svg";
+  var _TermRE = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
+
+  // Create path for node connections 
+  function _line (src, target) {
+    var x1 = src.x,
+        y1 = src.y,
+        x2 = target.x,
+        y2 = target.y - target.height / 2;
+
+    // c 0,0 -10,0
+    return 'M ' + x1 + ',' + y1 + ' ' + 
+      'C ' + x1 + ',' + y1 + ' ' + 
+      x2 + ',' + (y2 - (y2 - y1) / 2)  + ' ' + 
+      x2 + ',' + y2;
+  };
+
+  return {
+    create : function (snippet) {
+      return Object.create(this)._init(snippet);
+    },
+
+    nodes : function () {
+      return this._next;
+    },
+
+    _addNode : function (id, obj) {
+      obj["width"] = 55;
+      obj["height"] = 20;
+      this._graph.setNode(id, obj)
+    },
+    
+    _addEdge : function (src, target) {
+      this._graph.setEdge(src, target);
+    },
+    
+    _init : function (snippet) {
+      this._next = new Number(0);
+
+      // Create html for traversal
+      var html = document.createElement("div");
+      html.innerHTML = snippet;
+      var g = new dagre.graphlib.Graph({
+	"directed" : true	
+      });
+      g.setGraph({
+	"nodesep" : 35,
+	"ranksep" : 15,
+	"marginx" : 40,
+	"marginy" : 10
+      });
+      g.setDefaultEdgeLabel({});
+
+      this._graph = g;
+      
+      // This is a new root
+      this._addNode(
+	this._next++,
+	{ "class" : "root" }
+      );
+      
+      // Parse nodes from root
+      this._parse(0, html.childNodes);
+
+      // Root node has only one child - remove
+      if (g.outEdges(0).length === 1)
+	g.removeNode(0);
+
+      html = undefined;
+      return this;
+    },
+
+    // Remove foundry and layer for labels
+    _clean : function (title) {
+      return title.replace(_TermRE, "$3");
+    },
+
+    // Parse the snippet
+    _parse : function (parent, children) {
+      for (var i in children) {
+	var c = children[i];
+
+	// Element node
+	if (c.nodeType == 1) {
+
+	  // Get title from html
+	  if (c.getAttribute("title")) {
+	    var title = this._clean(c.getAttribute("title"));
+
+	    // Add child node
+	    var id = this._next++;
+
+	    this._addNode(id, {
+	      "class" : "middle",
+	      "label" : title
+	    });
+	    this._addEdge(parent, id);
+
+	    // Check for next level
+	    if (c.hasChildNodes())
+	      this._parse(id, c.childNodes);
+	  }
+
+	  // Step further
+	  else if (c.hasChildNodes())
+	    this._parse(parent, c.childNodes);
+	}
+
+	// Text node
+	else if (c.nodeType == 3)
+
+	  if (c.nodeValue.match(/[-a-z0-9]/i)) {
+
+	    // Add child node
+	    var id = this._next++;
+	    this._addNode(id, {
+	      "class" : "leaf",
+	      "label" : c.nodeValue
+	    });
+
+	    this._addEdge(parent, id);
+	  };
+      };
+      return this;
+    },
+
+    /**
+     * Center the viewport of the canvas
+     */
+    center : function () {
+      if (this._element === undefined)
+	return;
+
+      var treeDiv = this._element.parentNode;
+
+      var cWidth = parseFloat(window.getComputedStyle(this._element).width);
+      var treeWidth = parseFloat(window.getComputedStyle(treeDiv).width);
+      // Reposition:
+      if (cWidth > treeWidth) {
+	var scrollValue = (cWidth - treeWidth) / 2;
+	treeDiv.scrollLeft = scrollValue;
+      };
+    },
+
+    // Get element
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      var g = this._graph;
+
+      dagre.layout(g);
+
+      var canvas = document.createElementNS(svgXmlns, 'svg');
+      this._element = canvas;
+
+      canvas.setAttribute('height', g.graph().height);
+      canvas.setAttribute('width', g.graph().width);
+
+      // Create edges
+      g.edges().forEach(
+	function (e) {
+	  var src = g.node(e.v);
+	  var target = g.node(e.w);
+	  var p = document.createElementNS(svgXmlns, 'path');
+	  p.setAttributeNS(null, "d", _line(src, target));
+	  p.classList.add('edge');
+	  canvas.appendChild(p);
+	});
+
+      // Create nodes
+      g.nodes().forEach(
+	function (v) {
+	  v = g.node(v);
+	  var group = document.createElementNS(svgXmlns, 'g');
+	  group.classList.add(v.class);
+
+	  // Add node box
+	  var rect = group.appendChild(document.createElementNS(svgXmlns, 'rect'));
+	  rect.setAttributeNS(null, 'x', v.x - v.width / 2);
+	  rect.setAttributeNS(null, 'y', v.y - v.height / 2);
+	  rect.setAttributeNS(null, 'rx', 5);
+	  rect.setAttributeNS(null, 'ry', 5);
+	  rect.setAttributeNS(null, 'width', v.width);
+	  rect.setAttributeNS(null, 'height', v.height);
+
+	  if (v.class === 'root' && v.label === undefined) {
+	    rect.setAttributeNS(null, 'width', v.height);
+	    rect.setAttributeNS(null, 'x', v.x - v.height / 2);
+	    rect.setAttributeNS(null, 'class', 'empty');
+	  };
+
+	  // Add label
+	  if (v.label !== undefined) {
+	    var text = group.appendChild(document.createElementNS(svgXmlns, 'text'));
+	    text.setAttributeNS(null, 'x', v.x - v.width / 2);
+	    text.setAttributeNS(null, 'y', v.y - v.height / 2);
+	    text.setAttributeNS(
+	      null,
+	      'transform',
+	      'translate(' + v.width/2 + ',' + ((v.height / 2) + 5) + ')'
+	    );
+
+	    var tspan = document.createElementNS(svgXmlns, 'tspan');
+	    tspan.appendChild(document.createTextNode(v.label));
+	    text.appendChild(tspan);
+	  };
+
+	  canvas.appendChild(group);
+	}
+      );
+
+      return this._element;
+    }
+  };
+});
diff --git a/dev/js/src/match/treeitem.js b/dev/js/src/match/treeitem.js
new file mode 100644
index 0000000..f096861
--- /dev/null
+++ b/dev/js/src/match/treeitem.js
@@ -0,0 +1,49 @@
+define(['menu/item'], function (itemClass) {
+  /**
+   * Menu item for tree view choice.
+   */
+
+  return {
+    create : function (params) {
+      return Object.create(itemClass)
+	.upgradeTo(this)._init(params);
+    },
+    content : function (content) {
+      if (arguments.length === 1) {
+	this._content = content;
+      };
+      return this._content;
+    },
+    
+    // The foundry attribute
+    foundry : function () {
+      return this._foundry;
+    },
+
+    // The layer attribute
+    layer : function () {
+      return this._layer;
+    },
+
+    // enter or click
+    onclick : function (e) {
+      var menu = this.menu();
+      menu.hide();
+      e.halt();
+      if (menu.info() !== undefined)
+	menu.info().addTree(this._foundry, this._layer);
+    },
+    
+    _init : function (params) {
+      if (params[0] === undefined)
+	throw new Error("Missing parameters");
+
+      this._name    = params[0];
+      this._foundry = params[1];
+      this._layer   = params[2];
+      this._content = document.createTextNode(this._name);
+      this._lcField = ' ' + this.content().textContent.toLowerCase();
+      return this;
+    }
+  };
+});
diff --git a/dev/js/src/match/treemenu.js b/dev/js/src/match/treemenu.js
new file mode 100644
index 0000000..23341a4
--- /dev/null
+++ b/dev/js/src/match/treemenu.js
@@ -0,0 +1,26 @@
+  /**
+   * Menu to choose from for tree views.
+   */
+define(['menu', 'match/treeitem'], function (menuClass, itemClass) {
+  "use strict";
+
+  return {
+    create : function (info, params) {
+      var obj = Object.create(menuClass)
+	.upgradeTo(this)
+	._init(itemClass, undefined, params);
+      obj.limit(6);
+      obj._info = info;
+
+      // This is only domspecific
+      obj.element().addEventListener('blur', function (e) {
+	this.menu.hide();
+      });
+      
+      return obj;
+    },
+    info :function () {
+      return this._info;
+    }
+  };
+});
diff --git a/dev/js/src/menu.js b/dev/js/src/menu.js
index 78f9ea7..0d5e6ac 100644
--- a/dev/js/src/menu.js
+++ b/dev/js/src/menu.js
@@ -1,35 +1,35 @@
-var KorAP = KorAP || {};
-
 /**
  * Create scrollable drop-down menus.
  *
  * @author Nils Diewald
  */
-
 /*
-  * TODO: space is not a valid prefix!
+ * TODO: space is not a valid prefix!
  */
-(function (KorAP) {
-  "use strict";
+define([
+  'menu/item',
+  'menu/prefix',
+  'util'
+], function (defaultItemClass,
+	     defaultPrefixClass) {
 
-  // Don't let events bubble up
-  if (Event.halt === undefined) {
-    // Don't let events bubble up
-    Event.prototype.halt = function () {
-      this.stopPropagation();
-      this.preventDefault();
-    };
+  // Todo: This may not be necessary
+  // Default maximum number of menu items
+  var menuLimit = 8;
+
+  function _codeFromEvent (e) {
+    if (e.charCode && (e.keyCode == 0))
+      return e.charCode
+    return e.keyCode;
   };
 
-  // Default maximum number of menu items
-  KorAP.menuLimit = 8;
 
   /**
    * 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).
    */
-  KorAP.Menu = {
+  return {
     /**
      * Create new Menu based on the action prefix
      * and a list of menu items.
@@ -40,7 +40,7 @@
      * @param {Array.<Array.<string>>} List of menu items
      */
     create : function (params) {
-      return Object.create(KorAP.Menu)._init(params);
+      return Object.create(this)._init(params);
     },
 
     /**
@@ -143,12 +143,12 @@
     // Initialize list
     _init : function (itemClass, prefixClass, params) {
       var that = this;
-      this._itemClass = itemClass;
+      this._itemClass = itemClass || defaultItemClass;
 
       if (prefixClass !== undefined)
 	this._prefix = prefixClass.create();
       else
-	this._prefix = KorAP.MenuPrefix.create();
+	this._prefix = defaultPrefixClass.create();
 
       this._prefix._menu = this;
 
@@ -188,14 +188,14 @@
 
       // Initialize item list based on parameters
       for (i in params) {
-	var obj = itemClass.create(params[i]);
+	var obj = this._itemClass.create(params[i]);
 
 	// This may become circular
 	obj["_menu"] = this;
 
 	this._items.push(obj);
       };
-      this._limit    = KorAP.menuLimit;
+      this._limit    = menuLimit;
       this._position = 0;  // position in the active list
       this._active   = -1; // active item in the item list
       this._reset();
@@ -654,318 +654,4 @@
       this._element.removeChild(this._element.lastChild);
     }
   };
-
-
-  /**
-   * 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);
-    },
-
-    /**
-     * Upgrade this object to another object,
-     * while private data stays intact.
-     *
-     * @param {Object] An object with properties.
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    content : function (content) {
-      if (arguments.length === 1)
-	this._content = document.createTextNode(content);
-      return this._content;
-    },
-
-    lcField : function () {
-      return this._lcField;
-    },
-
-    action : function (action) {
-      if (arguments.length === 1)
-	this._action = action;
-      return this._action;
-    },
-
-    /**
-     * 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
-     */
-    element : function () {
-      // already defined
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create list item
-      var li = document.createElement("li");
-
-      // Connect action
-      if (this["onclick"] !== undefined) {
-	li["onclick"] = this.onclick.bind(this);
-      };
-
-      // Append template
-      li.appendChild(this.content());
-
-      return this._element = li;
-    },
-
-    /**
-     * Highlight parts of the item
-     *
-     * @param {string} Prefix string for highlights
-     */
-    highlight : function (prefix) {
-      var children = this.element().childNodes;
-      for (var i = children.length -1; i >= 0; i--) {
-	this._highlight(children[i], prefix);
-      };
-    },
-
-    // Highlight a certain substring of the menu item
-    _highlight : function (elem, prefix) {
-
-      if (elem.nodeType === 3) {
-
-	var text   = elem.nodeValue;
-	var textlc = text.toLowerCase();
-	var pos    = textlc.indexOf(prefix);
-	if (pos >= 0) {
-
-	  // First element
-	  if (pos > 0) {
-	    elem.parentNode.insertBefore(
-	      document.createTextNode(text.substr(0, pos)),
-	      elem
-	    );
-	  };
-
-	  // Second element
-	  var hl = document.createElement("mark");
-	  hl.appendChild(
-	    document.createTextNode(text.substr(pos, prefix.length))
-	  );
-	  elem.parentNode.insertBefore(hl, elem);
-
-	  // Third element
-	  var third = text.substr(pos + prefix.length);
-	  if (third.length > 0) {
-	    var thirdE = document.createTextNode(third);
-	    elem.parentNode.insertBefore(
-	      thirdE,
-	      elem
-	    );
-	    this._highlight(thirdE, prefix);
-	  };
-
-	  var p = elem.parentNode;
-	  p.removeChild(elem);
-	};
-      }
-      else {
-	var children = elem.childNodes;
-	for (var i = children.length -1; i >= 0; i--) {
-	  this._highlight(children[i], prefix);
-	};
-      };
-    },
-
-
-    /**
-     * Remove highlight of the menu item
-     */
-    lowlight : function () {
-      var e = this.element();
-
-      var marks = e.getElementsByTagName("mark");
-      for (var i = marks.length - 1; i >= 0; i--) {
-	// Create text node clone
-	var x = document.createTextNode(
-	  marks[i].firstChild.nodeValue
-	);
-
-	// Replace with content
-	marks[i].parentNode.replaceChild(
-	  x,
-	  marks[i]
-	);
-      };
-
-      // Remove consecutive textnodes
-      e.normalize();
-    },
-
-    // Initialize menu item
-    _init : function (params) {
-
-      if (params[0] === undefined)
-	throw new Error("Missing parameters");
-
-      this.content(params[0]);
-
-      if (params.length === 2)
-	this._action = params[1];
-
-      this._lcField = ' ' + this.content().textContent.toLowerCase();
-
-      return this;
-    },
-
-    /**
-     * Return menu list.
-     */
-    menu : function () {
-      return this._menu;
-    }
-  };
-
-  KorAP.MenuPrefix = {
-    create : function (params) {
-      return Object.create(KorAP.MenuPrefix)._init();
-    },
-    _init : function () {
-      this._string = '';
-
-      // Add prefix span
-      this._element = document.createElement('span');
-      this._element.classList.add('pref');
-      // Connect action
-
-      if (this["onclick"] !== undefined)
-	this._element["onclick"] = this.onclick.bind(this);
-
-      return this;
-    },
-    _update : function () {
-      this._element.innerHTML
-      = this._string;
-    },
-
-    /**
-     * Upgrade this object to another object,
-     * while private data stays intact.
-     *
-     * @param {Object} An object with properties.
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    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");
-    },
-
-    element : function () {
-      return this._element;
-    },
-
-    isSet : function () {
-      return this._string.length > 0 ?
-	true : false;
-    },
-
-    value : function (string) {
-      if (arguments.length === 1) {
-	this._string = string;
-	this._update();
-      };
-      return this._string;
-    },
-
-    add : function (string) {
-      this._string += string;
-      this._update();
-    },
-
-    onclick : function () {},
-
-    backspace : function () {
-      if (this._string.length > 1) {
-	this._string = this._string.substring(
-	  0, this._string.length - 1
-	);
-      }
-      else {
-	this._string = '';
-      };
-
-      this._update();
-    },
-
-    /**
-     * Return menu list.
-     */
-    menu : function () {
-      return this._menu;
-    }
-  };
-
-  function _codeFromEvent (e) {
-    if (e.charCode && (e.keyCode == 0))
-      return e.charCode
-    return e.keyCode;
-  };
-
-}(this.KorAP));
-
-/**
- * MenuItems may define:
- *
- * onclick: action happen on click and enter.
- * further: action happen on right arrow
- */
+});
diff --git a/dev/js/src/menu/item.js b/dev/js/src/menu/item.js
new file mode 100644
index 0000000..b80aa2a
--- /dev/null
+++ b/dev/js/src/menu/item.js
@@ -0,0 +1,213 @@
+/*
+ * MenuItems may define:
+ *
+ * onclick: action happen on click and enter.
+ * further: action happen on right arrow
+ */
+
+/**
+ * Item in the Dropdown menu
+ */
+define({
+  /**
+   * 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(this)._init(params);
+  },
+
+  /**
+   * Upgrade this object to another object,
+   * while private data stays intact.
+   *
+   * @param {Object] An object with properties.
+   */
+  upgradeTo : function (props) {
+    for (var prop in props) {
+      this[prop] = props[prop];
+    };
+    return this;
+  },
+
+  content : function (content) {
+    if (arguments.length === 1)
+      this._content = document.createTextNode(content);
+    return this._content;
+  },
+
+  lcField : function () {
+    return this._lcField;
+  },
+
+  action : function (action) {
+    if (arguments.length === 1)
+      this._action = action;
+    return this._action;
+  },
+
+  /**
+   * 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
+   */
+  element : function () {
+    // already defined
+    if (this._element !== undefined)
+      return this._element;
+    
+    // Create list item
+    var li = document.createElement("li");
+
+    // Connect action
+    if (this["onclick"] !== undefined) {
+      li["onclick"] = this.onclick.bind(this);
+    };
+
+    // Append template
+    li.appendChild(this.content());
+    
+    return this._element = li;
+  },
+
+  /**
+   * Highlight parts of the item
+   *
+   * @param {string} Prefix string for highlights
+   */
+  highlight : function (prefix) {
+    var children = this.element().childNodes;
+    for (var i = children.length -1; i >= 0; i--) {
+      this._highlight(children[i], prefix);
+    };
+  },
+
+  // Highlight a certain substring of the menu item
+  _highlight : function (elem, prefix) {
+    
+    if (elem.nodeType === 3) {
+      
+      var text   = elem.nodeValue;
+      var textlc = text.toLowerCase();
+      var pos    = textlc.indexOf(prefix);
+      if (pos >= 0) {
+	
+	// First element
+	if (pos > 0) {
+	  elem.parentNode.insertBefore(
+	    document.createTextNode(text.substr(0, pos)),
+	    elem
+	  );
+	};
+	
+	// Second element
+	var hl = document.createElement("mark");
+	hl.appendChild(
+	  document.createTextNode(text.substr(pos, prefix.length))
+	);
+	elem.parentNode.insertBefore(hl, elem);
+	
+	// Third element
+	var third = text.substr(pos + prefix.length);
+	if (third.length > 0) {
+	  var thirdE = document.createTextNode(third);
+	  elem.parentNode.insertBefore(
+	    thirdE,
+	    elem
+	  );
+	  this._highlight(thirdE, prefix);
+	};
+	
+	var p = elem.parentNode;
+	p.removeChild(elem);
+      };
+    }
+    else {
+      var children = elem.childNodes;
+      for (var i = children.length -1; i >= 0; i--) {
+	this._highlight(children[i], prefix);
+      };
+    };
+  },
+
+  /**
+   * Remove highlight of the menu item
+   */
+  lowlight : function () {
+    var e = this.element();
+    
+    var marks = e.getElementsByTagName("mark");
+    for (var i = marks.length - 1; i >= 0; i--) {
+      // Create text node clone
+      var x = document.createTextNode(
+	marks[i].firstChild.nodeValue
+      );
+      
+      // Replace with content
+      marks[i].parentNode.replaceChild(
+	x,
+	marks[i]
+      );
+    };
+
+    // Remove consecutive textnodes
+    e.normalize();
+  },
+
+  // Initialize menu item
+  _init : function (params) {
+    
+    if (params[0] === undefined)
+      throw new Error("Missing parameters");
+
+    this.content(params[0]);
+    
+    if (params.length === 2)
+      this._action = params[1];
+
+    this._lcField = ' ' + this.content().textContent.toLowerCase();
+
+    return this;
+  },
+
+  /**
+   * Return menu list.
+   */
+  menu : function () {
+    return this._menu;
+  }
+});
diff --git a/dev/js/src/menu/prefix.js b/dev/js/src/menu/prefix.js
new file mode 100644
index 0000000..a4e428f
--- /dev/null
+++ b/dev/js/src/menu/prefix.js
@@ -0,0 +1,89 @@
+define({
+  create : function (params) {
+    return Object.create(this)._init();
+  },
+  _init : function () {
+    this._string = '';
+
+    // Add prefix span
+    this._element = document.createElement('span');
+    this._element.classList.add('pref');
+    // Connect action
+
+    if (this["onclick"] !== undefined)
+      this._element["onclick"] = this.onclick.bind(this);
+    
+    return this;
+  },
+  _update : function () {
+    this._element.innerHTML
+      = this._string;
+  },
+
+  /**
+   * Upgrade this object to another object,
+   * while private data stays intact.
+   *
+   * @param {Object} An object with properties.
+   */
+  upgradeTo : function (props) {
+    for (var prop in props) {
+      this[prop] = props[prop];
+    };
+    return this;
+  },
+
+  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");
+  },
+
+  element : function () {
+    return this._element;
+  },
+
+  isSet : function () {
+    return this._string.length > 0 ?
+      true : false;
+  },
+
+  value : function (string) {
+    if (arguments.length === 1) {
+      this._string = string;
+      this._update();
+    };
+    return this._string;
+  },
+  
+  add : function (string) {
+    this._string += string;
+    this._update();
+  },
+
+  onclick : function () {},
+
+  backspace : function () {
+    if (this._string.length > 1) {
+      this._string = this._string.substring(
+	0, this._string.length - 1
+      );
+    }
+    else {
+      this._string = '';
+    };
+    
+    this._update();
+  },
+
+  /**
+   * Return menu list.
+   */
+  menu : function () {
+    return this._menu;
+  }
+});
diff --git a/dev/js/src/session.js b/dev/js/src/session.js
index a10ce81..f81eb8f 100644
--- a/dev/js/src/session.js
+++ b/dev/js/src/session.js
@@ -4,77 +4,68 @@
  *
  * @author Nils Diewald
  */
-var KorAP = KorAP || {};
+define({
+  /**
+   * Create a new session.
+   * Expects a name or defaults to 'korap'
+   */
+  create : function (name) {
+    var obj = Object.create(this);
+    if (name === undefined)
+      name = 'korap';
+    obj._name = name.toLowerCase();
+    obj._hash = {};
+    obj._parse();
+    return obj;
+  },
 
-(function (KorAP) {
-  "use strict";
+  /**
+   * Get a value based on a key.
+   * The value can be complex, as the value is stored as JSON.
+   */
+  get : function (key) {
+    return this._hash[key.toLowerCase()];
+  },
 
-  
-  KorAP.Session = {
+  /**
+   * Set a value based on a key.
+   * The value can be complex, as the value is stored as JSON.
+   */
+  set : function (key, value) {
+    this._hash[key] = value;
+    this._store();
+  },
 
-    /**
-     * Create a new session.
-     * Expects a name or defaults to 'korap'
-     */
-    create : function (name) {
-      var obj = Object.create(KorAP.Session);
-      if (name === undefined)
-	name = 'korap';
-      obj._name = name.toLowerCase();
-      obj._hash = {};
-      obj._parse();
-      return obj;
-    },
+  /**
+   * Clears the session by removing the cookie
+   */
+  clear : function () {
+    document.cookie = this._name + '=; expires=-1';
+  },
 
-    /**
-     * Get a value based on a key.
-     * The value can be complex, as the value is stored as JSON.
-     */
-    get : function (key) {
-      return this._hash[key.toLowerCase()];
-    },
+  /* Store cookie */
+  _store : function () {
+    /*
+      var date = new Date();
+      date.setYear(date.getFullYear() + 1);
+    */
+    document.cookie =
+      this._name + '=' + encodeURIComponent(JSON.stringify(this._hash)) + ';';
+  },
 
-    /**
-     * Set a value based on a key.
-     * The value can be complex, as the value is stored as JSON.
-     */
-    set : function (key, value) {
-      this._hash[key] = value;
-      this._store();
-    },
-
-    /**
-     * Clears the session by removing the cookie
-     */
-    clear : function () {
-      document.cookie = this._name + '=; expires=-1';
-    },
-
-    /* Store cookie */
-    _store : function () {
-      /*
-	var date = new Date();
-	date.setYear(date.getFullYear() + 1);
-      */
-      document.cookie =
-	this._name + '=' + encodeURIComponent(JSON.stringify(this._hash)) + ';';
-    },
-
-    /* Parse cookie */
-    _parse : function () {
-      var c = document.cookie;
-      var part = document.cookie.split(';');
-      for(var i = 0; i < part.length; i++) {
-        var pair = part[i].split('=');
-        var name = pair[0].trim().toLowerCase();
-	if (name === this._name) {
-	  if (pair.length === 1 || pair[1].length === 0)
-	    return;
-          this._hash = JSON.parse(decodeURIComponent(pair[1]));
+  /* Parse cookie */
+  _parse : function () {
+    var c = document.cookie;
+    var part = document.cookie.split(';');
+    for(var i = 0; i < part.length; i++) {
+      var pair = part[i].split('=');
+      var name = pair[0].trim().toLowerCase();
+      if (name === this._name) {
+	if (pair.length === 1 || pair[1].length === 0)
 	  return;
-	};
+        this._hash = JSON.parse(decodeURIComponent(pair[1]));
+	return;
       };
-    }
+    };
   }
-
-}(this.KorAP));
+});
diff --git a/dev/js/src/tutorial.js b/dev/js/src/tutorial.js
index 03cf903..dae5fbf 100644
--- a/dev/js/src/tutorial.js
+++ b/dev/js/src/tutorial.js
@@ -2,31 +2,30 @@
  * Open and close a tutorial page.
  * The current page is stored and retrieved in a session cookie.
  */
-// Requires session.js
-var KorAP = KorAP || {};
-
 // Todo: add query mechanism!
 
-(function (KorAP) {
+define(['session', 'util'], function (sessionClass) {
   "use strict";
 
   // Localization values
-  var loc   = (KorAP.Locale = KorAP.Locale || {} );
+  var loc   = KorAP.Locale;
   loc.CLOSE = loc.CLOSE || 'Close';
 
-  KorAP.Tutorial = {
-
+  return {
     /**
      * Create new tutorial object.
      * Accepts an element to bind the tutorial window to.
      */
     create : function (obj) {
-      return Object.create(KorAP.Tutorial)._init(obj);
+      if (!obj)
+	return null;
+      return Object.create(this)._init(obj);
     },
 
     // Initialize Tutorial object
     _init : function (obj) {
-      this._session = KorAP.Session.create();
+
+      this._session = sessionClass.create();
       this._show = obj;
       this.start = obj.getAttribute('href');
       obj.removeAttribute('href');
@@ -58,9 +57,6 @@
 	var ul = document.createElement('ul');
 	ul.classList.add('action', 'right');
 
-	// Use localization
-	var loc = KorAP.Locale;
-
 	// Add close button
 	var close = document.createElement('li');
 	close.appendChild(document.createElement('span'))
@@ -80,7 +76,7 @@
 	  info.classList.add('info');
 	  info.setAttribute('title', loc.SHOWINFO);
 	*/
-
+	
 	ul.appendChild(close);
 
 	element.appendChild(ul);
@@ -129,5 +125,5 @@
     getPage : function () {
       this._session.get('tutpage');
     },
-  }
-}(this.KorAP));
+  };
+});
diff --git a/dev/js/src/util.js b/dev/js/src/util.js
new file mode 100644
index 0000000..d183c36
--- /dev/null
+++ b/dev/js/src/util.js
@@ -0,0 +1,45 @@
+var KorAP = KorAP || {};
+
+// TODO: Make this part of util!
+// Don't let events bubble up
+if (Event.halt === undefined) {
+  // Don't let events bubble up
+  Event.prototype.halt = function () {
+    this.stopPropagation();
+    this.preventDefault();
+  };
+};
+
+// Add toggleClass method similar to jquery
+HTMLElement.prototype.toggleClass = function (c1, c2) {
+  var cl = this.classList;
+  if (cl.contains(c1)) {
+    cl.add(c2);
+    cl.remove(c1);
+  }
+  else {
+    cl.remove(c2);
+    cl.add(c1);
+  };
+};
+
+
+// Utility for removing all children of a node
+function _removeChildren (node) {
+  // Remove everything underneath
+  while (node.firstChild)
+    node.removeChild(node.firstChild);
+};
+
+
+define(function () {
+  KorAP.API = KorAP.API || {};
+  KorAP.Locale = KorAP.Locale || {};
+
+  // Default log message
+  KorAP.log = KorAP.log || function (type, msg) {
+    console.log(type + ": " + msg);
+  };
+
+  return KorAP;
+});
diff --git a/dev/js/src/vc.js b/dev/js/src/vc.js
index 2c8ad01..48c5694 100644
--- a/dev/js/src/vc.js
+++ b/dev/js/src/vc.js
@@ -6,9 +6,6 @@
 /*
  * Replaces a previous version written by Mengfei Zhou
  */
-var KorAP = KorAP || {};
-
-// Requires menu.js
 
 /*
   TODO: Implement a working localization solution!
@@ -33,131 +30,60 @@
   815: "Rewrite expects source"
 */
 
-(function (KorAP) {
+define([
+  'vc/unspecified',
+  'vc/doc',
+  'vc/docgroup',
+  'util'
+], function (unspecDocClass, docClass, docGroupClass) {
   "use strict";
 
-  // Default log message
-  KorAP.log = KorAP.log || function (type, msg) {
-    console.log(type + ": " + msg);
-  };
-
   KorAP._validStringMatchRE = new RegExp("^(?:eq|ne|contains|excludes)$");
-  KorAP._validRegexMatchRE  = new RegExp("^(?:eq|ne)$");
+  // KorAP._validRegexMatchRE  = new RegExp("^(?:eq|ne)$");
   KorAP._validDateMatchRE   = new RegExp("^[lg]?eq$");
   KorAP._validDateRE        = new RegExp("^(?:\\d{4})(?:-\\d\\d(?:-\\d\\d)?)?$");
-  KorAP._validGroupOpRE     = new RegExp("^(?:and|or)$");
-  KorAP._validRewriteOpRE   = new RegExp("^(?:injec|modifica)tion$");
-  KorAP._quote              = new RegExp("([\"\\\\])", 'g');
+  // KorAP._validGroupOpRE     = new RegExp("^(?:and|or)$");
+  // KorAP._quote              = new RegExp("([\"\\\\])", 'g');
 
   // Localization values
   var loc   = (KorAP.Locale = KorAP.Locale || {} );
-  loc.AND   = loc.AND   || 'and';
-  loc.OR    = loc.OR    || 'or';
-  loc.DEL   = loc.DEL   || '×';
-  loc.EMPTY = loc.EMPTY || '⋯'
-
-  // Utility for analysing boolean values
-  function _bool (bool) {
-    return (bool === undefined || bool === null || bool === false) ? false : true;
-  };
-
-
-  // Utility for removing all children of a node
-  function _removeChildren (node) {
-    // Remove everything underneath
-    while (node.firstChild)
-      node.removeChild(node.firstChild);
-  };
-
-
-  // Add new unspecified document
-  KorAP._add = function (obj, type) {
-    var ref = obj.parentNode.refTo;
-    var parent = ref.parent();
-
-    if (ref.ldType() === 'docGroup') {
-
-      // Check that the action differs from the type
-      if (ref.operation() === type)
-	return;
-
-      if (parent.ldType() !== null) {
-	return parent.newAfter(ref);
-      }
-      else {
-	// The group is on root - wrap
-	return ref.wrapOnRoot();
-      };
-    }
-    else if (ref.ldType() === 'doc') {
-
-      if (parent.ldType() === null) {
-	return ref.wrapOnRoot(type);
-      }
-      else if (parent.operation() === type) {
-	return parent.newAfter(ref);
-      }
-      else {
-	return ref.wrap(type);
-      };
-    };
-  };
-
-
-  // Add doc with 'and' relation
-  KorAP._and = function () {
-    return KorAP._add(this, 'and');
-  };
-
-
-  // Add doc with 'or' relation
-  KorAP._or = function () {
-    return KorAP._add(this, 'or');
-  };
-
-
-  // Remove doc or docGroup
-  KorAP._delete = function () {
-    var ref = this.parentNode.refTo;
-    if (ref.parent().ldType() !== null) {
-      return ref.parent().delOperand(ref).update();
-    }
-    else {
-      ref.parent().clean();
-    };
-  };
-
+  /*
+    loc.AND   = loc.AND   || 'and';
+    loc.OR    = loc.OR    || 'or';
+    loc.DEL   = loc.DEL   || '×';
+    loc.EMPTY = loc.EMPTY || '⋯'
+  */
 
   /**
    * Virtual Collection
    */
-  KorAP.VirtualCollection = {
+  return {
     ldType : function () {
       return null;
     },
 
     create : function () {
-      return Object.create(KorAP.VirtualCollection);
+      return Object.create(this);
     },
 
     clean : function () {
       if (this._root.ldType() !== "non") {
 	this._root.destroy();
-	this.root(KorAP.UnspecifiedDoc.create(this));
+	this.root(unspecDocClass.create(this));
       };
       return this;
     },
 
     render : function (json) {
-      var obj = Object.create(KorAP.VirtualCollection);
+      var obj = Object.create(this);
 
       if (json !== undefined) {
 	// Root object
 	if (json['@type'] == 'koral:doc') {
-	  obj._root = KorAP.Doc.create(obj, json);
+	  obj._root = docClass.create(obj, json);
 	}
 	else if (json['@type'] == 'koral:docGroup') {
-	  obj._root = KorAP.DocGroup.create(obj, json);
+	  obj._root = docGroupClass.create(obj, json);
 	}
 	else {
 	  KorAP.log(813, "Collection type is not supported");
@@ -225,1174 +151,4 @@
       return this._root.toQuery();
     }
   };
-
-
-  /**
-   * Operators for criteria
-   */
-  KorAP.Operators = {
-    create : function (and, or, del) {
-      var op = Object.create(KorAP.Operators);
-      op.and(and);
-      op.or(or);
-      op.del(del);
-      return op;
-    },
-
-    update : function () {
-      // Init the element
-      if (this._element === undefined)
-	return this.element();
-
-      var op = this._element;
-
-      op.refTo = this.parent();
-
-      // Remove everything underneath
-      _removeChildren(op);
-
-      // Add and button
-      if (this._and === true) {
-	var andE = document.createElement('span');
-	andE.setAttribute('class', 'and');
-	andE.addEventListener('click', KorAP._and, false);
-	andE.appendChild(
-	  document.createTextNode(KorAP.Locale.AND)
-	);
-	op.appendChild(andE);
-      };
-
-      // Add or button
-      if (this._or === true) {
-	var orE = document.createElement('span');
-	orE.setAttribute('class', 'or');
-	orE.addEventListener('click', KorAP._or, false);
-	orE.appendChild(document.createTextNode(KorAP.Locale.OR));
-	op.appendChild(orE);
-      };
-
-      // Add delete button
-      if (this._del === true) {
-	var delE = document.createElement('span');
-	delE.setAttribute('class', 'delete');
-	delE.appendChild(document.createTextNode(KorAP.Locale.DEL));
-	delE.addEventListener('click', KorAP._delete, false);
-	op.appendChild(delE);
-      };
-
-      return op;
-    },
-
-    // Be aware! This may be cyclic
-    parent : function (obj) {
-      if (arguments.length === 1)
-	this._parent = obj;
-      return this._parent;
-    },
-
-    element : function () {
-
-      // Return existing element
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'operators');
-
-      // Init elements
-      this.update();
-      return this._element;
-    },
-
-    and : function (bool) {
-      if (arguments.length === 1)
-	this._and = _bool(bool);
-      return this._and;
-    },
-
-    or : function (bool) {
-      if (arguments.length === 1)
-	this._or = _bool(bool);
-      return this._or;
-    },
-
-    del : function (bool) {
-      if (arguments.length === 1)
-	this._del = _bool(bool);
-      return this._del;
-    }
-  };
-
-
-  /**
-   * Unspecified criterion
-   */
-  KorAP.UnspecifiedDoc = {
-    _ldType : "non",
-    create : function (parent) {
-      var obj = Object.create(KorAP.JsonLD).
-	upgradeTo(KorAP.UnspecifiedDoc);
-
-      if (parent !== undefined)
-	obj._parent = parent;
-
-      return obj;
-    },
-
-    // Set key - replace
-    key : function (v) {
-
-      // Not replaceable
-      if (this._parent === undefined)
-	return null;
-
-      // Set JSON-LD type
-      var newDoc = KorAP.Doc.create(this._parent, {
-	"@type" : "koral:doc",
-	"value" : "",
-	"key"   : v
-      });
-
-      // Unspecified document on root
-      if (this._parent.ldType() === null) {
-	this._parent.root(newDoc);
-	this.destroy();
-      }
-
-      // Unspecified document in group
-      else {
-	this._parent.replaceOperand(this, newDoc);
-      };
-      this._parent.update();
-      return newDoc;
-    },
-
-    update : function () {
-
-      if (this._element === undefined)
-	return this.element();
-
-      // Remove element content
-      _removeChildren(this._element);
-
-      var ellipsis = document.createElement('span');
-      ellipsis.appendChild(document.createTextNode(loc.EMPTY));
-      this._element.appendChild(ellipsis);
-
-      // Set ref - TODO: Cleanup!
-      this._element.refTo = this;
-
-      // Set operators
-      if (this._parent !== undefined && this.parent().ldType() !== null) {
-	var op = this.operators(
-	  false,
-	  false,
-	  true
-	);
-
-	this._element.appendChild(
-	  op.element()
-	);
-      };
-
-      return this.element();
-    },
-
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'doc unspecified');
-      this.update();
-      return this._element;
-    },
-
-    
-  };
-
-
-  /**
-   * Document criterion
-   */
-  KorAP.Doc = {
-    _ldType : "doc",
-    _obj : function () { return KorAP.Doc },
-
-    create : function (parent, json) {
-      var obj = Object(KorAP.JsonLD).
-	create().
-	upgradeTo(KorAP.Doc).
-	fromJson(json);
-
-      if (parent !== undefined)
-	obj._parent = parent;
-
-      obj.__changed = true;
-      return obj;
-    },
-
-    update : function () {
-      if (this._element === undefined)
-	return this.element();
-
-      // Get element
-      var e = this._element;
-
-      // Set ref - TODO: Cleanup!
-      e.refTo = this;
-
-      // Check if there is a change
-      if (this.__changed) {
-
-	// Was rewritten
-	if (this.rewrites() !== undefined) {
-	  e.classList.add("rewritten");
-	};
-
-	// Added key
-	var key = document.createElement('span');
-	key.setAttribute('class', 'key');
-
-	// Change key
-	key.addEventListener('click', KorAP._changeKey, false);
-
-	if (this.key())
-	  key.appendChild(document.createTextNode(this.key()));
-
-	// Added match operator
-	var matchop = document.createElement('span');
-	matchop.setAttribute('data-type', this.type());
-	matchop.setAttribute('class', 'match');
-	matchop.appendChild(
-	  document.createTextNode(this.matchop())
-	);
-
-	// Added match operator
-	var value = document.createElement('span');
-	value.setAttribute('data-type', this.type());
-	value.setAttribute('class', 'value');
-	if (this.value())
-	  value.appendChild(
-	    document.createTextNode(this.value())
-	  );
-
-	// Remove all element children
-	_removeChildren(e);
-
-	// Add spans
-	e.appendChild(key);
-	e.appendChild(matchop);
-	e.appendChild(value);
-
-	this.__changed = false;
-      };
-
-      if (this._rewrites !== undefined) {
-	e.appendChild(this._rewrites.element());
-      };
-
-      if (this._parent !== undefined) {
-	// Set operators
-	var op = this.operators(
-	  true,
-	  true,
-	  true
-	);
-
-	// Append new operators
-	e.appendChild(op.element());
-      };
-
-      return e;
-    },
-
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'doc');
-
-      this.update();
-      return this._element;
-    },
-
-    // Wrap a new operation around the doc element
-    wrap : function (op) {
-      var parent = this.parent();
-      var group = KorAP.DocGroup.create(parent);
-      group.operation(op);
-      group.append(this);
-      group.append();
-      return parent.replaceOperand(this, group).update();
-    },
-
-    // Deserialize from json
-    fromJson : function (json) {
-      if (json === undefined)
-	return this;
-
-      if (json["@type"] === undefined) {
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-      };
-
-      if (json["value"] === undefined ||
-	  typeof json["value"] != 'string') {
-	KorAP.log(805, "Value is invalid");
-	return;
-      };
-
-      // There is a defined key
-      if (json["key"] !== undefined &&
-	  typeof json["key"] === 'string') {
-
-	// Set key
-	this.key(json["key"]);
-
-	// Set match operation
-	if (json["match"] !== undefined) {
-	  if (typeof json["match"] === 'string') {
-	    this.matchop(json["match"]);
-	  }
-	  else {
-	    KorAP.log(802, "Match type is not supported by value type");
-	    return;
-	  };
-	};
-
-	// Key is a string
-	if (json["type"] === undefined ||
-	    json["type"] == "type:string") {
-	  this.type("string");
-
-	  // Check match type
-	  if (!KorAP._validStringMatchRE.test(this.matchop())) {
-	    KorAP.log(802, "Match type is not supported by value type");
-	    return;
-	  };
-
-	  // Set string value
-	  this.value(json["value"]);
-	}
-
-	// Key is a date
-	else if (json["type"] === "type:date") {
-	  this.type("date");
-
-	  if (json["value"] !== undefined &&
-	      KorAP._validDateRE.test(json["value"])) {
-
-	    if (!KorAP._validDateMatchRE.test(this.matchop())) {
-	      KorAP.log(802, "Match type is not supported by value type");
-	      return;
-	    };
-
-	    // Set value
-	    this.value(json["value"]);
-	  }
-	  else {
-	    KorAP.log(806, "Value is not a valid date string");
-	    return;
-	  };
-	}
-
-	// Key is a regular expression
-	else if (json["type"] === "type:regex") {
-	  this.type("regex");
-
-	  try {
-
-	    // Try to create a regular expression
-	    var check = new RegExp(json["value"]);
-
-	    if (!KorAP._validRegexMatchRE.test(this.matchop())) {
-	      KorAP.log(802, "Match type is not supported by value type");
-	      return;
-	    };
-
-	    this.value(json["value"]);
-	  }
-
-	  catch (e) {
-	    KorAP.log(807, "Value is not a valid regular expression");
-	    return;
-	  };
-	  this.type("regex");
-	}
-
-	else {
-	  KorAP.log(804, "Unknown value type");
-	  return;
-	};
-
-      };
-
-      if (json["rewrites"] !== undefined) {
-	this._rewrites = KorAP.RewriteList.create(json["rewrites"]);
-      };
-	
-      return this;
-    },
-
-    key : function (value) {
-      if (arguments.length === 1) {
-	this._key = value;
-	this._changed();
-	return this;
-      };
-      return this._key;
-    },
-
-    matchop : function (match) {
-      if (arguments.length === 1) {
-	this._matchop = match.replace(/^match:/, '');
-	this._changed();
-	return this;
-      };
-      return this._matchop || "eq";
-    },
-
-    type : function (type) {
-      if (arguments.length === 1) {
-	this._type = type;
-	this._changed();
-	return this;
-      };
-      return this._type || "string";
-    },
-
-    value : function (value) {
-      if (arguments.length === 1) {
-	this._value = value;
-	this._changed();
-	return this;
-      };
-      return this._value;
-    },
-
-    rewrites : function () {
-      return this._rewrites;
-    },
-
-    _changed : function () {
-      this.__changed = true;
-
-      if (this._rewrites === undefined)
-	return;
-      delete this["_rewrites"];
-      if (this._element === undefined)
-	return;
-      this._element.classList.remove("rewritten");
-    },
-
-    toJson : function () {
-      if (!this.matchop() || !this.key())
-	return {};
-      
-      return {
-	"@type" : "koral:" + this.ldType(),
-	"key"   : this.key(),
-	"match" : "match:" + this.matchop(),
-	"value" : this.value() || '',
-	"type"  : "type:" + this.type()
-      };
-    },
-
-    toQuery : function () {
-      if (!this.matchop() || !this.key())
-	return "";
-
-      // Build doc string based on key
-      var string = this.key() + ' ';
-
-      // Add match operator
-      switch (this.matchop()) {
-      case "ne":
-	string += '!=';
-	break;
-      case "contains":
-	string += '~';
-	break;
-      case "excludes":
-	string += '!~';
-	break;
-      case "geq":
-	string += 'since';
-	break;
-      case "leq":
-	string += 'until';
-	break;
-      default:
-	string += (this.type() == 'date') ? 'in' : '=';
-	break;
-      };
-
-      string += ' ';
-
-      // Add value
-      switch (this.type()) {
-      case "date":
-	return string + this.value();
-	break;
-      case "regex":
-	return string + '/' + this.value() + '/';
-	break;
-      case "string":
-	return string + '"' + this.value().replace(KorAP._quote, '\\$1') + '"';
-	break;
-      };
-
-      return "";
-    }
-  };
-
-
-  /**
-   * Document group criterion
-   */
-  KorAP.DocGroup = {
-    _ldType : "docGroup",
-
-    create : function (parent, json) {
-      var obj = Object.create(KorAP.JsonLD).upgradeTo(KorAP.DocGroup);
-      obj._operands = [];
-      obj.fromJson(json);
-      if (parent !== undefined)
-	obj._parent = parent;
-      return obj;
-    },
-
-    newAfter : function (obj) {
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i] === obj) {
-	  var operand = KorAP.UnspecifiedDoc.create(this);
-	  this._operands.splice(i + 1, 0, operand);
-	  return this.update();
-	};
-      };
-    },
-
-    // The doc is already set in the group
-    _duplicate : function (operand) {
-      if (operand.ldType() !== 'doc')
-	return null;
-
-      for (var i = 0; i < this._operands.length; i++) {
-	var op = this.getOperand(i);
-	if (op.ldType() === 'doc'
-	    && operand.key() === op.key()
-	    && operand.matchop() === op.matchop()
-	    && operand.value() === op.value()) {
-	  return op;
-	};
-      };
-      return null;
-    },
-
-    append : function (operand) {
-
-      // Append unspecified object
-      if (operand === undefined) {
-
-	// Be aware of cyclic structures!
-	operand = KorAP.UnspecifiedDoc.create(this);
-	this._operands.push(operand);
-	return operand;
-      };
-
-      switch (operand["@type"]) {
-
-      case undefined:
-	// No @type defined
-	if (operand["ldType"] !== undefined) {
-	  if (operand.ldType() !== 'doc' &&
-	      operand.ldType() !== 'docGroup') {
-	    KorAP.log(812, "Operand not supported in document group");
-	    return;
-	  };
-	  // Be aware of cyclic structures!
-	  operand.parent(this);
-
-	  var dupl = this._duplicate(operand);
-	  if (dupl === null) {
-	    this._operands.push(operand);
-	    return operand;
-	  };
-	  return dupl;
-	};
-
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-
-      case "koral:doc":
-	// Be aware of cyclic structures!
-	var doc = KorAP.Doc.create(this, operand);
-	if (doc === undefined)
-	  return;
-	var dupl = this._duplicate(doc);
-	if (dupl === null) {
-	  this._operands.push(doc);
-	  return doc;
-	};
-	return dupl;
-
-      case "koral:docGroup":
-	// Be aware of cyclic structures!
-	var docGroup = KorAP.DocGroup.create(this, operand);
-	if (docGroup === undefined)
-	  return;
-
-	// Flatten group
-	if (docGroup.operation() === this.operation()) {
-	  for (var op in docGroup.operands()) {
-	    op = docGroup.getOperand(op);
-	    var dupl = this._duplicate(op);
-	    if (dupl === null) {
-	      this._operands.push(op);
-	      op.parent(this);
-	    };
-	  };
-	  docGroup._operands = [];
-	  docGroup.destroy();
-	  return this;
-	};
-	this._operands.push(docGroup);
-	return docGroup;
-
-      default:
-	KorAP.log(812, "Operand not supported in document group");
-	return;
-      };
-    },
-
-    update : function () {
-      // There is only one operand in group
-
-      if (this._operands.length === 1) {
-
-	var parent = this.parent();
-	var op = this.getOperand(0);
-
-	// This will prevent destruction of
-	// the operand
-	this._operands = [];
-
-	// Parent is a group
-	if (parent.ldType() !== null)
-	  return parent.replaceOperand(this, op).update();
-
-	// Parent is vc
-	else {
-	  this.destroy();
-	  // Cyclic madness
-	  parent.root(op);
-	  op.parent(parent);
-	  return parent.root();
-	};
-      };
-
-      if (this._element === undefined)
-	return this;
-
-      var group = this._element;
-      group.setAttribute('data-operation', this.operation());
-
-      _removeChildren(group);
-
-      // Append operands
-      for (var i = 0; i < this._operands.length; i++) {
-	group.appendChild(
-	  this.getOperand(i).element()
-	);
-      };
-
-      // Set operators
-      var op = this.operators(
-	this.operation() == 'and' ? false : true,
-	this.operation() == 'or'  ? false : true,
-	true
-      );
-
-      group.appendChild(
-	op.element()
-      );
-
-      return this;
-    },
-
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'docGroup');
-
-      // Update the object - including optimization
-      this.update();
-
-      return this._element;
-    },
-
-    operation : function (op) {
-      if (arguments.length === 1) {
-	if (KorAP._validGroupOpRE.test(op)) {
-	  this._op = op;
-	}
-	else {
-	  KorAP.log(810, "Unknown operation type");
-	  return;
-	};
-      };
-      return this._op || 'and';
-    },
-
-    operands : function () {
-      return this._operands;
-    },
-
-    getOperand : function (index) {
-      return this._operands[index];
-    },
-
-    // Replace operand
-    replaceOperand : function (oldOp, newOp) {
-
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i] === oldOp) {
-
-	  // Just insert a doc or ...
-	  if (newOp.ldType() === "doc" ||
-	      newOp.ldType() === "non" ||
-	      // ... insert a group of a different operation
-	      // (i.e. "and" in "or"/"or" in "and")
-	      newOp.operation() != this.operation()) {
-	    this._operands[i] = newOp;
-	    newOp.parent(this);
-	  }
-
-	  // Flatten group
-	  else {
-	    // Remove old group
-	    this._operands.splice(i, 1);
-
-	    // Inject new operands
-	    for (var op in newOp.operands().reverse()) {
-	      op = newOp.getOperand(op);
-	      this._operands.splice(i, 0, op);
-	      op.parent(this);
-	    };
-	    // Prevent destruction of operands
-	    newOp._operands = [];
-	    newOp.destroy();
-	  };
-	  oldOp.destroy();
-	  return this;
-	}
-      };
-      return false;
-    },
-
-    // Delete operand from group
-    delOperand : function (obj) {
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i] === obj) {
-
-	  // Delete identified operand
-	  this._operands.splice(i,1);
-
-	  // Destroy object for cyclic references
-	  obj.destroy();
-
-	  return this;
-	};
-      };
-
-      // Operand not found
-      return undefined;
-    },
-
-    // Deserialize from json
-    fromJson : function (json) {
-      if (json === undefined)
-	return this;
-
-      if (json["@type"] === undefined) {
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-      };
-
-      if (json["operation"] === undefined ||
-	  typeof json["operation"] !== 'string') {
-	KorAP.log(811, "Document group expects operation");
-	return;
-      };
-
-      var operation = json["operation"];
-
-      this.operation(operation.replace(/^operation:/,''));
-
-      if (json["operands"] === undefined ||
-	  !(json["operands"] instanceof Array)) {
-	KorAP.log(704, "Operation needs operand list")
-	return;
-      };
-
-      // Add all documents
-      for (var i in json["operands"]) {
-	var operand = json["operands"][i];
-	this.append(operand);
-      };
-    
-      return this;
-    },
-
-    toJson : function () {
-      var opArray = new Array();
-      for (var i = 0; i < this._operands.length; i++) {
-	if (this._operands[i].ldType() !== 'non')
-	  opArray.push(this._operands[i].toJson());
-      };
-      return {
-	"@type"     : "koral:" + this.ldType(),
-	"operation" : "operation:" + this.operation(),
-	"operands"  : opArray
-      };
-    },
-
-    toQuery : function (brackets) {
-      var list = this._operands
-	.filter(function (op) {
-	  return op.ldType() !== 'non';
-	})
-	.map(function (op) {
-	  return (op.ldType() === 'docGroup') ?
-	    op.toQuery(true) :
-	    op.toQuery();
-	});
-
-      if (list.length === 1)
-	return list.join('');
-      else {
-	var str = list.join(this.operation() === 'or' ? ' | ' : ' & ');
-	return brackets ? '(' + str + ')' : str;
-      };
-    }
-  };
-
-
-  KorAP.RewriteList = {
-    // Construction method
-    create : function (json) {
-      var obj = Object(KorAP.JsonLD).
-	create().
-	upgradeTo(KorAP.RewriteList).
-	fromJson(json);
-      return obj;
-    },
-    fromJson : function (json) {
-      this._list = new Array();
-      for (var i = 0; i < json.length; i++) {
-	this._list.push(
-	  KorAP.Rewrite.create(json[i])
-	);
-      };
-      return this;
-    },
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      this._element.setAttribute('class', 'rewrite');
-      for (var x in this._list) {
-	var rewrite = this._list[x];
-	var span = document.createElement('span');
-
-	// Set class attribute
-	span.setAttribute('class', rewrite.operation());
-
-	// Append source information
-	span.appendChild(document.createTextNode(rewrite.src()));
-
-	// Append scope information
-	if (rewrite.scope() !== undefined) {
-	  span.appendChild(
-	    document.createTextNode(
-	      ': ' + rewrite.scope()
-	    )
-	  );
-	};
-	this._element.appendChild(span);
-      };
-      return this._element;
-    }
-  };
-
-
-  /**
-   * Implementation of rewrite objects.
-   */
-  KorAP.Rewrite = {
-
-    // Construction method
-    create : function (json) {
-      var obj = Object(KorAP.JsonLD).
-	create().
-	upgradeTo(KorAP.Rewrite).
-	fromJson(json);
-      return obj;
-    },
-
-    // Get or set source
-    src : function (string) {
-      if (arguments.length === 1)
-	this._src = string;
-      return this._src;
-    },
-    
-    // Get or set operation
-    operation : function (op) {
-      if (arguments.length === 1) {
-	if (KorAP._validRewriteOpRE.test(op)) {
-	  this._op = op;
-	}
-	else {
-	  KorAP.log(814, "Unknown rewrite operation");
-	  return;
-	};
-      };
-      return this._op || 'injection';
-    },
-
-    // Get or set scope
-    scope : function (attr) {
-      if (arguments.length === 1)
-	this._scope = attr;
-      return this._scope;
-    },
-
-    // Serialize from Json
-    fromJson : function (json) {
-      if (json === undefined)
-	return this;
-
-      // Missing @type
-      if (json["@type"] === undefined) {
-	KorAP.log(701, "JSON-LD group has no @type attribute");
-	return;
-      };
-
-      // Missing source
-      if (json["src"] === undefined ||
-	 typeof json["src"] !== 'string') {
-	KorAP.log(815, "Rewrite expects source");
-	return;
-      };
-
-      // Set source
-      this.src(json["src"]);
-
-      // Set operation
-      if (json["operation"] !== undefined) {
-	var operation = json["operation"];
-	this.operation(operation.replace(/^operation:/,''));
-      };
-
-      // Set scope
-      if (json["scope"] !== undefined &&
-	  typeof json["scope"] === 'string')
-	this.scope(json["scope"]);
-
-      return this;
-    },
-
-    toString : function () {
-      var str = '';
-      var op = this.operation();
-      str += op.charAt(0).toUpperCase() + op.slice(1);
-      str += ' of ' + (
-	this._scope === null ?
-	  'object' :
-	  '"' +
-	  this.scope().replace(KorAP._quote, '\\$1') +
-	  '"'
-      );
-      str += ' by ' +
-	'"' +
-	this.src().replace(KorAP._quote, '\\$1') +
-	'"';
-      return str;
-    }
-  };
-
-
-  /**
-   * Abstract JsonLD criterion object
-   */
-  KorAP.JsonLD = {
-    __changed : false,
-
-    create : function () {
-      return Object.create(KorAP.JsonLD);
-    },
-
-    /**
-     * Upgrade this object to another object
-     * while private data stays intact
-     */
-    upgradeTo : function (props) {
-      for (var prop in props) {
-	this[prop] = props[prop];
-      };
-      return this;
-    },
-
-    ldType : function (type) {
-      if (arguments.length === 1)
-	this._ldType = type;
-      return this._ldType;
-    },
-
-    parent : function (obj) {
-      if (arguments.length === 1) {
-	this._parent = obj;
-	this.__changed = true;
-      };
-      return this._parent;
-    },
-
-    // Destroy object - especially for
-    // acyclic structures!
-    // I'm paranoid!
-    destroy : function () {
-      if (this._ops != undefined) {
-	this._ops._parent = undefined;
-	if (this._ops._element !== undefined)
-	  this._ops._element.refTo = undefined;
-	this._ops = undefined;
-      };
-      if (this._element !== undefined)
-	this._element = undefined;
-
-      // In case of a group, destroy all operands
-      if (this._operands !== undefined) {
-      for (var i = 0; i < this._operands.length; i++)
-	  this.getOperand(i).destroy();
-	this._operands = [];
-      };
-    },
-
-    // Wrap a new operation around the root group element 
-    wrapOnRoot : function (op) {
-      var parent = this.parent();
-
-      var group = KorAP.DocGroup.create(parent);
-      if (arguments.length === 1)
-	group.operation(op);
-      else
-	group.operation(
-	  this.operation() === 'and' ? 'or' : 'and'
-	);
-      group.append(this);
-      this.parent(group);
-      group.append();
-      group.element(); // Init (seems to be necessary)
-      parent.root(group);
-      return this.parent();
-    },
-
-    // Be aware! This may be cyclic
-    operators : function (and, or, del) {
-      if (arguments === 0)
-	return this._ops;
-      this._ops = KorAP.Operators.create(
-	and, or, del
-      );
-      this._ops.parent(this);
-      return this._ops;
-    },
-
-    toJson : function () {
-      return {
-	// Unspecified object
-	"@type" : "koral:" + this.ldType()
-      };
-    },
-
-    toQuery : function () {
-      return '';
-    }
-  };
-
-
-  /**
-   * Criterion in a KorAP.Doc
-   */
-  KorAP._changeKey = function () {
-    var doc = this.parentNode.refTo;
-    var key = doc.element().firstChild;
-    key.appendChild(KorAP.FieldChooser.element());
-    KorAP.FieldChooser.show();
-    KorAP.FieldChooser.focus();
-    // key, matchop, type, value
-  };
-  
-  // Field menu
-  KorAP.FieldMenu = {
-    create : function (params) {
-      return Object.create(KorAP.Menu)
-	.upgradeTo(KorAP.FieldMenu)
-	._init(KorAP.FieldMenuItem, undefined, params)
-    }
-  };
-
-
-  // Field menu item
-  KorAP.FieldMenuItem = {
-    create : function (params) {
-      return Object.create(KorAP.MenuItem)
-	.upgradeTo(KorAP.FieldMenuItem)
-	._init(params);
-    },
-    _init : function (params) {
-      if (params[0] === undefined)
-	throw new Error("Missing parameters");
-
-      this._name  = params[0];
-      this._value = params[1];
-      this._type  = params[2];
-
-      this._lcField = ' ' + this._name.toLowerCase();
-
-      return this;
-    },
-    name : function () {
-      return this._name;
-    },
-    type : function () {
-      return this._type;
-    },
-    element : function () {
-      // already defined
-      if (this._element !== undefined)
-	return this._element;
-
-      // Create list item
-      var li = document.createElement("li");
-      li.setAttribute("data-type", this._type);
-      li.setAttribute("data-value", this._value);
-      li.appendChild(document.createTextNode(this._name));
-      return this._element = li;
-    }
-  };
-
-  KorAP.FieldChooser = KorAP.FieldMenu.create([
-    ['Titel', 'title', 'string'],
-    ['Untertitel', 'subTitle', 'string'],
-    ['Veröffentlichungsdatum', 'pubDate', 'date'],
-    ['Autor', 'author', 'string']
-  ]);
-  KorAP.FieldChooser.limit(5);
- 
-}(this.KorAP));
+});
diff --git a/dev/js/src/vc/doc.js b/dev/js/src/vc/doc.js
new file mode 100644
index 0000000..61c6439
--- /dev/null
+++ b/dev/js/src/vc/doc.js
@@ -0,0 +1,363 @@
+/**
+ * Document criterion
+ */
+
+/**
+ * Criterion in a KorAP.Doc
+ */
+function _changeKey () {
+  var doc = this.parentNode.refTo;
+  var key = doc.element().firstChild;
+  key.appendChild(fieldMenu.element());
+  fieldMenu.show();
+  fieldMenu.focus();
+  // key, matchop, type, value
+};
+
+define([
+  'vc/jsonld', 'vc/menu', 'vc/rewritelist'], function (jsonldClass, menuClass, rewriteListClass) {
+  var fieldMenu = menuClass.create([
+    ['Titel', 'title', 'string'],
+    ['Untertitel', 'subTitle', 'string'],
+    ['Veröffentlichungsdatum', 'pubDate', 'date'],
+    ['Autor', 'author', 'string']
+  ]);
+
+  fieldMenu.limit(5);
+
+  _validRegexMatchRE  = new RegExp("^(?:eq|ne)$");
+
+  return {
+    _ldType : "doc",
+    _obj : function () { return '???'; /*KorAP.Doc*/ },
+    
+    create : function (parent, json) {
+      var obj = Object(jsonldClass).
+	create().
+	upgradeTo(this).
+	fromJson(json);
+      
+      if (parent !== undefined)
+	obj._parent = parent;
+      
+      obj.__changed = true;
+      return obj;
+    },
+
+    update : function () {
+      if (this._element === undefined)
+	return this.element();
+      
+      // Get element
+      var e = this._element;
+
+      // Set ref - TODO: Cleanup!
+      e.refTo = this;
+
+      // Check if there is a change
+      if (this.__changed) {
+
+	// Was rewritten
+	if (this.rewrites() !== undefined) {
+	  e.classList.add("rewritten");
+	};
+
+	// Added key
+	var key = document.createElement('span');
+	key.setAttribute('class', 'key');
+
+	// Change key
+	key.addEventListener('click', _changeKey, false);
+
+	if (this.key())
+	  key.appendChild(document.createTextNode(this.key()));
+	
+	// Added match operator
+	var matchop = document.createElement('span');
+	matchop.setAttribute('data-type', this.type());
+	matchop.setAttribute('class', 'match');
+	matchop.appendChild(
+	  document.createTextNode(this.matchop())
+	);
+
+	// Added match operator
+	var value = document.createElement('span');
+	value.setAttribute('data-type', this.type());
+	value.setAttribute('class', 'value');
+	if (this.value())
+	  value.appendChild(
+	    document.createTextNode(this.value())
+	  );
+
+	// Remove all element children
+	_removeChildren(e);
+
+	// Add spans
+	e.appendChild(key);
+	e.appendChild(matchop);
+	e.appendChild(value);
+
+	this.__changed = false;
+      };
+
+      if (this._rewrites !== undefined) {
+	e.appendChild(this._rewrites.element());
+      };
+
+      if (this._parent !== undefined) {
+	// Set operators
+	var op = this.operators(
+	  true,
+	  true,
+	  true
+	);
+
+	// Append new operators
+	e.appendChild(op.element());
+      };
+      
+      return e;
+    },
+
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'doc');
+
+      this.update();
+      return this._element;
+    },
+
+    // Wrap a new operation around the doc element
+    wrap : function (op) {
+      var parent = this.parent();
+      var group = KorAP.DocGroup.create(parent);
+      group.operation(op);
+      group.append(this);
+      group.append();
+      return parent.replaceOperand(this, group).update();
+    },
+
+    // Deserialize from json
+    fromJson : function (json) {
+      if (json === undefined)
+	return this;
+
+      if (json["@type"] === undefined) {
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+      };
+
+      if (json["value"] === undefined ||
+	  typeof json["value"] != 'string') {
+	KorAP.log(805, "Value is invalid");
+	return;
+      };
+
+      // There is a defined key
+      if (json["key"] !== undefined &&
+	  typeof json["key"] === 'string') {
+
+	// Set key
+	this.key(json["key"]);
+
+	// Set match operation
+	if (json["match"] !== undefined) {
+	  if (typeof json["match"] === 'string') {
+	    this.matchop(json["match"]);
+	  }
+	  else {
+	    KorAP.log(802, "Match type is not supported by value type");
+	    return;
+	  };
+	};
+
+	// Key is a string
+	if (json["type"] === undefined ||
+	    json["type"] == "type:string") {
+	  this.type("string");
+
+	  // Check match type
+	  if (!KorAP._validStringMatchRE.test(this.matchop())) {
+	    KorAP.log(802, "Match type is not supported by value type");
+	    return;
+	  };
+
+	  // Set string value
+	  this.value(json["value"]);
+	}
+
+	// Key is a date
+	else if (json["type"] === "type:date") {
+	  this.type("date");
+
+	  if (json["value"] !== undefined &&
+	      KorAP._validDateRE.test(json["value"])) {
+
+	    if (!KorAP._validDateMatchRE.test(this.matchop())) {
+	      KorAP.log(802, "Match type is not supported by value type");
+	      return;
+	    };
+
+	    // Set value
+	    this.value(json["value"]);
+	  }
+	  else {
+	    KorAP.log(806, "Value is not a valid date string");
+	    return;
+	  };
+	}
+
+	// Key is a regular expression
+	else if (json["type"] === "type:regex") {
+	  this.type("regex");
+
+	  try {
+
+	    // Try to create a regular expression
+	    var check = new RegExp(json["value"]);
+
+	    if (!_validRegexMatchRE.test(this.matchop())) {
+	      KorAP.log(802, "Match type is not supported by value type");
+	      return;
+	    };
+
+	    this.value(json["value"]);
+	  }
+
+	  catch (e) {
+	    KorAP.log(807, "Value is not a valid regular expression");
+	    return;
+	  };
+	  this.type("regex");
+	}
+
+	else {
+	  KorAP.log(804, "Unknown value type");
+	  return;
+	};
+      };
+
+      if (json["rewrites"] !== undefined) {
+	this._rewrites = rewriteListClass.create(json["rewrites"]);
+      };
+      
+      return this;
+    },
+
+    key : function (value) {
+      if (arguments.length === 1) {
+	this._key = value;
+	this._changed();
+	return this;
+      };
+      return this._key;
+    },
+
+    matchop : function (match) {
+      if (arguments.length === 1) {
+	this._matchop = match.replace(/^match:/, '');
+	this._changed();
+	return this;
+      };
+      return this._matchop || "eq";
+    },
+
+    type : function (type) {
+      if (arguments.length === 1) {
+	this._type = type;
+	this._changed();
+	return this;
+      };
+      return this._type || "string";
+    },
+
+    value : function (value) {
+      if (arguments.length === 1) {
+	this._value = value;
+	this._changed();
+	return this;
+      };
+      return this._value;
+    },
+
+    rewrites : function () {
+      return this._rewrites;
+    },
+
+    _changed : function () {
+      this.__changed = true;
+      
+      if (this._rewrites === undefined)
+	return;
+
+      delete this["_rewrites"];
+
+      if (this._element === undefined)
+	return;
+      this._element.classList.remove("rewritten");
+    },
+
+    toJson : function () {
+      if (!this.matchop() || !this.key())
+	return {};
+      
+      return {
+	"@type" : "koral:" + this.ldType(),
+	"key"   : this.key(),
+	"match" : "match:" + this.matchop(),
+	"value" : this.value() || '',
+	"type"  : "type:" + this.type()
+      };
+    },
+
+    toQuery : function () {
+      if (!this.matchop() || !this.key())
+	return "";
+
+      // Build doc string based on key
+      var string = this.key() + ' ';
+
+      // Add match operator
+      switch (this.matchop()) {
+      case "ne":
+	string += '!=';
+	break;
+      case "contains":
+	string += '~';
+	break;
+      case "excludes":
+	string += '!~';
+	break;
+      case "geq":
+	string += 'since';
+	break;
+      case "leq":
+	string += 'until';
+	break;
+      default:
+	string += (this.type() == 'date') ? 'in' : '=';
+	break;
+      };
+
+      string += ' ';
+
+      // Add value
+      switch (this.type()) {
+      case "date":
+	return string + this.value();
+	break;
+      case "regex":
+	return string + '/' + this.value() + '/';
+	break;
+      case "string":
+	return string + '"' + this.value().replace(KorAP._quote, '\\$1') + '"';
+	break;
+      };
+
+      return "";
+    }
+  };
+});
diff --git a/dev/js/src/vc/docgroup.js b/dev/js/src/vc/docgroup.js
new file mode 100644
index 0000000..5e5f010
--- /dev/null
+++ b/dev/js/src/vc/docgroup.js
@@ -0,0 +1,343 @@
+/**
+ * Document group criterion
+ */
+define([
+  'vc/jsonld',
+  'vc/unspecified',
+  'vc/doc',
+  'util'
+], function (jsonldClass,
+	     unspecClass,
+	     docClass) {
+
+  var _validGroupOpRE = new RegExp("^(?:and|or)$");
+
+  var docGroupClass = {
+    _ldType : "docGroup",
+
+    create : function (parent, json) {
+      var obj = Object.create(jsonldClass).upgradeTo(this);
+      obj._operands = [];
+      obj.fromJson(json);
+      if (parent !== undefined)
+	obj._parent = parent;
+      return obj;
+    },
+    
+    newAfter : function (obj) {
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i] === obj) {
+	  var operand = unspecClass.create(this);
+	  this._operands.splice(i + 1, 0, operand);
+	  return this.update();
+	};
+      };
+    },
+
+    // The doc is already set in the group
+    _duplicate : function (operand) {
+      if (operand.ldType() !== 'doc')
+	return null;
+
+      for (var i = 0; i < this._operands.length; i++) {
+	var op = this.getOperand(i);
+	if (op.ldType() === 'doc'
+	    && operand.key() === op.key()
+	    && operand.matchop() === op.matchop()
+	    && operand.value() === op.value()) {
+	  return op;
+	};
+      };
+      return null;
+    },
+    
+    append : function (operand) {
+      
+      // Append unspecified object
+      if (operand === undefined) {
+
+	// Be aware of cyclic structures!
+	operand = unspecClass.create(this);
+	this._operands.push(operand);
+	return operand;
+      };
+      
+      switch (operand["@type"]) {
+	
+      case undefined:
+	// No @type defined
+	if (operand["ldType"] !== undefined) {
+	  if (operand.ldType() !== 'doc' &&
+	      operand.ldType() !== 'docGroup') {
+	    KorAP.log(812, "Operand not supported in document group");
+	    return;
+	  };
+
+	  // Be aware of cyclic structures!
+	  operand.parent(this);
+
+	  var dupl = this._duplicate(operand);
+	  if (dupl === null) {
+	    this._operands.push(operand);
+	    return operand;
+	  };
+	  return dupl;
+	};
+
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+
+      case "koral:doc":
+	// Be aware of cyclic structures!
+	var doc = docClass.create(this, operand);
+	if (doc === undefined)
+	  return;
+	var dupl = this._duplicate(doc);
+	if (dupl === null) {
+	  this._operands.push(doc);
+	  return doc;
+	};
+	return dupl;
+
+      case "koral:docGroup":
+	// Be aware of cyclic structures!
+	var docGroup = docGroupClass.create(this, operand);
+	if (docGroup === undefined)
+	  return;
+
+	// Flatten group
+	if (docGroup.operation() === this.operation()) {
+	  for (var op in docGroup.operands()) {
+	    op = docGroup.getOperand(op);
+	    var dupl = this._duplicate(op);
+	    if (dupl === null) {
+	      this._operands.push(op);
+	      op.parent(this);
+	    };
+	  };
+	  docGroup._operands = [];
+	  docGroup.destroy();
+	  return this;
+	};
+	this._operands.push(docGroup);
+	return docGroup;
+
+      default:
+	KorAP.log(812, "Operand not supported in document group");
+	return;
+      };
+    },
+
+    update : function () {
+      // There is only one operand in group
+      
+      if (this._operands.length === 1) {
+	
+	var parent = this.parent();
+	var op = this.getOperand(0);
+	
+	// This will prevent destruction of
+	// the operand
+	this._operands = [];
+
+	// Parent is a group
+	if (parent.ldType() !== null)
+	  return parent.replaceOperand(this, op).update();
+
+	// Parent is vc
+	else {
+	  this.destroy();
+	  // Cyclic madness
+	  parent.root(op);
+	  op.parent(parent);
+	  return parent.root();
+	};
+      };
+
+      if (this._element === undefined)
+	return this;
+
+      var group = this._element;
+      group.setAttribute('data-operation', this.operation());
+
+      _removeChildren(group);
+
+      // Append operands
+      for (var i = 0; i < this._operands.length; i++) {
+	group.appendChild(
+	  this.getOperand(i).element()
+	);
+      };
+
+      // Set operators
+      var op = this.operators(
+	this.operation() == 'and' ? false : true,
+	this.operation() == 'or'  ? false : true,
+	true
+      );
+
+      group.appendChild(op.element());
+
+      return this;
+    },
+
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'docGroup');
+
+      // Update the object - including optimization
+      this.update();
+
+      return this._element;
+    },
+
+    operation : function (op) {
+      if (arguments.length === 1) {
+	if (_validGroupOpRE.test(op)) {
+	  this._op = op;
+	}
+	else {
+	  KorAP.log(810, "Unknown operation type");
+	  return;
+	};
+      };
+      return this._op || 'and';
+    },
+
+    operands : function () {
+      return this._operands;
+    },
+
+    getOperand : function (index) {
+      return this._operands[index];
+    },
+
+    // Replace operand
+    replaceOperand : function (oldOp, newOp) {
+      
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i] === oldOp) {
+	  
+	  // Just insert a doc or ...
+	  if (newOp.ldType() === "doc" ||
+	      newOp.ldType() === "non" ||
+	      // ... insert a group of a different operation
+	      // (i.e. "and" in "or"/"or" in "and")
+	      newOp.operation() != this.operation()) {
+	    this._operands[i] = newOp;
+	    newOp.parent(this);
+	  }
+
+	  // Flatten group
+	  else {
+	    // Remove old group
+	    this._operands.splice(i, 1);
+
+	    // Inject new operands
+	    for (var op in newOp.operands().reverse()) {
+	      op = newOp.getOperand(op);
+	      this._operands.splice(i, 0, op);
+	      op.parent(this);
+	    };
+	    // Prevent destruction of operands
+	    newOp._operands = [];
+	    newOp.destroy();
+	  };
+	  oldOp.destroy();
+	  return this;
+	}
+      };
+      return false;
+    },
+
+    // Delete operand from group
+    delOperand : function (obj) {
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i] === obj) {
+	  
+	  // Delete identified operand
+	  this._operands.splice(i,1);
+
+	  // Destroy object for cyclic references
+	  obj.destroy();
+
+	  return this;
+	};
+      };
+
+      // Operand not found
+      return undefined;
+    },
+    
+    // Deserialize from json
+    fromJson : function (json) {
+      if (json === undefined)
+	return this;
+
+      if (json["@type"] === undefined) {
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+      };
+
+      if (json["operation"] === undefined ||
+	  typeof json["operation"] !== 'string') {
+	KorAP.log(811, "Document group expects operation");
+	return;
+      };
+
+      var operation = json["operation"];
+
+      this.operation(operation.replace(/^operation:/,''));
+
+      if (json["operands"] === undefined ||
+	  !(json["operands"] instanceof Array)) {
+	KorAP.log(704, "Operation needs operand list")
+	return;
+      };
+
+      // Add all documents
+      for (var i in json["operands"]) {
+	var operand = json["operands"][i];
+	this.append(operand);
+      };
+      
+      return this;
+    },
+
+    toJson : function () {
+      var opArray = new Array();
+      for (var i = 0; i < this._operands.length; i++) {
+	if (this._operands[i].ldType() !== 'non')
+	  opArray.push(this._operands[i].toJson());
+      };
+      return {
+	"@type"     : "koral:" + this.ldType(),
+	"operation" : "operation:" + this.operation(),
+	"operands"  : opArray
+      };
+    },
+
+    toQuery : function (brackets) {
+      var list = this._operands
+	.filter(function (op) {
+	  return op.ldType() !== 'non';
+	})
+	.map(function (op) {
+	  return (op.ldType() === 'docGroup') ?
+	    op.toQuery(true) :
+	    op.toQuery();
+	});
+      
+      if (list.length === 1)
+	return list.join('');
+      else {
+	var str = list.join(this.operation() === 'or' ? ' | ' : ' & ');
+	return brackets ? '(' + str + ')' : str;
+      };
+    }
+  };
+  return docGroupClass;
+});
diff --git a/dev/js/src/vc/item.js b/dev/js/src/vc/item.js
new file mode 100644
index 0000000..bfefe38
--- /dev/null
+++ b/dev/js/src/vc/item.js
@@ -0,0 +1,44 @@
+// Field menu item
+define(['menu/item'], function (itemClass) {
+  return {
+    create : function (params) {
+      return Object.create(itemClass)
+	.upgradeTo(this)
+	._init(params);
+    },
+
+    _init : function (params) {
+      if (params[0] === undefined)
+	throw new Error("Missing parameters");
+
+      this._name  = params[0];
+      this._value = params[1];
+      this._type  = params[2];
+
+      this._lcField = ' ' + this._name.toLowerCase();
+
+      return this;
+    },
+
+    name : function () {
+      return this._name;
+    },
+
+    type : function () {
+      return this._type;
+    },
+
+    element : function () {
+      // already defined
+      if (this._element !== undefined)
+	return this._element;
+
+      // Create list item
+      var li = document.createElement("li");
+      li.setAttribute("data-type", this._type);
+      li.setAttribute("data-value", this._value);
+      li.appendChild(document.createTextNode(this._name));
+      return this._element = li;
+    }
+  };
+});
diff --git a/dev/js/src/vc/jsonld.js b/dev/js/src/vc/jsonld.js
new file mode 100644
index 0000000..324e7db
--- /dev/null
+++ b/dev/js/src/vc/jsonld.js
@@ -0,0 +1,99 @@
+/**
+ * Abstract JsonLD criterion object
+ */
+define(['vc/operators'], function (operatorsClass) {
+  return {
+    __changed : false,
+    
+    create : function () {
+      return Object.create(this);
+    },
+
+    /**
+     * Upgrade this object to another object
+     * while private data stays intact
+     */
+    upgradeTo : function (props) {
+      for (var prop in props) {
+	this[prop] = props[prop];
+      };
+      return this;
+    },
+    
+    ldType : function (type) {
+      if (arguments.length === 1)
+	this._ldType = type;
+      return this._ldType;
+    },
+    
+    parent : function (obj) {
+      if (arguments.length === 1) {
+	this._parent = obj;
+	this.__changed = true;
+      };
+      return this._parent;
+    },
+
+    // Destroy object - especially for
+    // acyclic structures!
+    // I'm paranoid!
+    destroy : function () {
+      if (this._ops != undefined) {
+	this._ops._parent = undefined;
+	if (this._ops._element !== undefined)
+	  this._ops._element.refTo = undefined;
+	this._ops = undefined;
+      };
+      if (this._element !== undefined)
+	this._element = undefined;
+      
+      // In case of a group, destroy all operands
+      if (this._operands !== undefined) {
+	for (var i = 0; i < this._operands.length; i++)
+	  this.getOperand(i).destroy();
+	this._operands = [];
+      };
+    },
+    
+    // Wrap a new operation around the root group element 
+    wrapOnRoot : function (op) {
+      var parent = this.parent();
+      
+      var group = require('vc/docgroup').create(parent);
+      if (arguments.length === 1)
+	group.operation(op);
+      else
+	group.operation(
+	  this.operation() === 'and' ? 'or' : 'and'
+	);
+      group.append(this);
+      this.parent(group);
+      group.append();
+      group.element(); // Init (seems to be necessary)
+      parent.root(group);
+      return this.parent();
+    },
+
+    // Be aware! This may be cyclic
+    operators : function (and, or, del) {
+      if (arguments === 0)
+	return this._ops;
+      this._ops = operatorsClass.create(
+	and, or, del
+      );
+      this._ops.parent(this);
+      return this._ops;
+    },
+
+    toJson : function () {
+      return {
+	// Unspecified object
+	"@type" : "koral:" + this.ldType()
+      };
+    },
+
+    toQuery : function () {
+      return '';
+    }
+  };
+});
diff --git a/dev/js/src/vc/menu.js b/dev/js/src/vc/menu.js
new file mode 100644
index 0000000..6f6d2bd
--- /dev/null
+++ b/dev/js/src/vc/menu.js
@@ -0,0 +1,10 @@
+// Field menu
+define(['menu', 'menu/item'], function (menuClass, itemClass) {
+  return {
+    create : function (params) {
+      return Object.create(menuClass)
+	.upgradeTo(this)
+	._init(itemClass, undefined, params)
+    }
+  };
+});
diff --git a/dev/js/src/vc/operators.js b/dev/js/src/vc/operators.js
new file mode 100644
index 0000000..312f75d
--- /dev/null
+++ b/dev/js/src/vc/operators.js
@@ -0,0 +1,168 @@
+/**
+ * Operators for criteria
+ */
+define(['util'], function () {
+
+  var loc = KorAP.Locale;
+  loc.AND   = loc.AND   || 'and';
+  loc.OR    = loc.OR    || 'or';
+  loc.DEL   = loc.DEL   || '×';
+
+
+  // Utility for analysing boolean values
+  function _bool (bool) {
+    return (bool === undefined || bool === null || bool === false) ? false : true;
+  };
+
+
+  // Add new unspecified document
+  function _add (obj, type) {
+    var ref = obj.parentNode.refTo;
+    var parent = ref.parent();
+
+    if (ref.ldType() === 'docGroup') {
+
+      // Check that the action differs from the type
+      if (ref.operation() === type)
+	return;
+
+      if (parent.ldType() !== null) {
+	return parent.newAfter(ref);
+      }
+      else {
+	// The group is on root - wrap
+	return ref.wrapOnRoot();
+      };
+    }
+    else if (ref.ldType() === 'doc') {
+
+      if (parent.ldType() === null) {
+	return ref.wrapOnRoot(type);
+      }
+      else if (parent.operation() === type) {
+	return parent.newAfter(ref);
+      }
+      else {
+	return ref.wrap(type);
+      };
+    };
+  };
+
+
+  // Add doc with 'and' relation
+  var _and = function () {
+    return _add(this, 'and');
+  };
+
+
+  // Add doc with 'or' relation
+  var _or = function () {
+    return _add(this, 'or');
+  };
+
+
+  // Remove doc or docGroup
+  var _delete = function () {
+    var ref = this.parentNode.refTo;
+    if (ref.parent().ldType() !== null) {
+      return ref.parent().delOperand(ref).update();
+    }
+    else {
+      ref.parent().clean();
+    };
+  };
+
+
+  return {
+    create : function (and, or, del) {
+      var op = Object.create(this);
+      op.and(and);
+      op.or(or);
+      op.del(del);
+      return op;
+    },
+
+    update : function () {
+      // Init the element
+      if (this._element === undefined)
+	return this.element();
+
+      var op = this._element;
+
+      op.refTo = this.parent();
+
+      // Remove everything underneath
+      _removeChildren(op);
+      
+      // Add and button
+      if (this._and === true) {
+	var andE = document.createElement('span');
+	andE.setAttribute('class', 'and');
+	andE.addEventListener('click', _and, false);
+	andE.appendChild(
+	  document.createTextNode(loc.AND)
+	);
+	op.appendChild(andE);
+      };
+
+      // Add or button
+      if (this._or === true) {
+	var orE = document.createElement('span');
+	orE.setAttribute('class', 'or');
+	orE.addEventListener('click', _or, false);
+	orE.appendChild(document.createTextNode(loc.OR));
+	op.appendChild(orE);
+      };
+
+      // Add delete button
+      if (this._del === true) {
+	var delE = document.createElement('span');
+	delE.setAttribute('class', 'delete');
+	delE.appendChild(document.createTextNode(loc.DEL));
+	delE.addEventListener('click', _delete, false);
+	op.appendChild(delE);
+      };
+
+      return op;
+    },
+
+    // Be aware! This may be cyclic
+    parent : function (obj) {
+      if (arguments.length === 1)
+	this._parent = obj;
+      return this._parent;
+    },
+
+    element : function () {
+
+      // Return existing element
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'operators');
+
+      // Init elements
+      this.update();
+      return this._element;
+    },
+
+    and : function (bool) {
+      if (arguments.length === 1)
+	this._and = _bool(bool);
+      return this._and;
+    },
+
+    or : function (bool) {
+      if (arguments.length === 1)
+	this._or = _bool(bool);
+      return this._or;
+    },
+
+    del : function (bool) {
+      if (arguments.length === 1)
+	this._del = _bool(bool);
+      return this._del;
+    }
+  };
+});
diff --git a/dev/js/src/vc/rewrite.js b/dev/js/src/vc/rewrite.js
new file mode 100644
index 0000000..79ba4b3
--- /dev/null
+++ b/dev/js/src/vc/rewrite.js
@@ -0,0 +1,100 @@
+/**
+ * Implementation of rewrite objects.
+ */
+define(['vc/jsonld', 'util'], function (jsonldClass) {
+
+  var _validRewriteOpRE   = new RegExp("^(?:injec|modifica)tion$");
+  var _quote              = new RegExp("([\"\\\\])", 'g');
+
+  return {
+    // Construction method
+    create : function (json) {
+      var obj = Object(jsonldClass).
+	create().
+	upgradeTo(this).
+	fromJson(json);
+      return obj;
+    },
+
+    // Get or set source
+    src : function (string) {
+      if (arguments.length === 1)
+	this._src = string;
+      return this._src;
+    },
+    
+    // Get or set operation
+    operation : function (op) {
+      if (arguments.length === 1) {
+	if (_validRewriteOpRE.test(op)) {
+	  this._op = op;
+	}
+	else {
+	  KorAP.log(814, "Unknown rewrite operation");
+	  return;
+	};
+      };
+      return this._op || 'injection';
+    },
+
+    // Get or set scope
+    scope : function (attr) {
+      if (arguments.length === 1)
+	this._scope = attr;
+      return this._scope;
+    },
+
+    // Serialize from Json
+    fromJson : function (json) {
+      if (json === undefined)
+	return this;
+
+      // Missing @type
+      if (json["@type"] === undefined) {
+	KorAP.log(701, "JSON-LD group has no @type attribute");
+	return;
+      };
+      
+      // Missing source
+      if (json["src"] === undefined ||
+	  typeof json["src"] !== 'string') {
+	KorAP.log(815, "Rewrite expects source");
+	return;
+      };
+
+      // Set source
+      this.src(json["src"]);
+
+      // Set operation
+      if (json["operation"] !== undefined) {
+	var operation = json["operation"];
+	this.operation(operation.replace(/^operation:/,''));
+      };
+
+      // Set scope
+      if (json["scope"] !== undefined &&
+	  typeof json["scope"] === 'string')
+	this.scope(json["scope"]);
+
+      return this;
+    },
+    
+    toString : function () {
+      var str = '';
+      var op = this.operation();
+      str += op.charAt(0).toUpperCase() + op.slice(1);
+      str += ' of ' + (
+	this._scope === null ?
+	  'object' :
+	  '"' +
+	  this.scope().replace(_quote, '\\$1') +
+	  '"'
+      );
+      str += ' by ' +
+	'"' +
+	this.src().replace(_quote, '\\$1') +
+	'"';
+      return str;
+    }
+  };
+});
diff --git a/dev/js/src/vc/rewritelist.js b/dev/js/src/vc/rewritelist.js
new file mode 100644
index 0000000..af3c05a
--- /dev/null
+++ b/dev/js/src/vc/rewritelist.js
@@ -0,0 +1,49 @@
+define(['vc/jsonld', 'vc/rewrite'], function (jsonldClass, rewriteClass) {
+  return {
+    // Construction method
+    create : function (json) {
+      var obj = Object(jsonldClass).
+	create().
+	upgradeTo(this).
+	fromJson(json);
+      return obj;
+    },
+    fromJson : function (json) {
+      this._list = new Array();
+      for (var i = 0; i < json.length; i++) {
+	this._list.push(
+	  rewriteClass.create(json[i])
+	);
+      };
+      return this;
+    },
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'rewrite');
+      for (var x in this._list) {
+	var rewrite = this._list[x];
+	var span = document.createElement('span');
+
+	// Set class attribute
+	span.setAttribute('class', rewrite.operation());
+
+	// Append source information
+	span.appendChild(document.createTextNode(rewrite.src()));
+
+	// Append scope information
+	if (rewrite.scope() !== undefined) {
+	  span.appendChild(
+	    document.createTextNode(
+	      ': ' + rewrite.scope()
+	    )
+	  );
+	};
+	this._element.appendChild(span);
+      };
+      return this._element;
+    }
+  };
+});
diff --git a/dev/js/src/vc/unspecified.js b/dev/js/src/vc/unspecified.js
new file mode 100644
index 0000000..9efd007
--- /dev/null
+++ b/dev/js/src/vc/unspecified.js
@@ -0,0 +1,89 @@
+/**
+ * Unspecified criterion
+ */
+define(['vc/jsonld', 'vc/doc', 'util'], function (jsonldClass, docClass) {
+
+  var loc = KorAP.Locale;
+  loc.EMPTY = loc.EMPTY || '⋯';
+
+  return {
+    _ldType : "non",
+    create : function (parent) {
+      var obj = Object.create(jsonldClass).
+	upgradeTo(this);
+
+      if (parent !== undefined)
+	obj._parent = parent;
+
+      return obj;
+    },
+
+    // Set key - replace
+    key : function (v) {
+
+      // Not replaceable
+      if (this._parent === undefined)
+	return null;
+
+      // Set JSON-LD type
+      var newDoc = docClass.create(this._parent, {
+	"@type" : "koral:doc",
+	"value" : "",
+	"key"   : v
+      });
+
+      // Unspecified document on root
+      if (this._parent.ldType() === null) {
+	this._parent.root(newDoc);
+	this.destroy();
+      }
+
+      // Unspecified document in group
+      else {
+	this._parent.replaceOperand(this, newDoc);
+      };
+      this._parent.update();
+      return newDoc;
+    },
+
+    update : function () {
+
+      if (this._element === undefined)
+	return this.element();
+
+      // Remove element content
+      _removeChildren(this._element);
+
+      var ellipsis = document.createElement('span');
+      ellipsis.appendChild(document.createTextNode(loc.EMPTY));
+      this._element.appendChild(ellipsis);
+
+      // Set ref - TODO: Cleanup!
+      this._element.refTo = this;
+
+      // Set operators
+      if (this._parent !== undefined && this.parent().ldType() !== null) {
+	var op = this.operators(
+	  false,
+	  false,
+	  true
+	);
+	
+	this._element.appendChild(
+	  op.element()
+	);
+      };
+
+      return this.element();
+    },
+
+    element : function () {
+      if (this._element !== undefined)
+	return this._element;
+      this._element = document.createElement('div');
+      this._element.setAttribute('class', 'doc unspecified');
+      this.update();
+      return this._element;
+    },
+  };
+});
