Test suite now relies on requirejs as well
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index beb4bca..d3aee67 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -9,11 +9,9 @@
  * - Scroll to match vertically per default
  */
 define([
-  'match/infolayer',
   'match/info',
   'util'
-], function (infoLayerClass,
-	     infoClass) {
+], function (infoClass) {
 
   // Localization values
   var loc   = KorAP.Locale;
@@ -21,8 +19,6 @@
   loc.SHOWINFO = loc.SHOWINFO || 'Show information';
   loc.CLOSE    = loc.CLOSE    || 'Close';
   
-  // KorAP._AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
-  // KorAP._TermRE      = new RegExp("^(?:([^\/]+?)\/)?([^:]+?):(.+?)$");
   var _matchTerms  = ['corpusID', 'docID', 'textID', 'matchID', 'available'];
 
   /**
@@ -39,6 +35,7 @@
       return Object.create(this)._init(match);
     },
 
+
     /**
      * Initialize match.
      */
@@ -74,16 +71,11 @@
 	// Iterate over allowed match terms
 	for (var i in _matchTerms) {
 	  var term = _matchTerms[i];
-	  if (match[term] !== undefined) {
-	    this[term] = match[term];
-	  }
-	  else {
-	    this[term] = undefined;
-	  }
+	  this[term] = match[term] !== undefined ? match[term] : undefined;
 	};
       };
       
-      this._available = {
+      this._avail = {
 	tokens : [],
 	spans  : [],
 	rels   : []
@@ -95,8 +87,8 @@
 
 	// Create info layer objects
 	try {
-	  var layer = infoLayerClass.create(term);
-	  this._available[layer.type].push(layer);
+	  var layer = require('match/infolayer').create(term);
+	  this._avail[layer.type].push(layer);
 	}
 	catch (e) {
 	  continue;
@@ -111,7 +103,7 @@
      * Return a list of parseable tree annotations.
      */
     getSpans : function () {
-      return this._available.spans;
+      return this._avail.spans;
     },
 
 
@@ -119,7 +111,7 @@
      * Return a list of parseable token annotations.
      */
     getTokens : function () {
-      return this._available.tokens;
+      return this._avail.tokens;
     },
 
 
@@ -127,9 +119,10 @@
      * Return a list of parseable relation annotations.
      */
     getRels : function () {
-      return this._available.rels;
+      return this._avail.rels;
     },
 
+
     /**
      * Open match
      */
@@ -149,13 +142,18 @@
       // Add active class to element
       element.classList.add('active');
 
+      // Already there
+      if (element.classList.contains('action'))
+	return true;
+
       // Create action buttons
       var ul = document.createElement('ul');
       ul.classList.add('action', 'right');
-      element.appendChild(ul);
 
-      // Use localization
-      var loc = KorAP.Locale;
+      element.appendChild(ul);
+      element.classList.add('action');
+
+      // Todo: Open in new frame
 
       // Add close button
       var close = document.createElement('li');
@@ -191,17 +189,16 @@
       return true;
     },
 
+
     /**
      * Close info view
      */
     close : function () {
       this._element.classList.remove('active');
-
-/*
-      if (this._info !== undefined) {
-	this._info.destroy();
-      };
-*/
+      /* if (this._info !== undefined) {
+       *   this._info.destroy();
+       * };
+       */
     },
 
 
@@ -218,7 +215,7 @@
       if (this._element === undefined ||
 	  this._element === null)
 	return this._info;
-
+      
       // Info is already activated
       if (this._info._element !== undefined)
 	return this._info;
@@ -226,14 +223,12 @@
       return this._info;
     },
 
-
+    
     /**
      * Get match element.
      */
     element : function () {
-
-      // May be null
-      return this._element;
+      return this._element; // May be null
     }
   };
 });
diff --git a/dev/js/src/match/info.js b/dev/js/src/match/info.js
index b24bed5..c47f5ae 100644
--- a/dev/js/src/match/info.js
+++ b/dev/js/src/match/info.js
@@ -1,7 +1,16 @@
   /**
    * Information about a match.
    */
