focus cosmas sequences to explicit tokens (operands)
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 d5b36d4..db3c51e 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
@@ -1,6 +1,7 @@
 package de.ids_mannheim.korap.query.serialize;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -142,6 +143,17 @@
 		return group;
 	}
 	
+	protected LinkedHashMap<String, Object> makePosition(String[] allowedPositions, String[] disallowedPositions, String[] sharedClasses) {
+		LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+		group.put("@type", "korap:group");
+		group.put("operation", "operation:position");
+		group.put("allowed", Arrays.asList(allowedPositions));
+		group.put("disallowed", Arrays.asList(disallowedPositions));
+		group.put("sharedClasses", Arrays.asList(sharedClasses));
+		group.put("operands", new ArrayList<Object>());
+		return group;
+	}
+	
 	protected LinkedHashMap<String, Object> makeSpanClass(int classCount) {
 		LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
 		group.put("@type", "korap:group");
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 9d0adb8..aa1abda 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
@@ -12,6 +12,10 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+import com.google.common.collect.TreeBasedTable;
+
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -47,8 +51,10 @@
      */
     int classCounter = 1;
     boolean negate = false;
-    int wrapFirstOpInClass = -1;
-    int wrapSecondOpInClass = -1;
+//    int wrapFirstOpInClass = -1;
+//    int wrapSecondOpInClass = -1;
+    
+    Table<Tree,Integer,Integer> operandWrap = HashBasedTable.create();
 
     /**
      * Keeps track of all visited nodes in a tree
@@ -442,11 +448,21 @@
                 }
             }
             group.put("inOrder", inOrder);
+            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"))) {
+//            	wrapFirstOpInClass = 0;
+//                wrapSecondOpInClass = 0;
+                wrapOperandInClass(node,1,0);
+                wrapOperandInClass(node,2,0);
+                group = wrapInReference(group, 0);
+            }
+            
             
 //            ArrayList<ArrayList<Object>> distributedOperands = new ArrayList<ArrayList<Object>>();
             LinkedHashMap<String,Object> sequence = null;
             if (putIntoOverlapDisjunction) {
-            	sequence = group;
+            	sequence = embeddedSequence;
             	group = makeGroup("or");
             	ArrayList<Object> disjOperands = (ArrayList<Object>) group.get("operands");
             	LinkedHashMap<String,Object> overlapsGroup = makePosition("overlaps");
@@ -456,7 +472,7 @@
             	sequence.put("operands", overlapsOperands);
             	if (invertedOperands) invertedOperandsLists.push(overlapsOperands);
             	disjOperands.add(overlapsGroup);
-            	disjOperands.add(sequence);
+            	disjOperands.add(wrapInReference(sequence, 0));
             	// Step II: decide where to put
             	putIntoSuperObject(group, 0);
             	objectStack.push(sequence);
@@ -464,7 +480,7 @@
             else {
             	// Step II: decide where to put
             	putIntoSuperObject(group, 0);
-            	objectStack.push(group);
+            	objectStack.push(embeddedSequence);
             }
             stackedObjects++;
             visited.add(node.getChild(0));
@@ -473,7 +489,8 @@
         // inlcusion or overlap
         if (nodeCat.equals("OPIN") || nodeCat.equals("OPOV")) {
             // Step I: create group
-        	wrapFirstOpInClass = classCounter;
+//        	wrapFirstOpInClass = classCounter;
+        	wrapOperandInClass(node,1,classCounter);
             LinkedHashMap<String, Object> posgroup = makePosition(null);
             if (nodeCat.equals("OPIN")) {
                 posgroup = parseOPINOptions(node, posgroup);
@@ -489,33 +506,48 @@
             putIntoSuperObject(submatchgroup, 1);
         }
 
-        // Wrap the first argument of an #IN operator in a class group
-        if (nodeCat.equals("ARG1"))  {
-    		if (wrapFirstOpInClass > -1) {        		
-        		// Step I: create group
-    			System.err.println("1st op: "+wrapFirstOpInClass);
-                LinkedHashMap<String, Object> classGroup = makeSpanClass(wrapFirstOpInClass);
-                objectStack.push(classGroup);
-                stackedObjects++;
-                // Step II: decide where to put
-                putIntoSuperObject(classGroup, 1);
-                wrapFirstOpInClass = -1;
-        	}
+        // Wrap the argument of an #IN operator in a class group
+        if (nodeCat.equals("ARG1") || nodeCat.equals("ARG2"))  {
+        	Tree parent = node.getParent();
+        	String child = getNodeCat(node.getChild(0));
+//        	if (child.equals("OPWF") | child.equals("OPLEM") | child.equals("OPELEM") | child.equals("OPMOPRH") | child.equals("OPLABEL")) {
+//        		if (wrapFirstOpInClass > -1) {        		
+        		if (operandWrap.containsRow(parent)) {
+            		// Step I: create group
+        			int argNr = nodeCat.equals("ARG1") ? 1 : 2;
+        			try {
+        				int cls = operandWrap.row(parent).get(argNr);
+            			System.err.println("1st op: "+cls);
+                        LinkedHashMap<String, Object> classGroup = makeSpanClass(cls);
+                        objectStack.push(classGroup);
+                        stackedObjects++;
+                        // Step II: decide where to put
+                        putIntoSuperObject(classGroup, 1);
+        			} catch (NullPointerException npe) {
+        				// do nothing, this just means the argument shall not be wrapped
+        				if (verbose) System.out.println("No class for argument "+argNr);
+        			}
+            	}
+//        	}
+//        	wrapFirstOpInClass = -1;
         }
 
-        // Wrap the 2nd argument of an #IN operator embedded in NHIT in a class group
-        if (nodeCat.equals("ARG2")) {
-        	if (wrapSecondOpInClass > -1) {
-        		System.err.println("2nd op: "+wrapSecondOpInClass);
-        		// Step I: create group
-                LinkedHashMap<String, Object> classGroup = makeSpanClass(wrapSecondOpInClass);
-                objectStack.push(classGroup);
-                stackedObjects++;
-                // Step II: decide where to put
-                putIntoSuperObject(classGroup, 1);
-                wrapSecondOpInClass = -1;
-        	}
-        }
+//        // Wrap the 2nd argument of an #IN operator embedded in NHIT in a class group
+//        if (nodeCat.equals("ARG2")) {
+//        	String child = getNodeCat(node.getChild(0));
+//        	if (child.equals("OPWF") | child.equals("OPLEM") | child.equals("OPELEM") | child.equals("OPMOPRH") | child.equals("OPLABEL")) {
+//	        	if (wrapSecondOpInClass > -1) {
+//	        		System.err.println("2nd op: "+wrapSecondOpInClass);
+//	        		// Step I: create group
+//	                LinkedHashMap<String, Object> classGroup = makeSpanClass(wrapSecondOpInClass);
+//	                objectStack.push(classGroup);
+//	                stackedObjects++;
+//	                // Step II: decide where to put
+//	                putIntoSuperObject(classGroup, 1);
+//	        	}
+//        	}
+//        	wrapSecondOpInClass = -1;
+//        }
 
 
         if (nodeCat.equals("OPNHIT")) {
@@ -527,8 +559,10 @@
             ArrayList<Object> operands = new ArrayList<Object>();
             exclGroup.put("operands", operands);
             System.err.println(classCounter);
-            wrapFirstOpInClass = classCounter++;
-            wrapSecondOpInClass = classCounter++;
+            wrapOperandInClass(node,1,classCounter++);
+            wrapOperandInClass(node,2,classCounter++);
+//            wrapFirstOpInClass = classCounter++;
+//            wrapSecondOpInClass = classCounter++;
             objectStack.push(exclGroup);
             stackedObjects++;
             putIntoSuperObject(exclGroup, 1);
@@ -678,7 +712,12 @@
         openNodeCats.pop();
     }
 
-    private void processSpanDistance(String meas, int parseInt, int parseInt2) {
+    private void wrapOperandInClass(Tree node, int arg, int cls) {
+		operandWrap.put(node, arg, cls);
+		
+	}
+
+	private void processSpanDistance(String meas, int parseInt, int parseInt2) {
 		// TODO Auto-generated method stub
 		
 	}
@@ -736,7 +775,8 @@
         	outerFocus.put("operands", new ArrayList<Object>());
         	toWrapStack.push(new LinkedHashMap[]{posgroup, innerFocus, noMatchPosition, outerFocus});
         	stackedToWrap++;
-        	wrapSecondOpInClass = classCounter+1;
+//        	wrapSecondOpInClass = classCounter+1;
+        	wrapOperandInClass(node,2,classCounter+1);
         }
         
         if (posOption != null && (posOption.equals("F") || posOption.equals("FI")) && !negatePosition) {
@@ -748,8 +788,10 @@
         	outerFocus.put("operands", new ArrayList<Object>());
         	toWrapStack.push(new LinkedHashMap[]{posgroup, innerFocus, endsWithPosition, outerFocus});
         	stackedToWrap++;
-        	wrapFirstOpInClass = classCounter;
-        	wrapSecondOpInClass = ++classCounter;
+        	wrapOperandInClass(node,1,classCounter);
+        	wrapOperandInClass(node,2,++classCounter);
+//        	wrapFirstOpInClass = classCounter;
+//        	wrapSecondOpInClass = ++classCounter;
         }
         
         
@@ -818,8 +860,10 @@
         	
         	toWrapStack.push(toWrap);
         	stackedToWrap++;
-        	wrapFirstOpInClass = classCounter+1;
-        	wrapSecondOpInClass = classCounter;
+        	wrapOperandInClass(node,1,classCounter+1);
+        	wrapOperandInClass(node,2,classCounter);
+//        	wrapFirstOpInClass = classCounter+1;
+//        	wrapSecondOpInClass = classCounter;
         }
         
         if (groupnode != null) {
@@ -862,8 +906,10 @@
 
     		toWrapStack.push(toWrap);
     		stackedToWrap++;
-    		wrapFirstOpInClass = classCounter+1;
-    		wrapSecondOpInClass = classCounter;
+//    		wrapOperandInClass(node,1,classCounter+1);
+//    		wrapOperandInClass(node,2,classCounter);
+//    		wrapFirstOpInClass = classCounter+1;
+//    		wrapSecondOpInClass = classCounter;
     	}
     	
     	return posgroup;
@@ -992,7 +1038,9 @@
 //                "#BEG(der /w3:5 Mann) /+w10 kommt",
 //                "Sonne /s0 Mond"
 //                "Sonne /+w4 Mond",
-                "#BED(der Mann , sa,-pa)"
+//                "#BED(der Mann , sa,-pa)",
+                "kommt /+w10 #BEG(der /w3:5 Mann) ",
+//                "wegen #OV(F) <s>"
                 
         };
 		CosmasTree.verbose=true;
diff --git a/src/test/java/CosmasTreeTest.java b/src/test/java/CosmasTreeTest.java
index ef5ed71..fe9a7dc 100644
--- a/src/test/java/CosmasTreeTest.java
+++ b/src/test/java/CosmasTreeTest.java
@@ -210,49 +210,67 @@
 	public void testOPPROX() throws QueryException {
 		query="Sonne /+w1:4 Mond";
 		String prox1 = 
-					"{@type=korap:group, operation=operation:sequence, " +
-						"operands=[" +
-							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
-							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
-						"], inOrder=true, " +
-						"distances=[" +
-							"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
-						"]" +
-					"}";
+					"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+						"{@type=korap:group, operation=operation:sequence, " +
+							"operands=[" +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+								"]}," +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+									"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+								"]}" +
+							"], inOrder=true, " +
+							"distances=[" +
+								"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
+							"]" +
+						"}" +
+					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(prox1.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query="Sonne /+w1:4,s0,p1:3 Mond";
 		String prox2 = 
+				"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 					"{@type=korap:group, operation=operation:sequence, " +
 						"operands=[" +
-							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
-							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+								"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+							"]}," +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+								"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+							"]}" +
 						"], inOrder=true, " +
 						"distances=[" +
 							"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}," +
 							"{@type=korap:distance, key=s, boundary={@type=korap:boundary, min=0, max=0}, min=0, max=0}," +
 							"{@type=korap:distance, key=p, boundary={@type=korap:boundary, min=1, max=3}, min=1, max=3}" +
 						"]" +
-					"}";
+					"}" +
+				"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(prox2.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query="Sonne %+w1:4,s0,p1:3 Mond";
 		String prox3 = 
-				"{@type=korap:group, operation=operation:sequence, " +
+				"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+					"{@type=korap:group, operation=operation:sequence, " +
 						"operands=[" +
-							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
-							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+								"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+							"]}," +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+								"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+							"]}" +
 						"], inOrder=true, " +
 						"distances=[" +
 							"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4, exclude=true}," +
 							"{@type=korap:distance, key=s, boundary={@type=korap:boundary, min=0, max=0}, min=0, max=0, exclude=true}," +
 							"{@type=korap:distance, key=p, boundary={@type=korap:boundary, min=1, max=3}, min=1, max=3, exclude=true}" +
 						"]" +
-					"}";
+					"}" +
+				"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 //		assertEquals(prox3.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -261,18 +279,28 @@
 		String prox4 = 
 					"{@type=korap:group, operation=operation:or, operands=[" +
 						"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
-							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
-							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
-						"]}," +
-						"{@type=korap:group, operation=operation:sequence, " +
-							"operands=[" +
-								"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+								"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+							"]}," +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
 								"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
-							"], inOrder=true, " +
-							"distances=[" +
-								"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
-							"]" +
-						"}" +
+							"]}" +
+						"]}," +
+						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+							"{@type=korap:group, operation=operation:sequence, " +
+								"operands=[" +
+									"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+										"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+									"]}," +
+									"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+										"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+									"]}" +
+								"], inOrder=true, " +
+								"distances=[" +
+									"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
+								"]" +
+							"}" +
+						"]}" +
 					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -281,20 +309,30 @@
 		query="Sonne /-w4 Mond";
 		String prox5 = 
 				"{@type=korap:group, operation=operation:or, operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
-							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}," +
-							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+					"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
+						"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
 						"]}," +
+						"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+						"]}" +
+					"]}," +
+					"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 						"{@type=korap:group, operation=operation:sequence, " +
 							"operands=[" +
-								"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}," +
-								"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+									"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+								"]}," +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+									"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+								"]}" +
 							"], inOrder=true, " +
 							"distances=[" +
 								"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
 							"]" +
 						"}" +
-					"]}";
+					"]}" +
+				"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(prox5.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -302,20 +340,30 @@
 		query="Sonne /w4 Mond";
 		String prox6 = 
 				"{@type=korap:group, operation=operation:or, operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
-							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
-							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+					"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
+						"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
 						"]}," +
+						"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+							"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+						"]}" +
+					"]}," +
+					"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 						"{@type=korap:group, operation=operation:sequence, " +
 							"operands=[" +
-								"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
-								"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+									"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+								"]}," +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+									"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+								"]}" +
 							"], inOrder=false, " +
 							"distances=[" +
 								"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
 							"]" +
 						"}" +
-					"]}";
+					"]}" +
+				"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(prox6.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -328,36 +376,71 @@
 		String mondsterne = 
 					"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}," +
 					"{@type=korap:token, wrap={@type=korap:term, key=Sterne, layer=orth, match=match:eq}}" ;
+		
+		String mondsterneClasses = 
+					"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+						"{@type=korap:token, wrap={@type=korap:term, key=Mond, layer=orth, match=match:eq}}" +
+					"]}," +
+					"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+						"{@type=korap:token, wrap={@type=korap:term, key=Sterne, layer=orth, match=match:eq}}" +
+					"]}";
 		String mondsterneSeq = 
 					"{@type=korap:group, operation=operation:sequence, operands=[" +
 						mondsterne +
 					"], inOrder=true, distances=[" +
 						"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=2}, min=1, max=2}" +
 					"]}" ;
+		String mondsterneClassesSeq = 
+				"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+					"{@type=korap:group, operation=operation:sequence, operands=[" +
+						mondsterneClasses +
+					"], inOrder=true, distances=[" +
+						"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=2}, min=1, max=2}" +
+					"]}" +
+				"]}" ;
 		String mondsterneOv =
 					"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
 						mondsterne +
 					"]}";
+		String mondsterneClassesOv =
+				"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
+					mondsterneClasses +
+				"]}";
 		String mondsterneAll =
 					"{@type=korap:group, operation=operation:or, operands=[" +
-						mondsterneOv + "," + mondsterneSeq +
+						mondsterneOv + "," + mondsterneClassesSeq +
 					"]}";
-
+		String mondsterneAllClasses = 
+					"{@type=korap:group, operation=operation:or, operands=[" +
+						mondsterneClassesOv + "," + mondsterneClassesSeq +
+					"]}";
+		
+		
 		String prox6 = 
 			"{@type=korap:group, operation=operation:or, operands=[" +
 				"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
-					mondsterneAll + "," +
-					"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
-				"]}," +
-				"{@type=korap:group, operation=operation:sequence, " +
-					"operands=[" +
-						mondsterneAll + "," +
+					"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+						mondsterneAllClasses  + 
+					"]}," +
+					"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
 						"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
-					"], inOrder=true, " +
-					"distances=[" +
-						"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
-					"]" +
-				"}" +
+					"]}" +
+				"]}," +
+				"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+					"{@type=korap:group, operation=operation:sequence, " +
+						"operands=[" +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +	
+								mondsterneAllClasses  + 
+							"]}," +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}" +
+							"]}" +
+						"], inOrder=true, " +
+						"distances=[" +
+							"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=4}, min=1, max=4}" +
+						"]" +
+					"}" +
+				"]}" +
 			"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -632,32 +715,53 @@
 		assertEquals(beg1.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		
-		String dermannSeq = "{@type=korap:group, operation=operation:sequence," +
-								"operands = [" +
-									"{@type=korap:token, wrap={@type=korap:term, key=der, layer=orth, match=match:eq}}," +
-									"{@type=korap:token, wrap={@type=korap:term, key=Mann, layer=orth, match=match:eq}}" +
-								"], inOrder=false, distances=[" +
-									"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=3, max=5}, min=3, max=5}" +
-								"]}";
-		String begDermannSeq = "{@type=korap:reference, operation=operation:focus, spanRef=[0,1], operands=[" +
-								dermannSeq +
-							"]}";
+//		String dermannSeq = "{@type=korap:group, operation=operation:sequence," +
+//								"operands = [" +
+//									"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+//										"{@type=korap:token, wrap={@type=korap:term, key=der, layer=orth, match=match:eq}}" +
+//									"]}," +
+//									"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+//										"{@type=korap:token, wrap={@type=korap:term, key=Mann, layer=orth, match=match:eq}}" +
+//									"]}" +
+//									
+//								"], inOrder=false, distances=[" +
+//									"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=3, max=5}, min=3, max=5}" +
+//								"]}";
+//		
+//		String begDermannSeq = 
+////							"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+//								"{@type=korap:reference, operation=operation:focus, spanRef=[0,1], operands=[" +
+//									dermannSeq +
+//								"]}" +
+////							"]}" +
+//							"";
+		
 		String kommt = "{@type=korap:token, wrap={@type=korap:term, key=kommt, layer=orth, match=match:eq}}";
 		
 		query="#BEG(der /w3:5 Mann) /+w10 kommt"; // nesting #BEG() in a distance group
 		String beg2 = 
-				"{@type=korap:group, operation=operation:or, operands=[" +
+					"{@type=korap:group, operation=operation:or, operands=[" +
 						"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
-							begDermannSeq + "," +
-							kommt +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								beg1 +
+							"]}" + "," +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								kommt +
+							"]}" +
 						"]}," +
-						"{@type=korap:group, operation=operation:sequence, operands=[" +
-							begDermannSeq + "," +
-							kommt +
-						"], inOrder=true, distances=[" +
-							"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=10}, min=1, max=10}" +
+						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+							"{@type=korap:group, operation=operation:sequence, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									beg1 + 
+								"]}," +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									kommt +
+								"]}" +
+							"], inOrder=true, distances=[" +
+								"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=10}, min=1, max=10}" +
+							"]}" +
 						"]}" +
-				"]}";
+					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(beg2.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -666,16 +770,27 @@
 		String beg3 = 
 				"{@type=korap:group, operation=operation:or, operands=[" +
 						"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
-							kommt + "," +
-							begDermannSeq +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								kommt + 
+//							"," +
+							"]}," +
+							"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								beg1+
+							"]}" +
 						"]}," +
-						"{@type=korap:group, operation=operation:sequence, operands=[" +
-							kommt + "," +
-							begDermannSeq +
-						"], inOrder=true, distances=[" +
-							"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=10}, min=1, max=10}" +
+						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
+							"{@type=korap:group, operation=operation:sequence, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									kommt +
+								"]}," +
+								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									beg1+
+								"]}" +
+							"], inOrder=true, distances=[" +
+								"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=10}, min=1, max=10}" +
+							"]}" +
 						"]}" +
-				"]}";
+					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(beg3.replaceAll(" ", ""), map.replaceAll(" ", ""));