- system-set classes use IDs starting at 1024
- Cosmas OPBED serialised using matches-Positions rather than 0-word-distances
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
index ec93a84..5f1b2d8 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
@@ -189,10 +189,20 @@
 	}
 	
 	protected LinkedHashMap<String, Object> makeSpanClass(int classCount) {
+		return makeSpanClass(classCount, true);
+	}
+	
+	protected LinkedHashMap<String, Object> makeSpanClass(int classCount, boolean setBySystem) {
 		LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
 		group.put("@type", "korap:group");
 		group.put("operation", "operation:class");
-		group.put("class", classCount);
+		if (setBySystem) {
+			group.put("class", 1024+classCount);
+			announcements.add("A class has been introduced into the backend representation of " +
+					"your query for later reference to a part of the query. The class id is "+classCount);
+		} else {
+			group.put("class", classCount);
+		}
 		group.put("operands", new ArrayList<Object>());
 		return group;
 	}
@@ -284,7 +294,7 @@
 
 	@SuppressWarnings("unchecked")
 	protected LinkedHashMap<String, Object> wrapInClass(LinkedHashMap<String, Object> group, Integer classId) {
-		LinkedHashMap<String, Object> classGroup = makeSpanClass(classId);
+		LinkedHashMap<String, Object> classGroup = makeSpanClass(classId, true);
 		((ArrayList<Object>) classGroup.get("operands")).add(group);
 		return classGroup;
 	}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java
index e6c2a05..feb6337 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java
@@ -453,9 +453,9 @@
             LinkedHashMap<String, Object> embeddedSequence = group;
             
             if (! (openNodeCats.get(1).equals("OPBEG") || openNodeCats.get(1).equals("OPEND") || openNodeCats.get(1).equals("OPALL") || openNodeCats.get(1).equals("OPNHIT"))) {
-                wrapOperandInClass(node,1,0);
-                wrapOperandInClass(node,2,0);
-                group = wrapInReference(group, 0);
+                wrapOperandInClass(node,1,classCounter);
+                wrapOperandInClass(node,2,classCounter);
+                group = wrapInReference(group, 1024+classCounter++);
             }
             
             LinkedHashMap<String,Object> sequence = null;
@@ -508,7 +508,7 @@
             invertedOperandsLists.push((ArrayList<Object>) posgroup.get("operands"));
             stackedObjects++;
             // Step II: wrap in reference (limit match to first argument) and decide where to put
-            LinkedHashMap<String, Object> submatchgroup = wrapInReference(posgroup, classCounter);
+            LinkedHashMap<String, Object> submatchgroup = wrapInReference(posgroup, 1024+classCounter);
             putIntoSuperObject(submatchgroup, 1);
         }
 
@@ -533,14 +533,14 @@
 
         if (nodeCat.equals("OPNHIT")) {
             ArrayList<Integer> classRef = new ArrayList<Integer>();
-            classRef.add(classCounter);
+            classRef.add(1024+classCounter);
 //            classRef.add(classCounter + 1);  // yes, do this twice (two classes)!
             LinkedHashMap<String, Object> group = makeReference(classRef);
             group.put("classRefOp", "classRefOp:inversion");
             ArrayList<Object> operands = new ArrayList<Object>();
             group.put("operands", operands);
-            wrapOperandInClass(node.getChild(0),1,classCounter); // direct child is OPPROX
-            wrapOperandInClass(node.getChild(0),2,classCounter++);
+            wrapOperandInClass(node.getChild(0),1,1024+classCounter); // direct child is OPPROX
+            wrapOperandInClass(node.getChild(0),2,1024+classCounter++);
             objectStack.push(group);
             stackedObjects++;
             putIntoSuperObject(group, 1);
@@ -576,7 +576,7 @@
             // create a containing group expressing the submatch constraint on the first argument
             ArrayList<Integer> spanRef = new ArrayList<Integer>();
             spanRef.add(1);
-            LinkedHashMap<String, Object> submatchgroup = makeReference(spanRef);
+            LinkedHashMap<String, Object> submatchgroup = makeReference(1024+classCounter);
             ArrayList<Object> submatchoperands = new ArrayList<Object>();
             submatchgroup.put("operands", submatchoperands);
             putIntoSuperObject(submatchgroup);
@@ -611,11 +611,11 @@
                 //     use 'focus' operations to create nested conditions
             } else {
                 // node has several conditions (like 'sa, -pa')
-                // -> create zero-distance sequence group and embed all position groups there
-                LinkedHashMap<String, Object> conjunct = makeGroup("sequence");
-                ArrayList<Object> distances = new ArrayList<Object>();
-                distances.add(makeDistance("w", 0,0));
-                conjunct.put("distances", distances);
+                // -> create identity position group and embed all position groups there
+                LinkedHashMap<String, Object> conjunct = makePosition(new String[]{"frame:matches"}, new String[]{"sharedClasses:equals"});
+//                ArrayList<Object> distances = new ArrayList<Object>();
+//                distances.add(makeDistance("w", 0,0));
+//                conjunct.put("distances", distances);
                 ArrayList<Object> operands = new ArrayList<Object>();
                 conjunct.put("operands", operands);
                 ArrayList<Object> distributedOperands = new ArrayList<Object>();
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java
index 5d136b7..8124abc 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java
@@ -101,6 +101,7 @@
 		if (nodeCat.equals("sequence")) {
 			LinkedHashMap<String,Object> sequence = makeGroup("sequence");
 			ParseTree distanceNode = getFirstChildWithCat(node, "distance");
+			
 			if (distanceNode!=null) {
 				Integer[] minmax = parseDistance(distanceNode);
 				LinkedHashMap<String,Object> distance = makeDistance("w", minmax[0], minmax[1]);
@@ -134,6 +135,18 @@
 			stackedObjects++;
 		}
 		
+		if (nodeCat.equals("emptyTokenSequenceClass")) {
+			Integer[] minmax = parseDistance(node);
+			int classId = 0;
+			if (hasChild(node, "spanclass_id")) {
+				classId = Integer.parseInt(node.getChild(1).getChild(0).toStringTree(parser));
+			}
+			LinkedHashMap<String,Object> classGroup = makeSpanClass(classId, false);
+			putIntoSuperObject(classGroup);
+			objectStack.push(classGroup);
+			stackedObjects++;
+		}
+		
 
 		if (nodeCat.equals("token")) {
 			LinkedHashMap<String,Object> token = makeToken();
@@ -287,7 +300,7 @@
 					classId = 0;
 				}
 			}
-			LinkedHashMap<String, Object> classGroup = makeSpanClass(classId);
+			LinkedHashMap<String, Object> classGroup = makeSpanClass(classId, false);
 			putIntoSuperObject(classGroup);
 			objectStack.push(classGroup);
 			stackedObjects++;
@@ -592,7 +605,8 @@
 	 * @return
 	 */
 	private Integer[] parseDistance(ParseTree distanceNode) {
-		Integer[] minmax = parseEmptySegments(distanceNode.getChild(0));
+		int emptyTokenSeqIndex = getNodeCat(distanceNode).equals("distance") ? 0 : 2; 
+		Integer[] minmax = parseEmptySegments(distanceNode.getChild(emptyTokenSeqIndex));
 		Integer min = minmax[0];
 		Integer max = minmax[1];
 		min++;