-define(['match/infolayer','match/table','match/tree', 'match/treemenu', 'util'], function (infoLayerClass, matchTableClass, matchTreeClass, matchTreeMenuClass) {
+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 () {
diff --git a/dev/js/src/util.js b/dev/js/src/util.js
index d183c36..b3bb423 100644
--- a/dev/js/src/util.js
+++ b/dev/js/src/util.js
@@ -10,6 +10,11 @@
   };
 };
 
+var _quoteRE = new RegExp("([\"\\\\])", 'g');
+String.prototype.quote = function () {
+  return this.replace(_quoteRE, '\\$1');
+};
+
 // Add toggleClass method similar to jquery
 HTMLElement.prototype.toggleClass = function (c1, c2) {
   var cl = this.classList;
diff --git a/dev/js/src/vc.js b/dev/js/src/vc.js
index 48c5694..65ac5ca 100644
--- a/dev/js/src/vc.js
+++ b/dev/js/src/vc.js
@@ -45,14 +45,6 @@
   // 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 || '⋯'
-  */
 
   /**
    * Virtual Collection
@@ -93,7 +85,7 @@
 
       else {
 	// Add unspecified object
-	obj._root = KorAP.UnspecifiedDoc.create(obj);
+	obj._root = unspecDocClass.create(obj);
       };
 
       // Init element and update
diff --git a/dev/js/src/vc/doc.js b/dev/js/src/vc/doc.js
index 61c6439..700f410 100644
--- a/dev/js/src/vc/doc.js
+++ b/dev/js/src/vc/doc.js
@@ -133,7 +133,7 @@
     // Wrap a new operation around the doc element
     wrap : function (op) {
       var parent = this.parent();
-      var group = KorAP.DocGroup.create(parent);
+      var group = require('vc/docgroup').create(parent);
       group.operation(op);
       group.append(this);
       group.append();
@@ -353,7 +353,7 @@
 	return string + '/' + this.value() + '/';
 	break;
       case "string":
-	return string + '"' + this.value().replace(KorAP._quote, '\\$1') + '"';
+	return string + '"' + this.value().quote() + '"';
 	break;
       };
 
diff --git a/dev/js/src/vc/operators.js b/dev/js/src/vc/operators.js
index 312f75d..9b0ebd1 100644
--- a/dev/js/src/vc/operators.js
+++ b/dev/js/src/vc/operators.js
@@ -50,19 +50,19 @@
 
 
   // Add doc with 'and' relation
-  var _and = function () {
+  KorAP._and = function () {
     return _add(this, 'and');
   };
 
 
   // Add doc with 'or' relation
-  var _or = function () {
+  KorAP._or = function () {
     return _add(this, 'or');
   };
 
 
   // Remove doc or docGroup
-  var _delete = function () {
+  KorAP._delete = function () {
     var ref = this.parentNode.refTo;
     if (ref.parent().ldType() !== null) {
       return ref.parent().delOperand(ref).update();
@@ -98,7 +98,7 @@
       if (this._and === true) {
 	var andE = document.createElement('span');
 	andE.setAttribute('class', 'and');
-	andE.addEventListener('click', _and, false);
+	andE.addEventListener('click', KorAP._and, false);
 	andE.appendChild(
 	  document.createTextNode(loc.AND)
 	);
@@ -109,7 +109,7 @@
       if (this._or === true) {
 	var orE = document.createElement('span');
 	orE.setAttribute('class', 'or');
-	orE.addEventListener('click', _or, false);
+	orE.addEventListener('click', KorAP._or, false);
 	orE.appendChild(document.createTextNode(loc.OR));
 	op.appendChild(orE);
       };
@@ -119,7 +119,7 @@
 	var delE = document.createElement('span');
 	delE.setAttribute('class', 'delete');
 	delE.appendChild(document.createTextNode(loc.DEL));
-	delE.addEventListener('click', _delete, false);
+	delE.addEventListener('click', KorAP._delete, false);
 	op.appendChild(delE);
       };
 
diff --git a/dev/js/src/vc/rewrite.js b/dev/js/src/vc/rewrite.js
index 79ba4b3..f0dfe34 100644
--- a/dev/js/src/vc/rewrite.js
+++ b/dev/js/src/vc/rewrite.js
@@ -4,7 +4,6 @@
 define(['vc/jsonld', 'util'], function (jsonldClass) {
 
   var _validRewriteOpRE   = new RegExp("^(?:injec|modifica)tion$");
-  var _quote              = new RegExp("([\"\\\\])", 'g');
 
   return {
     // Construction method
@@ -87,12 +86,12 @@
 	this._scope === null ?
 	  'object' :
 	  '"' +
-	  this.scope().replace(_quote, '\\$1') +
+	  this.scope().quote() +
 	  '"'
       );
       str += ' by ' +
 	'"' +
-	this.src().replace(_quote, '\\$1') +
+	this.src().quote() +
 	'"';
       return str;
     }