Major change:
- positions as allowed frames plus shared classes between operands
- inversion classRef operation to support NHIT operator
- 'reset' attribute for references
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 db3c51e..02fa6f0 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
@@ -134,6 +134,7 @@
 		return group;
 	}
 	
+	@Deprecated
 	protected LinkedHashMap<String, Object> makePosition(String frame) {
 		LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
 		group.put("@type", "korap:group");
@@ -143,12 +144,11 @@
 		return group;
 	}
 	
-	protected LinkedHashMap<String, Object> makePosition(String[] allowedPositions, String[] disallowedPositions, String[] sharedClasses) {
+	protected LinkedHashMap<String, Object> makePosition(String[] allowedFrames, 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("frames", Arrays.asList(allowedFrames));
 		group.put("sharedClasses", Arrays.asList(sharedClasses));
 		group.put("operands", new ArrayList<Object>());
 		return group;
@@ -226,6 +226,15 @@
 		return makeReference(classRefs, "focus");
 	}
 	
+	protected LinkedHashMap<String, Object> makeResetReference() {
+		LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+		group.put("@type", "korap:reference");
+		group.put("operation", "operation:focus");
+		group.put("reset", true);
+		group.put("operands", new ArrayList<Object>());
+		return group;
+	}
+	
 	protected void addOperandsToGroup(LinkedHashMap<String, Object> group) {
 		ArrayList<Object> operands = new ArrayList<Object>();
 		group.put("operands", operands);
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 aa1abda..1a239da 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
@@ -54,7 +54,7 @@
 //    int wrapFirstOpInClass = -1;
 //    int wrapSecondOpInClass = -1;
     
-    Table<Tree,Integer,Integer> operandWrap = HashBasedTable.create();
+    Table<Tree,Integer,LinkedHashMap<String,Object>> operandWrap = HashBasedTable.create();
 
     /**
      * Keeps track of all visited nodes in a tree
@@ -451,15 +451,11 @@
             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 = embeddedSequence;
@@ -489,83 +485,56 @@
         // inlcusion or overlap
         if (nodeCat.equals("OPIN") || nodeCat.equals("OPOV")) {
             // Step I: create group
-//        	wrapFirstOpInClass = classCounter;
         	wrapOperandInClass(node,1,classCounter);
-            LinkedHashMap<String, Object> posgroup = makePosition(null);
+//            LinkedHashMap<String, Object> posgroup = makePosition(null);
+            LinkedHashMap<String, Object> posgroup = makeGroup("position");
+//            posgroup
             if (nodeCat.equals("OPIN")) {
                 posgroup = parseOPINOptions(node, posgroup);
             } else {
             	posgroup = parseOPOVOptions(node, posgroup);
             }
             objectStack.push(posgroup);
-            // mark this an inverted list
+            // mark this an inverted operands object
             invertedOperandsLists.push((ArrayList<Object>) posgroup.get("operands"));
             stackedObjects++;
-            // Step II: wrap in reference and decide where to put
+            // Step II: wrap in reference (limit match to first argument) and decide where to put
             LinkedHashMap<String, Object> submatchgroup = wrapInReference(posgroup, classCounter);
             putIntoSuperObject(submatchgroup, 1);
         }
 
-        // Wrap the argument of an #IN operator in a class group
+        // Wrap the argument of an #IN operator in a previously defined container
         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);
-        			}
-            	}
+    		if (operandWrap.containsRow(parent)) {
+        		// Step I: create group
+    			int argNr = nodeCat.equals("ARG1") ? 1 : 2;
+				LinkedHashMap<String,Object> container = operandWrap.row(parent).get(argNr);
+				// Step II: ingest
+				if (container!=null) {
+					objectStack.push(container);
+                    stackedObjects++;
+                    putIntoSuperObject(container,1);
+    			}
+        	}
 //        	}
-//        	wrapFirstOpInClass = -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")) {
             ArrayList<Integer> classRef = new ArrayList<Integer>();
             classRef.add(classCounter);
-            classRef.add(classCounter + 1);  // yes, do this twice (two classes)!
-            LinkedHashMap<String, Object> exclGroup = makeReference(classRef);
-            exclGroup.put("classRefOp", "classRefOp:intersection");
+//            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>();
-            exclGroup.put("operands", operands);
-            System.err.println(classCounter);
-            wrapOperandInClass(node,1,classCounter++);
-            wrapOperandInClass(node,2,classCounter++);
-//            wrapFirstOpInClass = classCounter++;
-//            wrapSecondOpInClass = classCounter++;
-            objectStack.push(exclGroup);
+            group.put("operands", operands);
+            wrapOperandInClass(node.getChild(0),1,classCounter); // direct child is OPPROX
+            wrapOperandInClass(node.getChild(0),2,classCounter++);
+            objectStack.push(group);
             stackedObjects++;
-            putIntoSuperObject(exclGroup, 1);
+            putIntoSuperObject(group, 1);
         }
 
         if (nodeCat.equals("OPEND") || nodeCat.equals("OPBEG")) {
@@ -713,10 +682,14 @@
     }
 
     private void wrapOperandInClass(Tree node, int arg, int cls) {
-		operandWrap.put(node, arg, cls);
-		
+    	LinkedHashMap<String,Object> clsGroup = makeSpanClass(cls);
+		wrapOperand(node,arg,clsGroup);
 	}
 
+    private void wrapOperand(Tree node, int arg, LinkedHashMap<String, Object> container) {
+    	operandWrap.put(node, arg, container);
+  	}
+    
 	private void processSpanDistance(String meas, int parseInt, int parseInt2) {
 		// TODO Auto-generated method stub
 		
@@ -745,19 +718,43 @@
         Tree groupnode = getFirstChildWithCat(node, "GROUP");
         boolean negatePosition = false;
 
-        String position = "";
+        ArrayList<String> positions = new ArrayList<String>();
+        ArrayList<String> sharedClasses = new ArrayList<String>();
         String posOption = null; 
         if (posnode != null) {
             posOption = posnode.getChild(0).toStringTree();
-            position = translateTextAreaArgument(posOption, "in");
-            if (posOption.equals("N")) {
-                negatePosition = !negatePosition;
+            switch (posOption) {
+            case "L":
+                positions.add("startswith");
+                sharedClasses.add("includes");
+                break;
+            case "R":
+            	positions.add("endswith");
+                sharedClasses.add("includes");
+                break;
+            case "F":
+            	positions.add("matches");
+                sharedClasses.add("includes");
+                break;
+            case "FE":
+            	positions.add("matches");
+                sharedClasses.add("equals");
+                break;
+            case "FI":
+            	positions.add("matches");
+            	sharedClasses.add("unequals");
+                sharedClasses.add("includes");
+                break;
+            case "N": 
+            	positions.add("contains");
+                sharedClasses.add("includes");
+                break;
             }
         } else {
-            position = "contains";
+        	sharedClasses.add("includes");
         }
-        posgroup.put("frame", "frame:" + position);
-//      position = openNodeCats.get(1).equals("OPIN") ? "contains" : "full";
+        posgroup.put("frames", positions);
+        posgroup.put("sharedClasses", sharedClasses);
         
         if (exclnode != null) {
             if (exclnode.getChild(0).toStringTree().equals("YES")) {
@@ -765,39 +762,13 @@
             }
         }
         
-        if (posOption != null && (posOption.equals("L") || posOption.equals("R")) && !negatePosition) {
-        	LinkedHashMap<String, Object> noMatchPosition = makePosition("matches");
-        	((ArrayList<Object>) noMatchPosition.get("operands")).add(makeReference(classCounter+1));
-        	noMatchPosition.put("exclude", true);
-        	LinkedHashMap<String,Object> innerFocus = makeReference(classCounter);
-        	innerFocus.put("operands", new ArrayList<Object>());
-        	LinkedHashMap<String,Object> outerFocus = makeReference(classCounter);
-        	outerFocus.put("operands", new ArrayList<Object>());
-        	toWrapStack.push(new LinkedHashMap[]{posgroup, innerFocus, noMatchPosition, outerFocus});
-        	stackedToWrap++;
-//        	wrapSecondOpInClass = classCounter+1;
-        	wrapOperandInClass(node,2,classCounter+1);
-        }
-        
-        if (posOption != null && (posOption.equals("F") || posOption.equals("FI")) && !negatePosition) {
-        	LinkedHashMap<String, Object> endsWithPosition = makePosition("endswith");
-        	((ArrayList<Object>) endsWithPosition.get("operands")).add(makeReference(classCounter+1));
-        	LinkedHashMap<String,Object> innerFocus = makeReference(classCounter);
-        	innerFocus.put("operands", new ArrayList<Object>());
-        	LinkedHashMap<String,Object> outerFocus = makeReference(classCounter);
-        	outerFocus.put("operands", new ArrayList<Object>());
-        	toWrapStack.push(new LinkedHashMap[]{posgroup, innerFocus, endsWithPosition, outerFocus});
-        	stackedToWrap++;
-        	wrapOperandInClass(node,1,classCounter);
-        	wrapOperandInClass(node,2,++classCounter);
-//        	wrapFirstOpInClass = classCounter;
-//        	wrapSecondOpInClass = ++classCounter;
-        }
-        
-        
         if (rangenode != null) {
-            String range = rangenode.getChild(0).toStringTree();
-            posgroup.put("range", range.toLowerCase());
+            String range = rangenode.getChild(0).toStringTree().toLowerCase();
+            if (range.equals("all")) {
+//            	wrapOperandInClass(node,2,classCounter);
+            	LinkedHashMap<String,Object> ref = makeResetReference();
+            	wrapOperand(node,2,ref);
+            }
         }
 
         if (negatePosition) {
@@ -811,29 +782,53 @@
         return posgroup;
     }
 
-    private LinkedHashMap<String, Object> parseOPOVOptions(Tree node, LinkedHashMap<String, Object> posgroup) {
+  
+
+	private LinkedHashMap<String, Object> parseOPOVOptions(Tree node, LinkedHashMap<String, Object> posgroup) {
     	boolean negatePosition = false;
         Tree posnode = getFirstChildWithCat(node, "POS");
         Tree exclnode = getFirstChildWithCat(node, "EXCL");
         Tree groupnode = getFirstChildWithCat(node, "GROUP");
 
-        String position = "";
+        ArrayList<String> positions = new ArrayList<String>();
+        ArrayList<String> sharedClasses = new ArrayList<String>();
         String posOption = null; 
         if (posnode != null) {
             posOption = posnode.getChild(0).toStringTree();
-            position = translateTextAreaArgument(posOption, "ov");
-            if (posOption.equals("N")) {
-                negatePosition = !negatePosition;
+            switch (posOption) {
+            case "L":
+                positions.add("startswith");
+                positions.add("overlapsLeft");
+                sharedClasses.add("intersects");
+                break;
+            case "R":
+            	positions.add("endswith");
+            	positions.add("overlapsRight");
+                sharedClasses.add("intersects");
+                break;
+            case "F":
+            	positions.add("matches");
+                sharedClasses.add("intersects");
+                break;
+            case "FE":
+            	positions.add("matches");
+                sharedClasses.add("equals");
+                break;
+            case "FI":
+            	positions.add("matches");
+            	sharedClasses.add("unequals");
+                break;
+            case "X": 
+            	positions.add("contains");
+                sharedClasses.add("intersects");
+                break;
             }
         } else {
-            position = "overlaps";
+        	sharedClasses.add("intersects");
         }
         
-        if (posnode != null) {
-            String value = posnode.getChild(0).toStringTree();
-            position = translateTextAreaArgument(value, "ov");
-        }
-        posgroup.put("frame", "frame:" + position);
+        posgroup.put("frames", positions);
+        posgroup.put("sharedClasses", sharedClasses);
 
         if (exclnode != null) {
             if (exclnode.getChild(0).toStringTree().equals("YES")) {
@@ -841,30 +836,30 @@
             }
         }
         
-        if (posOption != null && (posOption.equals("F") || posOption.equals("FI")) && !negatePosition) {
-        	LinkedHashMap<String, Object> endsWithPosition = makePosition("endswith");
-        	((ArrayList<Object>) endsWithPosition.get("operands")).add(makeReference(classCounter+1));
-        	LinkedHashMap<String,Object> innerFocus = makeReference(classCounter);
-        	innerFocus.put("operands", new ArrayList<Object>());
-        	LinkedHashMap<String,Object> outerFocus = makeReference(classCounter);
-        	outerFocus.put("operands", new ArrayList<Object>());
-        	LinkedHashMap[] toWrap = new LinkedHashMap[]{posgroup, innerFocus, endsWithPosition, outerFocus};
-        	if (posOption.equals("FI")) {
-        		LinkedHashMap<String, Object> noMatchPosition = makePosition("matches");
-            	((ArrayList<Object>) noMatchPosition.get("operands")).add(makeReference(classCounter+1));
-            	noMatchPosition.put("exclude", true);
-        		LinkedHashMap<String,Object> outermostFocus = makeReference(classCounter);
-        		outermostFocus.put("operands", new ArrayList<Object>());
-        		toWrap = new LinkedHashMap[]{posgroup, innerFocus, endsWithPosition, outerFocus, noMatchPosition, outermostFocus};
-        	}
-        	
-        	toWrapStack.push(toWrap);
-        	stackedToWrap++;
-        	wrapOperandInClass(node,1,classCounter+1);
-        	wrapOperandInClass(node,2,classCounter);
+//        if (posOption != null && (posOption.equals("F") || posOption.equals("FI")) && !negatePosition) {
+//        	LinkedHashMap<String, Object> endsWithPosition = makePosition("endswith");
+//        	((ArrayList<Object>) endsWithPosition.get("operands")).add(makeReference(classCounter+1));
+//        	LinkedHashMap<String,Object> innerFocus = makeReference(classCounter);
+//        	innerFocus.put("operands", new ArrayList<Object>());
+//        	LinkedHashMap<String,Object> outerFocus = makeReference(classCounter);
+//        	outerFocus.put("operands", new ArrayList<Object>());
+//        	LinkedHashMap[] toWrap = new LinkedHashMap[]{posgroup, innerFocus, endsWithPosition, outerFocus};
+//        	if (posOption.equals("FI")) {
+//        		LinkedHashMap<String, Object> noMatchPosition = makePosition("matches");
+//            	((ArrayList<Object>) noMatchPosition.get("operands")).add(makeReference(classCounter+1));
+//            	noMatchPosition.put("exclude", true);
+//        		LinkedHashMap<String,Object> outermostFocus = makeReference(classCounter);
+//        		outermostFocus.put("operands", new ArrayList<Object>());
+//        		toWrap = new LinkedHashMap[]{posgroup, innerFocus, endsWithPosition, outerFocus, noMatchPosition, outermostFocus};
+//        	}
+//        	
+//        	toWrapStack.push(toWrap);
+//        	stackedToWrap++;
+//        	wrapOperandInClass(node,1,classCounter+1);
+//        	wrapOperandInClass(node,2,classCounter);
 //        	wrapFirstOpInClass = classCounter+1;
 //        	wrapSecondOpInClass = classCounter;
-        }
+//        }
         
         if (groupnode != null) {
             String grouping = groupnode.getChild(0).toStringTree().equals("@max") ? "true" : "false";
@@ -915,45 +910,45 @@
     	return posgroup;
     }
     
-    /**
-     * Translates the text area specifications (position option arguments) to terms used in serialisation.
-     * For the allowed argument types and their values for OPIN and OPOV, see
-     * http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/ARGUMENT_I.html or
-     * http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/ARGUMENT_O.html, respectively.
-     *
-     * @param argument
-     * @param mode
-     * @return
-     */
-    private String translateTextAreaArgument(String argument, String mode) {
-        String position = "overlaps";
-        // POSTYP	:	'L'|'l'|'R'|'r'|'F'|'f'|'FE'|'fe'|'FI'|'fi'|'N'|'n'|'X'|'x' ;
-        argument = argument.toUpperCase();
-        switch (argument) {
-            case "L":
-                position = mode.equals("in") ? "startswith" : "overlapsLeft";
-                break;
-            case "R":
-                position = mode.equals("in") ? "endswith" : "overlapsRight";
-                break;
-            case "F":
-                position = "startswith";
-                break;
-            case "FE":
-                position = "matches";
-                break;
-            case "FI":
-                position = "startswith";
-                break;
-            case "N": // for OPIN only - exclusion constraint formulated in parseOPINOptions
-                position = "leftrightmatch";
-                break;
-            case "X": // for OPOV only
-                position = "residual";
-                break;
-        }
-        return position;
-    }
+//    /**
+//     * Translates the text area specifications (position option arguments) to terms used in serialisation.
+//     * For the allowed argument types and their values for OPIN and OPOV, see
+//     * http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/ARGUMENT_I.html or
+//     * http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/ARGUMENT_O.html, respectively.
+//     *
+//     * @param argument
+//     * @param mode
+//     * @return
+//     */
+//    private ArrayList<String> translateTextAreaArgument(String argument, String mode) {
+//    	ArrayList<String> positions = new ArrayList<String>();
+//        // POSTYP	:	'L'|'l'|'R'|'r'|'F'|'f'|'FE'|'fe'|'FI'|'fi'|'N'|'n'|'X'|'x' ;
+//        argument = argument.toUpperCase();
+//        switch (argument) {
+//            case "L":
+//                if (mode.equals("in")) positions.add("startswith");
+//                break;
+//            case "R":
+//                positions = mode.equals("in") ? "endswith" : "overlapsRight";
+//                break;
+//            case "F":
+//                positions = "startswith";
+//                break;
+//            case "FE":
+//                positions = "matches";
+//                break;
+//            case "FI":
+//                positions = "startswith";
+//                break;
+//            case "N": // for OPIN only - exclusion constraint formulated in parseOPINOptions
+//                positions = "leftrightmatch";
+//                break;
+//            case "X": // for OPOV only
+//                positions = "residual";
+//                break;
+//        }
+//        return positions;
+//    }
 
     LinkedList<ArrayList<Object>> nestedDistOperands = new LinkedList<ArrayList<Object>>();  
     
@@ -1039,7 +1034,10 @@
 //                "Sonne /s0 Mond"
 //                "Sonne /+w4 Mond",
 //                "#BED(der Mann , sa,-pa)",
-                "kommt /+w10 #BEG(der /w3:5 Mann) ",
+//        		"Sonne /+w1:4 Mond /-w1:7 Sterne",
+        		"wegen #IN('FE,ALL,%,MIN') <s>",
+        		"#NHIT(gehen /w1:10 voran)"
+        		
 //                "wegen #OV(F) <s>"
                 
         };
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 ff0ce02..08b269f 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
@@ -672,7 +672,8 @@
 				"focus(2&3|4:contains({2:<s>},[base=mann]))",
 				"relatesTo(cnx/c:<s>,<np>)",
 				"dominates(cnx/c*:<np>,[base=Baum])",
-				"submatch(2:<np>{2:<s>})"
+				"submatch(2:<np>{2:<s>})",
+				"focus(3:{1:[orth=der]}{3:[]}{2:[orth=Mann]})"
 		};
 //		PoliqarpPlusTree.verbose=true;
 		for (String q : queries) {
diff --git a/src/test/java/CosmasTreeTest.java b/src/test/java/CosmasTreeTest.java
index fe9a7dc..c35a4f5 100644
--- a/src/test/java/CosmasTreeTest.java
+++ b/src/test/java/CosmasTreeTest.java
@@ -371,6 +371,42 @@
 	
 	@Test
 	public void testOPPROXNested() throws QueryException {	
+		query="Sonne /+w1:4 Mond /-w1:7 Sterne";
+		expected = 
+					"{@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: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=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}}" +
+												"]}" +
+											"], inOrder=true, " +
+											"distances=[" +
+												"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=7}, min=1, max=7}" +
+											"]" +
+										"}" +
+									"]}" +
+								"]}" +
+							"], 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(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		
 		query="Sonne /-w4 Mond /+w2 Sterne";
 		
 		String mondsterne = 
@@ -452,33 +488,26 @@
 		query="wegen #IN <s>";
 		String opin1 = 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:contains, operands=[" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
 							"{@type=korap:span, key=s}," +
 							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
 							"]}" +
-						"]}" +
+						"], frames=[], sharedClasses=[includes]}" +
 					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(opin1.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
-		query="wegen #IN(L) <s>"; //wrap an *excluded* matches-position around a startwith-position constraint in order to 
+		query="wegen #IN(L) <s>"; 
 		String opin2 = 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:matches, operands=[" +
-							"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-								"{@type=korap:group, operation=operation:position, frame=frame:startswith, operands=[" +
-									"{@type=korap:group, operation=operation:class, class=2, operands=[" +
-										"{@type=korap:span, key=s}" +
-									"]}," +
-									"{@type=korap:group, operation=operation:class, class=1, operands=[" +
-										"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
-									"]}" +
-								"]}" +
-							"]}," +
-							"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-						"], exclude=true}" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
+							"{@type=korap:span, key=s}," +
+							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
+							"]}" +
+						"], frames=[startswith], sharedClasses=[includes]}" +
 					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -488,24 +517,12 @@
 		query="wegen #IN(F) <s>";
 		String opin3= 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:contains, operands=[" +
-							"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-								"{@type=korap:group, operation=operation:position, frame=frame:endswith, operands=[" +
-									"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-										"{@type=korap:group, operation=operation:position, frame=frame:startswith, operands=[" +
-											"{@type=korap:group, operation=operation:class, class=1, operands=[" +
-												"{@type=korap:span, key=s}" +
-											"]}," +
-											"{@type=korap:group, operation=operation:class, class=2, operands=[" +
-												"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
-											"]}" +
-										"]}" +
-									"]}," +
-									"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-								"]}" +
-							"]}," +
-							"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-						"]}" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
+							"{@type=korap:span, key=s}," +
+							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
+							"]}" +
+						"], frames=[matches], sharedClasses=[includes]}" +
 					"]}" +
 					"";
 		ct = new CosmasTree(query);
@@ -515,24 +532,12 @@
 		query="wegen #IN(FI) <s>";
 		String opin4= 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:matches, operands=[" +
-							"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-								"{@type=korap:group, operation=operation:position, frame=frame:endswith, operands=[" +
-									"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-										"{@type=korap:group, operation=operation:position, frame=frame:startswith, operands=[" +
-											"{@type=korap:group, operation=operation:class, class=1, operands=[" +
-												"{@type=korap:span, key=s}" +
-											"]}," +
-											"{@type=korap:group, operation=operation:class, class=2, operands=[" +
-												"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
-											"]}" +
-										"]}" +
-									"]}," +
-									"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-								"]}" +
-							"]}," +
-							"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-						"], exclude=true}" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
+							"{@type=korap:span, key=s}," +
+							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
+							"]}" +
+						"], frames=[matches], sharedClasses=[unequals,includes]}" +
 					"]}" +
 					"";
 		ct = new CosmasTree(query);
@@ -541,14 +546,14 @@
 		
 		query="wegen #IN(FE) <s>";
 		String opin5= 
-							"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-								"{@type=korap:group, operation=operation:position, frame=frame:matches, operands=[" +
-									"{@type=korap:span, key=s}," +
-									"{@type=korap:group, operation=operation:class, class=1, operands=[" +
-										"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
-									"]}" +
-								"]}" +
+				"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
+							"{@type=korap:span, key=s}," +
+							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
 							"]}" +
+						"], frames=[matches], sharedClasses=[equals]}" +
+					"]}" +
 					"";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -557,12 +562,12 @@
 		query="wegen #IN(%, L) <s>";
 		String opin6 = 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:startswith, operands=[" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
 							"{@type=korap:span, key=s}," +
 							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
 							"]}" +
-						"], exclude=true}" +
+						"], frames=[startswith], sharedClasses=[includes], exclude=true}" +
 					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -571,12 +576,14 @@
 		query="wegen #IN('FE,ALL,%,MIN') <s>";
 		String opin7 = 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:matches, operands=[" +
-							"{@type=korap:span, key=s}," +
+						"{@type=korap:group, operation=operation:position, operands=[" +
+							"{@type=korap:reference, operation=operation:focus, reset=true, operands=[" +
+								"{@type=korap:span, key=s}" +
+							"]}," +
 							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
 							"]}" +
-						"], range=all, exclude=true, grouping=false}" +
+						"], frames=[matches], sharedClasses=[equals], exclude=true, grouping=false}" +
 					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -588,12 +595,12 @@
 		query="wegen #OV <s>";
 		String opov1 = 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:overlaps, operands=[" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
 							"{@type=korap:span, key=s}," +
 							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
 							"]}" +
-						"]}" +
+						"], frames=[], sharedClasses=[intersects]}" +
 					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -602,12 +609,12 @@
 		query="wegen #OV(L) <s>";
 		String opov2 = 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:overlapsLeft, operands=[" +
+						"{@type=korap:group, operation=operation:position, operands=[" +
 							"{@type=korap:span, key=s}," +
 							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
 							"]}" +
-						"]}" +
+						"], frames=[startswith,overlapsLeft], sharedClasses=[intersects]}" +
 					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
@@ -616,21 +623,13 @@
 		query="wegen #OV(F) <s>";
 		String opov3= 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:endswith, operands=[" +
-							"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-								"{@type=korap:group, operation=operation:position, frame=frame:startswith, operands=[" +
-									"{@type=korap:group, operation=operation:class, class=1, operands=[" +
-										"{@type=korap:span, key=s}" +
-									"]}," +
-									"{@type=korap:group, operation=operation:class, class=2, operands=[" +
-										"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
-									"]}" +
-								"]}" +
-							"]}," +
-							"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-						"]}" +
-					"]}" +
-					"";
+						"{@type=korap:group, operation=operation:position, operands=[" +
+							"{@type=korap:span, key=s}," +
+							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
+							"]}" +
+						"], frames=[matches], sharedClasses=[intersects]}" +
+					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(opov3.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -638,26 +637,13 @@
 		query="wegen #OV(FI) <s>";
 		String opov4= 
 					"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-						"{@type=korap:group, operation=operation:position, frame=frame:matches, operands=[" +
-							"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-								"{@type=korap:group, operation=operation:position, frame=frame:endswith, operands=[" +
-									"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-										"{@type=korap:group, operation=operation:position, frame=frame:startswith, operands=[" +
-											"{@type=korap:group, operation=operation:class, class=1, operands=[" +
-												"{@type=korap:span, key=s}" +
-											"]}," +
-											"{@type=korap:group, operation=operation:class, class=2, operands=[" +
-												"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
-											"]}" +
-										"]}" +
-									"]}," +
-									"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-								"]}" +
-							"]}," +
-							"{@type=korap:reference, operation=operation:focus, classRef=[2]}" +
-						"], exclude=true}" +
-					"]}" +
-					"";
+						"{@type=korap:group, operation=operation:position, operands=[" +
+							"{@type=korap:span, key=s}," +
+							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+								"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
+							"]}" +
+						"], frames=[matches], sharedClasses=[unequals]}" +
+					"]}";
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(opov4.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -665,12 +651,12 @@
 		query="wegen #OV(FE) <s>";
 		String opov5= 
 							"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-								"{@type=korap:group, operation=operation:position, frame=frame:matches, operands=[" +
+								"{@type=korap:group, operation=operation:position, operands=[" +
 									"{@type=korap:span, key=s}," +
 									"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, key=wegen, layer=orth, match=match:eq}}" +
 									"]}" +
-								"]}" +
+								"], frames=[matches], sharedClasses=[equals]}" +
 							"]}" +
 					"";
 		ct = new CosmasTree(query);
@@ -1010,13 +996,13 @@
 	public void testOPNHIT() throws QueryException {
 		query="#NHIT(gehen /w1:10 voran)";
 		String nhit1 = 
-				"{@type=korap:reference, operation=operation:focus, classRef=[1,2], classRefOp=classRefOp:intersection, operands=[" +
+				"{@type=korap:reference, operation=operation:focus, classRef=[1], classRefOp=classRefOp:inversion, operands=[" +
 					"{@type=korap:group, operation=operation:sequence, " +
 						"operands=[" +
 							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, key=gehen, layer=orth, match=match:eq}}" +
 							"]}," +
-							"{@type=korap:group, operation=operation:class, class=2, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, key=voran, layer=orth, match=match:eq}}" +
 							"]}" +
 						"], inOrder=false, " +