diff --git a/public/js/src/vc.js b/public/js/src/vc.js
index 771152d..fe702a7 100644
--- a/public/js/src/vc.js
+++ b/public/js/src/vc.js
@@ -2,6 +2,7 @@
 
 // TODO: Implement a working localization solution!
 // TODO: Support 'update' method to update elements on change
+// TODO: Implement "toQuery"
 
 /*
  * Error codes:
@@ -18,7 +19,6 @@
   813: "Collection type is not supported" (like 713)
 */
 
-
 (function (KorAP) {
   "use strict";
 
@@ -38,6 +38,17 @@
   loc.OR  = loc.OR  || 'or';
   loc.DEL = loc.DEL || '×';
 
+  function _bool (bool) {
+    return (bool === undefined || bool === false) ? false : true;
+  };
+
+  function _removeChildren (node) {
+    // Remove everything underneath
+    while (node.firstChild) {
+      node.removeChild(node.firstChild);
+    };
+  };
+
   KorAP.VirtualCollection = {
     _root : undefined,
     create : function () {
@@ -105,9 +116,7 @@
       var op = this._element;
 
       // Remove everything underneath
-      while (op.firstChild) {
-	op.removeChild(op.firstChild);
-      };
+      _removeChildren(op);
 
       // Add and button
       if (this._and === true) {
@@ -132,7 +141,8 @@
 	delE.appendChild(document.createTextNode(KorAP.Locale.DEL));
 	op.appendChild(delE);
       };
-      return true;
+
+      return op;
     },
     element : function () {
 
@@ -149,17 +159,17 @@
     },
     and : function (bool) {
       if (arguments.length === 1)
-	this._and = (bool === undefined || bool === false) ? false : true;
+	this._and = _bool(bool);
       return this._and;
     },
     or : function (bool) {
       if (arguments.length === 1)
-	this._or = (bool === undefined || bool === false) ? false : true;
+	this._or = _bool(bool);
       return this._or;
     },
     del : function (bool) {
       if (arguments.length === 1)
-	this._del = (bool === undefined || bool === false) ? false : true;
+	this._del = _bool(bool);
       return this._del;
     }
   };
@@ -169,17 +179,46 @@
    * Unspecified criterion
    */
   KorAP.UnspecifiedDoc = {
+    _ldType : "doc",
     create : function (parent) {
       var obj = Object.create(KorAP.JsonLD).upgradeTo(KorAP.UnspecifiedDoc);
       if (parent !== undefined)
 	obj._parent = parent;
       return obj;
     },
+    update : function () {
+      if (this._element === undefined)
+	return this.element();
+
+      _removeChildren(this._element);
+
+      var ellipsis = document.createElement('span');
+      ellipsis.appendChild(document.createTextNode('⋯'));
+      this._element.appendChild(ellipsis);
+
+      // Set operators
+      var op = this.operators(
+	false,
+	false,
+	// No delete object, if this is the root
+	this._parent !== undefined ? true : false
+      );
+
+      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', 'undefined');
+      this._element.setAttribute('class', 'unspecified');
+
+      this.update();
       return this._element;
     }
   };
@@ -198,13 +237,9 @@
 	obj._parent = parent;
       return obj;
     },
-    element : function () {
-      if (this._element !== undefined)
-	return this._element;
-
-      this._element = document.createElement('div');
-      var e = this._element;
-      e.setAttribute('class', 'doc');
+    update : function () {
+      if (this._element === undefined)
+	return this.element();
 
       // Added key
       var key = document.createElement('span');
@@ -225,18 +260,37 @@
       if (this.value())
 	value.appendChild(document.createTextNode(this.value()));
 
+      var e = this._element;
+
       // Add spans
       e.appendChild(key);
       e.appendChild(matchop);
       e.appendChild(value);
+
+      // Set operators
+      var op = this.operators(true, true, true);
+
+      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 group = KorAP.DocGroup.create(undefined);
-      group.appendOperand(this);
-      group.appendOperand(null);
+      group.append(this);
+      group.append(null);
       this.parent(group);
 /*
       var div = document.createElement('div');
@@ -398,16 +452,30 @@
 	obj._parent = parent;
       return obj;
     },
-    appendOperand : function (operand) {
+    append : function (operand) {
+
+      // Append unspecified object
+      if (operand === undefined) {
+
+	// Be aware of cyclic structures!
+	operand = KorAP.UnspecifiedDoc.create(this);
+	this._operands.push(operand);
+	this.update();
+	return operand;
+      };
+
       switch (operand["@type"]) {
       case undefined:
 	if (operand["ldType"] !== undefined) {
 	  if (operand.ldType() !== 'doc' &&
-		   operand.ldType() !== 'docGroup') {
+	      operand.ldType() !== 'docGroup') {
 	    KorAP.log(812, "Operand not supported in document group");
 	    return;
 	  };
+	  // Be aware of cyclic structures!
+	  operand.parent(this);
 	  this._operands.push(operand);
+	  this.update();
 	  return operand;
 	};
 
@@ -415,17 +483,21 @@
 	return;
 
       case "korap:doc":
-	var doc = KorAP.Doc.create().fromJson(operand);
+	// Be aware of cyclic structures!
+	var doc = KorAP.Doc.create(this, operand);
 	if (doc === undefined)
 	  return;
 	this._operands.push(doc);
+	this.update();
 	return doc;
 
       case "korap:docGroup":
-	var docGroup = KorAP.DocGroup.create().fromJson(operand);
+	// Be aware of cyclic structures!
+	var docGroup = KorAP.DocGroup.create(this, operand);
 	if (docGroup === undefined)
 	  return;
 	this._operands.push(docGroup);
+	this.update();
 	return docGroup;
 
       default:
@@ -433,19 +505,43 @@
 	return;
       };
     },
+    update : function () {
+      if (this._element === undefined)
+	return this.element();
+
+      var op = this._element;
+      op.setAttribute('data-operation', this.operation());
+
+      _removeChildren(op);
+
+      // Append operands
+      for (var i in this.operands()) {
+	op.appendChild(
+	  this.getOperand(i).element()
+	);
+      };
+
+      // Set operators
+      var op = this.operators(
+	this.operation() == 'and' ? false : true,
+	this.operation() == 'or'  ? false : true,
+	true
+      );
+
+      this._element.appendChild(
+	op.element()
+      );
+
+      return op;
+    },
     element : function () {
       if (this._element !== undefined)
 	return this._element;
 
       this._element = document.createElement('div');
       this._element.setAttribute('class', 'docGroup');
-      this._element.setAttribute('data-operation', this.operation());
 
-      for (var i in this.operands()) {
-	this._element.appendChild(
-	  this.getOperand(i).element()
-	);
-      };
+      this.update();
 
       return this._element;
     },
@@ -497,7 +593,7 @@
       // Add all documents
       for (var i in json["operands"]) {
 	var operand = json["operands"][i];
-	this.appendOperand(operand);
+	this.append(operand);
       };
     
       return this;
@@ -541,6 +637,20 @@
       if (arguments.length === 1)
 	this._parent = obj;
       return this._parent;
+    },
+    operators : function (and, or, del) {
+      if (arguments === 0)
+	return this._ops;
+      this._ops = KorAP.Operators.create(
+	and, or, del
+      );
+      return this._ops;
+    },
+    toJson : function () {
+      return {
+	// Unspecified object
+	"@type" : "korap:" + this.ldType()
+      };
     }
   };
  
