positions using classRefCheck
cosmas MORPH
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 4ad6a01..0a348fa 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
@@ -64,6 +64,7 @@
 		requestMap.put("warnings", warnings);
 		requestMap.put("announcements", announcements);
 		requestMap.put("collection", collection);
+		requestMap.put("meta", new LinkedHashMap<String, Object>());
 	}
 	
 	public Map<String, Object> getRequestMap() {
@@ -267,7 +268,11 @@
 
 	protected LinkedHashMap<String, Object> makeDistance(String key, Integer min, Integer max) {
 		LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
-		group.put("@type", "korap:distance");
+		if (key.equals("w")) {
+			group.put("@type", "korap:distance");
+		} else {
+			group.put("@type", "cosmas:distance");
+		}
 		group.put("key", key);
 		group.put("boundary", makeBoundary(min, max));
 		group.put("min", min);
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 c89f418..f8a7f19 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
@@ -28,275 +28,256 @@
  */
 public class CosmasTree extends Antlr3AbstractSyntaxTree {
 
-    private static Logger log = LoggerFactory.getLogger(CosmasTree.class);
+	private static Logger log = LoggerFactory.getLogger(CosmasTree.class);
 
-    LinkedList<LinkedHashMap[]> toWrapStack = new LinkedList<LinkedHashMap[]>();
-    /**
-     * Field for repetition query (Kleene + or * operations, or min/max queries: {2,4}
-     */
-    String repetition = "";
-    /**
-     * Global control structure for fieldGroups, keeps track of open fieldGroups.
-     */
-    LinkedList<ArrayList<Object>> openFieldGroups = new LinkedList<ArrayList<Object>>();
-    /**
-     * Keeps track of how many toWrap objects there are to pop after every recursion of {@link #processNode(ParseTree)}
-     */
-    LinkedList<Integer> toWrapsToPop = new LinkedList<Integer>();
-    /**
-     * Flag that indicates whether token fields or meta fields are currently being processed
-     */
-    boolean inMeta = false;
-    /**
-     * If true, a sequence (OPPROX node) is governed by an OPALL node (ALL()-operator), which requires to match
-     * all tokens of the sequence.
-     */
-    boolean inOPALL = false;
-    boolean inOPNHIT = false;
-    /**
-     *
-     */
-    int classCounter = 1;
-    boolean negate = false;
+	LinkedList<LinkedHashMap[]> toWrapStack = new LinkedList<LinkedHashMap[]>();
+	/**
+	 * Field for repetition query (Kleene + or * operations, or min/max queries: {2,4}
+	 */
+	String repetition = "";
+	/**
+	 * Global control structure for fieldGroups, keeps track of open fieldGroups.
+	 */
+	LinkedList<ArrayList<Object>> openFieldGroups = new LinkedList<ArrayList<Object>>();
+	/**
+	 * Keeps track of how many toWrap objects there are to pop after every recursion of {@link #processNode(ParseTree)}
+	 */
+	LinkedList<Integer> toWrapsToPop = new LinkedList<Integer>();
+	/**
+	 * Flag that indicates whether token fields or meta fields are currently being processed
+	 */
+	boolean inMeta = false;
+	/**
+	 * If true, a sequence (OPPROX node) is governed by an OPALL node (ALL()-operator), which requires to match
+	 * all tokens of the sequence.
+	 */
+	boolean inOPALL = false;
+	boolean inOPNHIT = false;
+	/**
+	 *
+	 */
+	int classCounter = 1;
+	boolean negate = false;
 
-    /**
-     * Allows for the definition of objects to be wrapped around the arguments of an operation.
-     * Each record in the table holds the parent node of the argument, the number of the argument 
-     * and an object in whose operands list the argument shall be wrapped.
-     */
-    Table<Tree,Integer,LinkedHashMap<String,Object>> operandWrap = HashBasedTable.create();
+	/**
+	 * Allows for the definition of objects to be wrapped around the arguments of an operation.
+	 * Each record in the table holds the parent node of the argument, the number of the argument 
+	 * and an object in whose operands list the argument shall be wrapped.
+	 */
+	Table<Tree,Integer,LinkedHashMap<String,Object>> operandWrap = HashBasedTable.create();
 
-    /**
-     * Keeps track of all visited nodes in a tree
-     */
-    List<Tree> visited = new ArrayList<Tree>();
+	/**
+	 * Keeps track of all visited nodes in a tree
+	 */
+	List<Tree> visited = new ArrayList<Tree>();
 
-    Integer stackedToWrap = 0;
-    /**
-     * A list of node categories that can be sequenced (i.e. which can be in a sequence with any number of other nodes in this list)
-     */
-    private final List<String> sequentiableCats = Arrays.asList(new String[]{"OPWF", "OPLEM", "OPMORPH", "OPBEG", "OPEND", "OPIN", "OPBED"});
-    /**
-     * Keeps track of sequenced nodes, i.e. nodes that implicitly govern  a sequence, as in (C2PQ (OPWF der) (OPWF Mann)).
-     * This is necessary in order to know when to take the sequence off the object stack, as the sequence is introduced by the
-     * first child but cannot be closed after this first child in order not to lose its siblings
-     */
-    private LinkedList<Tree> sequencedNodes = new LinkedList<Tree>();
+	Integer stackedToWrap = 0;
+	/**
+	 * A list of node categories that can be sequenced (i.e. which can be in a sequence with any number of other nodes in this list)
+	 */
+	private final List<String> sequentiableCats = Arrays.asList(new String[]{"OPWF", "OPLEM", "OPMORPH", "OPBEG", "OPEND", "OPIN", "OPBED"});
+	/**
+	 * Keeps track of sequenced nodes, i.e. nodes that implicitly govern  a sequence, as in (C2PQ (OPWF der) (OPWF Mann)).
+	 * This is necessary in order to know when to take the sequence off the object stack, as the sequence is introduced by the
+	 * first child but cannot be closed after this first child in order not to lose its siblings
+	 */
+	private LinkedList<Tree> sequencedNodes = new LinkedList<Tree>();
 
-    private boolean nodeHasSequentiableSiblings;
+	private boolean nodeHasSequentiableSiblings;
 
-    /**
-     * Keeps track of operands lists that are to be serialised in an inverted
-     * order (e.g. the IN() operator) compared to their AST representation.
-     */
-    private LinkedList<ArrayList<Object>> invertedOperandsLists = new LinkedList<ArrayList<Object>>();
-    /**
-     * @param tree   The syntax tree as returned by ANTLR
-     * @param parser The ANTLR parser instance that generated the parse tree
-     * @throws QueryException
-     */
-    public CosmasTree(String query) throws QueryException {
-        this.query = query;
-        process(query);
-        log.info(">>> " + requestMap.get("query") + " <<<");
-    }
+	/**
+	 * Keeps track of operands lists that are to be serialised in an inverted
+	 * order (e.g. the IN() operator) compared to their AST representation.
+	 */
+	private LinkedList<ArrayList<Object>> invertedOperandsLists = new LinkedList<ArrayList<Object>>();
+	/**
+	 * @param tree   The syntax tree as returned by ANTLR
+	 * @param parser The ANTLR parser instance that generated the parse tree
+	 * @throws QueryException
+	 */
+	public CosmasTree(String query) throws QueryException {
+		this.query = query;
+		process(query);
+		log.info(">>> " + requestMap.get("query") + " <<<");
+	}
 
-    @Override
-    public void process(String query) throws QueryException {
-        Tree tree = null;
-        try {
-            tree = parseCosmasQuery(query);
-        } catch (RecognitionException e) {
-            throw new QueryException("Your query could not be processed. Please make sure it is well-formed.");
-        } catch (NullPointerException e) {
-            throw new QueryException("Your query could not be processed. Please make sure it is well-formed.");
-        }
-        log.info("Processing CosmasII query");
-        System.out.println("Processing Cosmas");
-        processNode(tree);
-        log.info(requestMap.toString());
-    }
+	@Override
+	public void process(String query) throws QueryException {
+		Tree tree = null;
+		try {
+			tree = parseCosmasQuery(query);
+		} catch (RecognitionException e) {
+			throw new QueryException("Your query could not be processed. Please make sure it is well-formed.");
+		} catch (NullPointerException e) {
+			throw new QueryException("Your query could not be processed. Please make sure it is well-formed.");
+		}
+		log.info("Processing CosmasII query");
+		System.out.println("Processing Cosmas");
+		processNode(tree);
+		log.info(requestMap.toString());
+	}
 
-    @SuppressWarnings("unchecked")
-    private void processNode(Tree node) {
+	@SuppressWarnings("unchecked")
+	private void processNode(Tree node) {
 
-        // Top-down processing
-        if (visited.contains(node)) return;
-        else visited.add(node);
+		// Top-down processing
+		if (visited.contains(node)) return;
+		else visited.add(node);
 
 
-        String nodeCat = getNodeCat(node);
-        openNodeCats.push(nodeCat);
+		String nodeCat = getNodeCat(node);
+		openNodeCats.push(nodeCat);
 
-        stackedObjects = 0;
-        stackedToWrap = 0;
+		stackedObjects = 0;
+		stackedToWrap = 0;
 
-        if (verbose) {
-            System.err.println(" " + objectStack);
-            System.out.println(openNodeCats);
-        }
+		if (verbose) {
+			System.err.println(" " + objectStack);
+			System.out.println(openNodeCats);
+		}
 
-		
+
 		/* ***************************************
-         * Processing individual node categories *
+		 * Processing individual node categories *
 		 *****************************************/
 
 
-        // Check for potential implicit sequences as in (C2PQ (OPWF der) (OPWF Mann)). The sequence is introduced
-        // by the first child if it (and its siblings) is sequentiable.
-        if (sequentiableCats.contains(nodeCat)) {
-            // for each node, check if parent has more than one child (-> could be implicit sequence)
-            Tree parent = node.getParent();
-            if (parent.getChildCount() > 1) {
-                // if node is first child of parent...
-                if (node == parent.getChild(0)) {
-                    nodeHasSequentiableSiblings = false;
-                    for (int i = 1; i < parent.getChildCount(); i++) {
-                        if (sequentiableCats.contains(getNodeCat(parent.getChild(i)))) {
-                            nodeHasSequentiableSiblings = true;
-                            continue;
-                        }
-                    }
-                    if (nodeHasSequentiableSiblings) {
-                        // Step I: create sequence
-                        LinkedHashMap<String, Object> sequence = new LinkedHashMap<String, Object>();
-                        sequence.put("@type", "korap:group");
-                        sequence.put("operation", "operation:sequence");
-                        sequence.put("operands", new ArrayList<Object>());
-                        // push sequence on object stack but don't increment stackedObjects counter since
-                        // we've got to wait until the parent node is processed - therefore, add the parent
-                        // to the sequencedNodes list and remove the sequence from the stack when the parent
-                        // has been processed
-                        objectStack.push(sequence);
-                        sequencedNodes.push(parent);
-                        // Step II: decide where to put sequence
-                        putIntoSuperObject(sequence, 1);
-                    }
-                }
-            }
-        }
+		// Check for potential implicit sequences as in (C2PQ (OPWF der) (OPWF Mann)). The sequence is introduced
+		// by the first child if it (and its siblings) is sequentiable.
+		if (sequentiableCats.contains(nodeCat)) {
+			// for each node, check if parent has more than one child (-> could be implicit sequence)
+			Tree parent = node.getParent();
+			if (parent.getChildCount() > 1) {
+				// if node is first child of parent...
+				if (node == parent.getChild(0)) {
+					nodeHasSequentiableSiblings = false;
+					for (int i = 1; i < parent.getChildCount(); i++) {
+						if (sequentiableCats.contains(getNodeCat(parent.getChild(i)))) {
+							nodeHasSequentiableSiblings = true;
+							continue;
+						}
+					}
+					if (nodeHasSequentiableSiblings) {
+						// Step I: create sequence
+						LinkedHashMap<String, Object> sequence = new LinkedHashMap<String, Object>();
+					sequence.put("@type", "korap:group");
+					sequence.put("operation", "operation:sequence");
+					sequence.put("operands", new ArrayList<Object>());
+					// push sequence on object stack but don't increment stackedObjects counter since
+					// we've got to wait until the parent node is processed - therefore, add the parent
+					// to the sequencedNodes list and remove the sequence from the stack when the parent
+					// has been processed
+					objectStack.push(sequence);
+					sequencedNodes.push(parent);
+					// Step II: decide where to put sequence
+					putIntoSuperObject(sequence, 1);
+					}
+				}
+			}
+		}
 
-        // Nodes introducing tokens. Process all in the same manner, except for the fieldMap entry
-        if (nodeCat.equals("OPWF") || nodeCat.equals("OPLEM")) {
+		// Nodes introducing tokens. Process all in the same manner, except for the fieldMap entry
+		if (nodeCat.equals("OPWF") || nodeCat.equals("OPLEM")) {
 
-            //Step I: get info
-            LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
-            token.put("@type", "korap:token");
-            objectStack.push(token);
-            stackedObjects++;
-            LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
-            token.put("wrap", fieldMap);
+			//Step I: get info
+			LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
+			token.put("@type", "korap:token");
+			objectStack.push(token);
+			stackedObjects++;
+			LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
+			token.put("wrap", fieldMap);
 
-            fieldMap.put("@type", "korap:term");
-            // make category-specific fieldMap entry
-            String attr = nodeCat.equals("OPWF") ? "orth" : "lemma";
-            String value = node.getChild(0).toStringTree().replaceAll("\"", "");
-            // check for wildcard string
-            Pattern p = Pattern.compile("[+*?]");
-            Matcher m = p.matcher(value);
-            if (m.find()) fieldMap.put("type", "type:wildcard");
-            
-            if (value.startsWith("$")) {
-                value = value.substring(1);
-                fieldMap.put("caseInsensitive", true);
-            }
+			fieldMap.put("@type", "korap:term");
+			// make category-specific fieldMap entry
+			String attr = nodeCat.equals("OPWF") ? "orth" : "lemma";
+			String value = node.getChild(0).toStringTree().replaceAll("\"", "");
+			// check for wildcard string
+			Pattern p = Pattern.compile("[+*?]");
+			Matcher m = p.matcher(value);
+			if (m.find()) fieldMap.put("type", "type:wildcard");
 
-            fieldMap.put("key", value);
-            fieldMap.put("layer", attr);
+			if (value.startsWith("$")) {
+				value = value.substring(1);
+				fieldMap.put("caseInsensitive", true);
+			}
 
-            // negate field (see above)
-            if (negate) {
-                fieldMap.put("match", "match:ne");
-            } else {
-                fieldMap.put("match", "match:eq");
-            }
-            //Step II: decide where to put
-            if (!hasChild(node, "TPOS")) {
-                putIntoSuperObject(token, 1);
-                visited.add(node.getChild(0));
-            } else {
-            	// TODO
-            }
-        }
+			fieldMap.put("key", value);
+			fieldMap.put("layer", attr);
 
-        if (nodeCat.equals("OPMORPH")) {
-            //Step I: get info
-            LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
-            token.put("@type", "korap:token");
-            LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
-            token.put("wrap", fieldMap);
+			// negate field (see above)
+			if (negate) {
+				fieldMap.put("match", "match:ne");
+			} else {
+				fieldMap.put("match", "match:eq");
+			}
+			//Step II: decide where to put
+			if (!hasChild(node, "TPOS")) {
+				putIntoSuperObject(token, 1);
+				visited.add(node.getChild(0));
+			} else {
+				// TODO
+			}
+		}
 
-            fieldMap.put("@type", "korap:term");
-//			fieldMap.put("key", "morph:"+node.getChild(0).toString().replace(" ", "_"));
-            String[] morphValues = node.getChild(0).toString().split(" ");
-            String pos = morphValues[0];
-            fieldMap.put("key", pos);
-            fieldMap.put("layer", "pos");
-            // make category-specific fieldMap entry
-            // negate field (see above)
-            if (negate) {
-                fieldMap.put("match", "match:ne");
-            } else {
-                fieldMap.put("match", "match:eq");
-            }
-//			List<String> morphValues = parseMorph(node.getChild(0).toStringTree());
-//			System.err.println(morphValues);
-//			if (morphValues.size() == 1) {
-//				LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
-//				token.put("key", fieldMap);
-//				
-//				fieldMap.put("@type", "korap:term");
-//				fieldMap.put("key", morphValues.get(0));
-//				// make category-specific fieldMap entry
-//				// negate field (see above)
-//				if (negate) {
-//					fieldMap.put("operation", "operation:"+ "!=");
-//				} else {
-//					fieldMap.put("operation", "operation:"+ "=");
-//				}
-//			} else {
-//				LinkedHashMap<String, Object> conjGroup = new LinkedHashMap<String, Object>();
-//				token.put("key", conjGroup);
-//				ArrayList<Object> conjOperands = new ArrayList<Object>();
-//				conjGroup.put("@type", "korap:group");
-//				conjGroup.put("operation", "operation:"+ "and");
-//				conjGroup.put("operands", conjOperands);
-//				for (String value : morphValues) {
-//					LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
-//					token.put("key", fieldMap);
-//					
-//					fieldMap.put("@type", "korap:term");
-//					fieldMap.put("key", value);
-//					// make category-specific fieldMap entry
-//					// negate field (see above)
-//					if (negate) {
-//						fieldMap.put("operation", "operation:"+ "!=");
-//					} else {
-//						fieldMap.put("operation", "operation:"+ "=");
-//					}
-//				}
-//			}
+		if (nodeCat.equals("OPMORPH")) {
+			//Step I: get info
+			String[] morphterms = node.getChild(0).toStringTree().split("&");
+			LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
+			token.put("@type", "korap:token");
+			ArrayList<Object> terms = new ArrayList<Object>();
+			for (String morphterm : morphterms) {
+				String[] attrval = morphterm.split("=");
+				if (attrval[0].endsWith("!")) {
+					negate = !negate;
+					attrval[0] = attrval[0].replace("!", "");
+				}
+				String[] foundrylayer = attrval[0].split("/");
+				LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
+				fieldMap.put("@type", "korap:term");
+				//     			fieldMap.put("key", "morph:"+node.getChild(0).toString().replace(" ", "_"));
+				fieldMap.put("key", attrval[1]);
+				if (foundrylayer.length==1) {
+					fieldMap.put("layer", foundrylayer[0]);
+				} else {
+					fieldMap.put("foundry", foundrylayer[0]);
+					fieldMap.put("layer", foundrylayer[1]);
+				}
+				
+				// make category-specific fieldMap entry
+				// negate field (see above)
+				if (negate) {
+					fieldMap.put("match", "match:ne");
+				} else {
+					fieldMap.put("match", "match:eq");
+				}
+				terms.add(fieldMap);
+			}
+			if (morphterms.length == 1) {
+				token.put("wrap", terms);
+			} else {
+				LinkedHashMap<String, Object> termGroup = makeTermGroup("and");
+				termGroup.put("operands", terms);
+				token.put("wrap", termGroup);
+			}
+			//Step II: decide where to put
+			putIntoSuperObject(token, 0);
+			visited.add(node.getChild(0));
+		}
 
+		if (nodeCat.equals("OPELEM")) {
+			// Step I: create element
+			LinkedHashMap<String, Object> span = makeSpan();
+			if (node.getChild(0).toStringTree().equals("EMPTY")) {
 
-            //Step II: decide where to put
-            putIntoSuperObject(token, 0);
-            visited.add(node.getChild(0));
-        }
-
-        if (nodeCat.equals("OPELEM")) {
-            // Step I: create element
-            LinkedHashMap<String, Object> span = makeSpan();
-            if (node.getChild(0).toStringTree().equals("EMPTY")) {
-
-            } else {
-                int elname = 0;
-                Tree elnameNode = getFirstChildWithCat(node, "ELNAME");
-                if (elnameNode != null) {
-                    span.put("key", elnameNode.getChild(0).toStringTree().toLowerCase());
-                    elname = 1;
-                }
-                if (node.getChildCount() > elname) {
-                    /*
+			} else {
+				int elname = 0;
+				Tree elnameNode = getFirstChildWithCat(node, "ELNAME");
+				if (elnameNode != null) {
+					span.put("key", elnameNode.getChild(0).toStringTree().toLowerCase());
+					elname = 1;
+				}
+				if (node.getChildCount() > elname) {
+					/*
 					 * Attributes can carry several values, like #ELEM(W ANA != 'N V'), 
 					 * denoting a word whose POS is neither N nor V.
 					 * When seeing this, create a sub-termGroup and put it into the top-level
@@ -305,396 +286,396 @@
 					 * top-level group (in order to avoid a top-level group that only
 					 * contains a sub-group).
 					 */
-                    LinkedHashMap<String, Object> termGroup = makeTermGroup("and");
-                    ArrayList<Object> termGroupOperands = (ArrayList<Object>) termGroup.get("operands");
-                    for (int i = elname; i < node.getChildCount(); i++) {
-                        Tree attrNode = node.getChild(i);
-                        if (attrNode.getChildCount() == 2) {
-                            LinkedHashMap<String, Object> term = makeTerm();
-                            termGroupOperands.add(term);
-                            String layer = attrNode.getChild(0).toStringTree();
-                            String[] splitted = layer.split("/");
-                            if (splitted.length > 1) {
-                                term.put("foundry", splitted[0]);
-                                layer = splitted[1];
-                            }
-                            term.put("layer", translateMorph(layer));
-                            term.put("key", attrNode.getChild(1).toStringTree());
-                            String match = getNodeCat(attrNode).equals("EQ") ? "eq" : "ne";
-                            term.put("match", "match:" + match);
-                        } else {
-                            LinkedHashMap<String, Object> subTermGroup = makeTermGroup("and");
-                            ArrayList<Object> subTermGroupOperands = (ArrayList<Object>) subTermGroup.get("operands");
-                            int j;
-                            for (j = 1; j < attrNode.getChildCount(); j++) {
-                                LinkedHashMap<String, Object> term = makeTerm();
-                                String layer = attrNode.getChild(0).toStringTree();
-                                String[] splitted = layer.split("/");
-                                if (splitted.length > 1) {
-                                    term.put("foundry", splitted[0]);
-                                    layer = splitted[1];
-                                }
-                                term.put("layer", translateMorph(layer));
-                                term.put("key", attrNode.getChild(j).toStringTree());
-                                String match = getNodeCat(attrNode).equals("EQ") ? "eq" : "ne";
-                                term.put("match", "match:" + match);
-                                if (node.getChildCount() == elname + 1) {
-                                    termGroupOperands.add(term);
-                                } else {
-                                    subTermGroupOperands.add(term);
-                                }
-                            }
-                            if (node.getChildCount() > elname + 1) {
-                                termGroupOperands.add(subTermGroup);
-                            }
-                        }
-                        if (getNodeCat(attrNode).equals("NOTEQ")) negate = true;
-                    }
-                    span.put("attr", termGroup);
-                }
-            }
+					LinkedHashMap<String, Object> termGroup = makeTermGroup("and");
+					ArrayList<Object> termGroupOperands = (ArrayList<Object>) termGroup.get("operands");
+					for (int i = elname; i < node.getChildCount(); i++) {
+						Tree attrNode = node.getChild(i);
+						if (attrNode.getChildCount() == 2) {
+							LinkedHashMap<String, Object> term = makeTerm();
+							termGroupOperands.add(term);
+							String layer = attrNode.getChild(0).toStringTree();
+							String[] splitted = layer.split("/");
+							if (splitted.length > 1) {
+								term.put("foundry", splitted[0]);
+								layer = splitted[1];
+							}
+							term.put("layer", translateMorph(layer));
+							term.put("key", attrNode.getChild(1).toStringTree());
+							String match = getNodeCat(attrNode).equals("EQ") ? "eq" : "ne";
+							term.put("match", "match:" + match);
+						} else {
+							LinkedHashMap<String, Object> subTermGroup = makeTermGroup("and");
+							ArrayList<Object> subTermGroupOperands = (ArrayList<Object>) subTermGroup.get("operands");
+							int j;
+							for (j = 1; j < attrNode.getChildCount(); j++) {
+								LinkedHashMap<String, Object> term = makeTerm();
+								String layer = attrNode.getChild(0).toStringTree();
+								String[] splitted = layer.split("/");
+								if (splitted.length > 1) {
+									term.put("foundry", splitted[0]);
+									layer = splitted[1];
+								}
+								term.put("layer", translateMorph(layer));
+								term.put("key", attrNode.getChild(j).toStringTree());
+								String match = getNodeCat(attrNode).equals("EQ") ? "eq" : "ne";
+								term.put("match", "match:" + match);
+								if (node.getChildCount() == elname + 1) {
+									termGroupOperands.add(term);
+								} else {
+									subTermGroupOperands.add(term);
+								}
+							}
+							if (node.getChildCount() > elname + 1) {
+								termGroupOperands.add(subTermGroup);
+							}
+						}
+						if (getNodeCat(attrNode).equals("NOTEQ")) negate = true;
+					}
+					span.put("attr", termGroup);
+				}
+			}
 
-            //Step II: decide where to put
-            putIntoSuperObject(span);
-        }
+			//Step II: decide where to put
+			putIntoSuperObject(span);
+		}
 
-        if (nodeCat.equals("OPLABEL")) {
-            // Step I: create element
-            LinkedHashMap<String, Object> elem = new LinkedHashMap<String, Object>();
-            elem.put("@type", "korap:span");
-            elem.put("key", node.getChild(0).toStringTree().replaceAll("<|>", ""));
-            //Step II: decide where to put
-            putIntoSuperObject(elem);
-        }
+		if (nodeCat.equals("OPLABEL")) {
+			// Step I: create element
+			LinkedHashMap<String, Object> elem = new LinkedHashMap<String, Object>();
+			elem.put("@type", "korap:span");
+			elem.put("key", node.getChild(0).toStringTree().replaceAll("<|>", ""));
+			//Step II: decide where to put
+			putIntoSuperObject(elem);
+		}
 
-        if (nodeCat.equals("OPAND") || nodeCat.equals("OPNOT")) {
-            // Step I: create group
-            LinkedHashMap<String, Object> distgroup = new LinkedHashMap<String, Object>();
-            distgroup.put("@type", "korap:group");
-            distgroup.put("operation", "operation:sequence");
-            ArrayList<Object> distances = new ArrayList<Object>();
-            LinkedHashMap<String, Object> zerodistance = new LinkedHashMap<String, Object>();
-            zerodistance.put("@type", "korap:distance");
-            zerodistance.put("key", "t");
-            zerodistance.put("min", 0);
-            zerodistance.put("max", 0);
-            if (nodeCat.equals("OPNOT")) zerodistance.put("exclude", true);
-            distances.add(zerodistance);
-            distgroup.put("distances", distances);
-            distgroup.put("operands", new ArrayList<Object>());
-            objectStack.push(distgroup);
-            stackedObjects++;
-            // Step II: decide where to put
-            putIntoSuperObject(distgroup, 1);
-        }
+		if (nodeCat.equals("OPAND") || nodeCat.equals("OPNOT")) {
+			// Step I: create group
+			LinkedHashMap<String, Object> distgroup = new LinkedHashMap<String, Object>();
+			distgroup.put("@type", "korap:group");
+			distgroup.put("operation", "operation:sequence");
+			ArrayList<Object> distances = new ArrayList<Object>();
+			LinkedHashMap<String, Object> zerodistance = new LinkedHashMap<String, Object>();
+			zerodistance.put("@type", "cosmas:distance");
+			zerodistance.put("key", "t");
+			zerodistance.put("min", 0);
+			zerodistance.put("max", 0);
+			if (nodeCat.equals("OPNOT")) zerodistance.put("exclude", true);
+			distances.add(zerodistance);
+			distgroup.put("distances", distances);
+			distgroup.put("operands", new ArrayList<Object>());
+			objectStack.push(distgroup);
+			stackedObjects++;
+			// Step II: decide where to put
+			putIntoSuperObject(distgroup, 1);
+		}
 
-        if (nodeCat.equals("OPOR")) {
-            // Step I: create group
-            LinkedHashMap<String, Object> disjunction = new LinkedHashMap<String, Object>();
-            disjunction.put("@type", "korap:group");
-            disjunction.put("operation", "operation:or");
-            disjunction.put("operands", new ArrayList<Object>());
-            objectStack.push(disjunction);
-            stackedObjects++;
-            // Step II: decide where to put
-            putIntoSuperObject(disjunction, 1);
-        }
+		if (nodeCat.equals("OPOR")) {
+			// Step I: create group
+			LinkedHashMap<String, Object> disjunction = new LinkedHashMap<String, Object>();
+			disjunction.put("@type", "korap:group");
+			disjunction.put("operation", "operation:or");
+			disjunction.put("operands", new ArrayList<Object>());
+			objectStack.push(disjunction);
+			stackedObjects++;
+			// Step II: decide where to put
+			putIntoSuperObject(disjunction, 1);
+		}
 
-        if (nodeCat.equals("OPPROX")) {
-            // collect info
-            Tree prox_opts = node.getChild(0);
-            Tree typ = prox_opts.getChild(0);
-            Tree dist_list = prox_opts.getChild(1);
-            // Step I: create group
-            LinkedHashMap<String, Object> group = makeGroup("sequence");
-            
-            ArrayList<Object> constraints = new ArrayList<Object>();
-            boolean exclusion = typ.getChild(0).toStringTree().equals("EXCL");
+		if (nodeCat.equals("OPPROX")) {
+			// collect info
+			Tree prox_opts = node.getChild(0);
+			Tree typ = prox_opts.getChild(0);
+			Tree dist_list = prox_opts.getChild(1);
+			// Step I: create group
+			LinkedHashMap<String, Object> group = makeGroup("sequence");
 
-            boolean inOrder = false;
-            boolean invertedOperands = false;
-            
-            group.put("inOrder", inOrder);
-            group.put("distances", constraints);
-            
-            boolean putIntoOverlapDisjunction = false;
+			ArrayList<Object> constraints = new ArrayList<Object>();
+			boolean exclusion = typ.getChild(0).toStringTree().equals("EXCL");
 
-            int min = 0, max = 0;
-            // possibly several distance constraints
-            for (int i = 0; i < dist_list.getChildCount(); i++) {
-                String direction = dist_list.getChild(i).getChild(0).getChild(0).toStringTree().toLowerCase();
-                String minStr = dist_list.getChild(i).getChild(1).getChild(0).toStringTree();
-                String maxStr = dist_list.getChild(i).getChild(1).getChild(1).toStringTree();
-                String meas = dist_list.getChild(i).getChild(2).getChild(0).toStringTree();
-                if (minStr.equals("VAL0")) {
-                    minStr = "0";
-                }
-                min = Integer.parseInt(minStr);
-                max = Integer.parseInt(maxStr);
-                // If zero word-distance, wrap this sequence in a disjunction along with an overlap position
-                // between the two operands
-     /*   
+			boolean inOrder = false;
+			boolean invertedOperands = false;
+
+			group.put("inOrder", inOrder);
+			group.put("distances", constraints);
+
+			boolean putIntoOverlapDisjunction = false;
+
+			int min = 0, max = 0;
+			// possibly several distance constraints
+			for (int i = 0; i < dist_list.getChildCount(); i++) {
+				String direction = dist_list.getChild(i).getChild(0).getChild(0).toStringTree().toLowerCase();
+				String minStr = dist_list.getChild(i).getChild(1).getChild(0).toStringTree();
+				String maxStr = dist_list.getChild(i).getChild(1).getChild(1).toStringTree();
+				String meas = dist_list.getChild(i).getChild(2).getChild(0).toStringTree();
+				if (minStr.equals("VAL0")) {
+					minStr = "0";
+				}
+				min = Integer.parseInt(minStr);
+				max = Integer.parseInt(maxStr);
+				// If zero word-distance, wrap this sequence in a disjunction along with an overlap position
+				// between the two operands
+				/*   
      	XXX: This is currently deactivated. Uncomment to activate treatment of zero-word distances as overlap-alternatives
      			(see google doc on special distances serialization)
-     	
+
                 if (meas.equals("w") && min == 0) {
                 	min = 1;
                 	putIntoOverlapDisjunction = true;
                 }
-     */
-                if (!meas.equals("w") && min == 0 ) {
-                	processSpanDistance(meas,min,max);
-                }
-                LinkedHashMap<String, Object> distance = makeDistance(meas,min,max);
-                if (exclusion) {
-                    distance.put("exclude", true);
-                }
-//                if (! openNodeCats.get(1).equals("OPNHIT")) {
-                	constraints.add(distance);
-//                }
-                if (i==0) {
-                	if (direction.equals("plus")) {
-                        inOrder = true;
-                    } else if (direction.equals("minus")) {
-                        inOrder = true;
-                        invertedOperands = true;
-                    } else if (direction.equals("both")) {
-                    	inOrder = false;
-                    }
-                }
-            }
-            group.put("inOrder", inOrder);
-            LinkedHashMap<String, Object> embeddedSequence = group;
-            
-            if (! (openNodeCats.get(1).equals("OPBEG") || openNodeCats.get(1).equals("OPEND") || inOPALL || openNodeCats.get(1).equals("OPNHIT"))) {
-                wrapOperandInClass(node,1,classCounter);
-                wrapOperandInClass(node,2,classCounter);
-                group = wrapInReference(group, 1024+classCounter++);
-            } else if (openNodeCats.get(1).equals("OPNHIT")) {
-            	LinkedHashMap<String,Object> repetition = makeRepetition(min, max);
-            	((ArrayList<Object>) repetition.get("operands")).add(makeToken());
-            	// TODO go on with this: put the repetition into a class and put it in between the operands
-            	// -> what if there's several distance constraints. with different keys, like /w4,s0? 
-            }
-            
-            LinkedHashMap<String,Object> sequence = null;
-            if (putIntoOverlapDisjunction) {
-            	sequence = embeddedSequence;
-            	group = makeGroup("or");
-            	ArrayList<Object> disjOperands = (ArrayList<Object>) group.get("operands");
-            	String[] sharedClasses = new String[]{"intersects"};
-            	LinkedHashMap<String,Object> overlapsGroup = makePosition(new String[0], sharedClasses);
-            	
-            	ArrayList<Object> overlapsOperands = (ArrayList<Object>) overlapsGroup.get("operands");
-            	// this ensures identity of the operands lists and thereby a distribution of the operands for both created objects 
-            	sequence.put("operands", overlapsOperands);
-            	if (invertedOperands) {
-                    invertedOperandsLists.push(overlapsOperands);
-            	}
-            	disjOperands.add(overlapsGroup);
-            	disjOperands.add(wrapInReference(sequence, 0));
-            	// Step II: decide where to put
-            	putIntoSuperObject(group, 0);
-            	objectStack.push(sequence);
-            }
-            else {
-            	if (invertedOperands) {
-            		ArrayList<Object> operands = (ArrayList<Object>) embeddedSequence.get("operands");
-                    invertedOperandsLists.push(operands);
-            	}
-            	// Step II: decide where to put
-            	putIntoSuperObject(group, 0);
-            	objectStack.push(embeddedSequence);
-            }
-            stackedObjects++;
-            visited.add(node.getChild(0));
-        }
+				 */
+				if (!meas.equals("w") && min == 0 ) {
+					processSpanDistance(meas,min,max);
+				}
+				LinkedHashMap<String, Object> distance = makeDistance(meas,min,max);
+				if (exclusion) {
+					distance.put("exclude", true);
+				}
+				//                if (! openNodeCats.get(1).equals("OPNHIT")) {
+				constraints.add(distance);
+				//                }
+				if (i==0) {
+					if (direction.equals("plus")) {
+						inOrder = true;
+					} else if (direction.equals("minus")) {
+						inOrder = true;
+						invertedOperands = true;
+					} else if (direction.equals("both")) {
+						inOrder = false;
+					}
+				}
+			}
+			group.put("inOrder", inOrder);
+			LinkedHashMap<String, Object> embeddedSequence = group;
 
-        // inlcusion or overlap
-        if (nodeCat.equals("OPIN") || nodeCat.equals("OPOV")) {
-            // Step I: create group
-        	wrapOperandInClass(node,2,classCounter++);
-        	wrapOperandInClass(node,1,classCounter++);
-//            LinkedHashMap<String, Object> posgroup = makePosition(null);
-            LinkedHashMap<String, Object> posgroup = makeGroup("position");
-            LinkedHashMap<String, Object> positionOptions;
-//            posgroup
-            if (nodeCat.equals("OPIN")) {
-            	positionOptions = parseOPINOptions(node);
-            } else {
-            	positionOptions = parseOPOVOptions(node);
-            }
-            posgroup.put("frames", positionOptions.get("frames"));
-            posgroup.put("frame", positionOptions.get("frame"));
-            if (positionOptions.containsKey("exclude")) {
-            	posgroup.put("exclude", positionOptions.get("exclude"));
-            }
-            if (positionOptions.containsKey("grouping")) {
-            	posgroup.put("grouping", positionOptions.get("grouping"));
-            }
-            objectStack.push(posgroup);
-            // mark this an inverted operands object
-            invertedOperandsLists.push((ArrayList<Object>) posgroup.get("operands"));
-            stackedObjects++;
-            // Step II: wrap in reference and decide where to put
-            ArrayList<String> check = (ArrayList<String>) positionOptions.get("classRefCheck");
-            Integer[] classIn = new Integer[]{1024+classCounter-2,1024+classCounter-1};
-            LinkedHashMap<String, Object> classRefCheck = makeClassRefCheck(check, classIn, 1024+classCounter);
-            ((ArrayList<Object>) classRefCheck.get("operands")).add(posgroup);
-            LinkedHashMap<String, Object> focusGroup = null;
-            if ((boolean) positionOptions.get("matchall") == true) {
-            	focusGroup = makeResetReference();
-            	((ArrayList<Object>) focusGroup.get("operands")).add(classRefCheck);
-            } else { // match only first argument
-            	focusGroup = wrapInReference(classRefCheck, 1024+classCounter-1);
-            }
-            putIntoSuperObject(focusGroup, 1);
-        }
+			if (! (openNodeCats.get(1).equals("OPBEG") || openNodeCats.get(1).equals("OPEND") || inOPALL || openNodeCats.get(1).equals("OPNHIT"))) {
+				wrapOperandInClass(node,1,classCounter);
+				wrapOperandInClass(node,2,classCounter);
+				group = wrapInReference(group, 1024+classCounter++);
+			} else if (openNodeCats.get(1).equals("OPNHIT")) {
+				LinkedHashMap<String,Object> repetition = makeRepetition(min, max);
+				((ArrayList<Object>) repetition.get("operands")).add(makeToken());
+				// TODO go on with this: put the repetition into a class and put it in between the operands
+				// -> what if there's several distance constraints. with different keys, like /w4,s0? 
+			}
 
-        // 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 (operandWrap.containsRow(parent)) {
-        		// Step I: create group
-    			int argNr = nodeCat.equals("ARG1") ? 1 : 2;
+			LinkedHashMap<String,Object> sequence = null;
+			if (putIntoOverlapDisjunction) {
+				sequence = embeddedSequence;
+				group = makeGroup("or");
+				ArrayList<Object> disjOperands = (ArrayList<Object>) group.get("operands");
+				String[] sharedClasses = new String[]{"intersects"};
+				LinkedHashMap<String,Object> overlapsGroup = makePosition(new String[0], sharedClasses);
+
+				ArrayList<Object> overlapsOperands = (ArrayList<Object>) overlapsGroup.get("operands");
+				// this ensures identity of the operands lists and thereby a distribution of the operands for both created objects 
+				sequence.put("operands", overlapsOperands);
+				if (invertedOperands) {
+					invertedOperandsLists.push(overlapsOperands);
+				}
+				disjOperands.add(overlapsGroup);
+				disjOperands.add(wrapInReference(sequence, 0));
+				// Step II: decide where to put
+				putIntoSuperObject(group, 0);
+				objectStack.push(sequence);
+			}
+			else {
+				if (invertedOperands) {
+					ArrayList<Object> operands = (ArrayList<Object>) embeddedSequence.get("operands");
+					invertedOperandsLists.push(operands);
+				}
+				// Step II: decide where to put
+				putIntoSuperObject(group, 0);
+				objectStack.push(embeddedSequence);
+			}
+			stackedObjects++;
+			visited.add(node.getChild(0));
+		}
+
+		// inlcusion or overlap
+		if (nodeCat.equals("OPIN") || nodeCat.equals("OPOV")) {
+			// Step I: create group
+			wrapOperandInClass(node,2,classCounter++);
+			wrapOperandInClass(node,1,classCounter++);
+			//            LinkedHashMap<String, Object> posgroup = makePosition(null);
+			LinkedHashMap<String, Object> posgroup = makeGroup("position");
+			LinkedHashMap<String, Object> positionOptions;
+			//            posgroup
+			if (nodeCat.equals("OPIN")) {
+				positionOptions = parseOPINOptions(node);
+			} else {
+				positionOptions = parseOPOVOptions(node);
+			}
+			posgroup.put("frames", positionOptions.get("frames"));
+			posgroup.put("frame", positionOptions.get("frame"));
+			if (positionOptions.containsKey("exclude")) {
+				posgroup.put("exclude", positionOptions.get("exclude"));
+			}
+			if (positionOptions.containsKey("grouping")) {
+				posgroup.put("grouping", positionOptions.get("grouping"));
+			}
+			objectStack.push(posgroup);
+			// mark this an inverted operands object
+			invertedOperandsLists.push((ArrayList<Object>) posgroup.get("operands"));
+			stackedObjects++;
+			// Step II: wrap in reference and decide where to put
+			ArrayList<String> check = (ArrayList<String>) positionOptions.get("classRefCheck");
+			Integer[] classIn = new Integer[]{1024+classCounter-2,1024+classCounter-1};
+			LinkedHashMap<String, Object> classRefCheck = makeClassRefCheck(check, classIn, 1024+classCounter);
+			((ArrayList<Object>) classRefCheck.get("operands")).add(posgroup);
+			LinkedHashMap<String, Object> focusGroup = null;
+			if ((boolean) positionOptions.get("matchall") == true) {
+				focusGroup = makeResetReference();
+				((ArrayList<Object>) focusGroup.get("operands")).add(classRefCheck);
+			} else { // match only first argument
+				focusGroup = wrapInReference(classRefCheck, 1024+classCounter-1);
+			}
+			putIntoSuperObject(focusGroup, 1);
+		}
+
+		// 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 (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);
-    			}
-        	}
-//        	}
-        }
+					stackedObjects++;
+					putIntoSuperObject(container,1);
+				}
+			}
+			//        	}
+		}
 
-        if (nodeCat.equals("OPALL")) {
-        	inOPALL = true;
-        }
-        
-        if (nodeCat.equals("OPNHIT")) {
-            Integer[] classRef = new Integer[]{1024+classCounter+1, 1024+classCounter+2}; 
-//            classRef.add(classCounter + 1);  // yes, do this twice (two classes)!
-            LinkedHashMap<String, Object> group = makeReference(1024+classCounter);
-            LinkedHashMap<String, Object> classRefCheck = makeClassRefOp("classRefOp:inversion", classRef, classCounter+1024);
-            ArrayList<Object> operands = new ArrayList<Object>();
-            operands.add(classRefCheck);
-            group.put("operands", operands);
-            classCounter++;
-            wrapOperandInClass(node.getChild(0),1,classCounter++); // direct child is OPPROX
-            wrapOperandInClass(node.getChild(0),2,classCounter++);
-            objectStack.push(classRefCheck);
-            stackedObjects++;
-            putIntoSuperObject(group, 1);
-        }
+		if (nodeCat.equals("OPALL")) {
+			inOPALL = true;
+		}
 
-        if (nodeCat.equals("OPEND") || nodeCat.equals("OPBEG")) {
-            // Step I: create group
-            LinkedHashMap<String, Object> beggroup = new LinkedHashMap<String, Object>();
-            beggroup.put("@type", "korap:reference");
-            beggroup.put("operation", "operation:focus");
-            ArrayList<Integer> spanRef = new ArrayList<Integer>();
-            if (nodeCat.equals("OPBEG")) {
-                spanRef.add(0);
-                spanRef.add(1);
-            } else if (nodeCat.equals("OPEND")) {
-                spanRef.add(-1);
-                spanRef.add(1);
-            }
-            beggroup.put("spanRef", spanRef);
-            beggroup.put("operands", new ArrayList<Object>());
-            objectStack.push(beggroup);
-            stackedObjects++;
+		if (nodeCat.equals("OPNHIT")) {
+			Integer[] classRef = new Integer[]{1024+classCounter+1, 1024+classCounter+2}; 
+			//            classRef.add(classCounter + 1);  // yes, do this twice (two classes)!
+			LinkedHashMap<String, Object> group = makeReference(1024+classCounter);
+			LinkedHashMap<String, Object> classRefCheck = makeClassRefOp("classRefOp:inversion", classRef, classCounter+1024);
+			ArrayList<Object> operands = new ArrayList<Object>();
+			operands.add(classRefCheck);
+			group.put("operands", operands);
+			classCounter++;
+			wrapOperandInClass(node.getChild(0),1,classCounter++); // direct child is OPPROX
+			wrapOperandInClass(node.getChild(0),2,classCounter++);
+			objectStack.push(classRefCheck);
+			stackedObjects++;
+			putIntoSuperObject(group, 1);
+		}
 
-            // Step II: decide where to put
-            putIntoSuperObject(beggroup, 1);
-        }
+		if (nodeCat.equals("OPEND") || nodeCat.equals("OPBEG")) {
+			// Step I: create group
+			LinkedHashMap<String, Object> beggroup = new LinkedHashMap<String, Object>();
+			beggroup.put("@type", "korap:reference");
+			beggroup.put("operation", "operation:focus");
+			ArrayList<Integer> spanRef = new ArrayList<Integer>();
+			if (nodeCat.equals("OPBEG")) {
+				spanRef.add(0);
+				spanRef.add(1);
+			} else if (nodeCat.equals("OPEND")) {
+				spanRef.add(-1);
+				spanRef.add(1);
+			}
+			beggroup.put("spanRef", spanRef);
+			beggroup.put("operands", new ArrayList<Object>());
+			objectStack.push(beggroup);
+			stackedObjects++;
 
-        if (nodeCat.equals("OPBED")) {
-            // Step I: create group
-            int optsChild = node.getChildCount() - 1;
-            Tree conditions = node.getChild(optsChild).getChild(0);
+			// Step II: decide where to put
+			putIntoSuperObject(beggroup, 1);
+		}
 
-            // 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(1024+classCounter);
-            ArrayList<Object> submatchoperands = new ArrayList<Object>();
-            submatchgroup.put("operands", submatchoperands);
-            putIntoSuperObject(submatchgroup);
+		if (nodeCat.equals("OPBED")) {
+			// Step I: create group
+			int optsChild = node.getChildCount() - 1;
+			Tree conditions = node.getChild(optsChild).getChild(0);
 
-            // Distinguish two cases. Normal case: query has just one condition, like #BED(X, sa) ...
-            if (conditions.getChildCount() == 1) {
-                CosmasCondition c = new CosmasCondition(conditions.getChild(0));
+			// 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(1024+classCounter);
+			ArrayList<Object> submatchoperands = new ArrayList<Object>();
+			submatchgroup.put("operands", submatchoperands);
+			putIntoSuperObject(submatchgroup);
 
-                // create the group expressing the position constraint
-                String[] frames = new String[]{c.position};
-                String[] sharedClasses = new String[]{};  // OPBED only defines frame constraint, neglects intersection type
-            	LinkedHashMap<String,Object> posgroup = makePosition(frames, sharedClasses);
-//                LinkedHashMap<String, Object> posgroup = makePosition(c.position);
-                ArrayList<Object> operands = (ArrayList<Object>) posgroup.get("operands");
-                if (c.negated) posgroup.put("exclude", true);
+			// Distinguish two cases. Normal case: query has just one condition, like #BED(X, sa) ...
+			if (conditions.getChildCount() == 1) {
+				CosmasCondition c = new CosmasCondition(conditions.getChild(0));
 
-                // create span representing the element expressed in the condition
-                LinkedHashMap<String, Object> bedElem = new LinkedHashMap<String, Object>();
-                bedElem.put("@type", "korap:span");
-                bedElem.put("key", c.elem);
+				// create the group expressing the position constraint
+				String[] frames = new String[]{c.position};
+				String[] sharedClasses = new String[]{};  // OPBED only defines frame constraint, neglects intersection type
+				LinkedHashMap<String,Object> posgroup = makePosition(frames, sharedClasses);
+				//                LinkedHashMap<String, Object> posgroup = makePosition(c.position);
+				ArrayList<Object> operands = (ArrayList<Object>) posgroup.get("operands");
+				if (c.negated) posgroup.put("exclude", true);
 
-                // create a class group containing the argument, in order to submatch the arg.
-                LinkedHashMap<String, Object> classGroup = makeSpanClass(classCounter++);
-                objectStack.push(classGroup);
-                stackedObjects++;
-                operands.add(bedElem);
-                operands.add(classGroup);
-                // Step II: decide where to put
-                submatchoperands.add(posgroup);
+				// create span representing the element expressed in the condition
+				LinkedHashMap<String, Object> bedElem = new LinkedHashMap<String, Object>();
+				bedElem.put("@type", "korap:span");
+				bedElem.put("key", c.elem);
 
-                // ... or the query has several conditions specified, like #BED(XY, sa,-pa). In that case,
-                //     use 'focus' operations to create nested conditions
-            } else {
-                // node has several conditions (like 'sa, -pa')
-                // -> create identity position group and embed all position groups there
-                LinkedHashMap<String, Object> conjunct = makePosition(new String[]{"frames:matches"}, new String[]{"classRefCheck: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>();
+				// create a class group containing the argument, in order to submatch the arg.
+				LinkedHashMap<String, Object> classGroup = makeSpanClass(classCounter++);
+				objectStack.push(classGroup);
+				stackedObjects++;
+				operands.add(bedElem);
+				operands.add(classGroup);
+				// Step II: decide where to put
+				submatchoperands.add(posgroup);
 
-                for (int i = 0; i < conditions.getChildCount(); i++) {
-                    // for each condition, create a position group containing a class group.
-                    // make position group
-                    CosmasCondition c = new CosmasCondition(conditions.getChild(i));
-                    String[] frames = new String[]{c.position};
-                    String[] sharedClasses = new String[]{};  // OPBED only defines frame constraint, neglects intersection type
-                	LinkedHashMap<String,Object> posGroup = makePosition(frames, sharedClasses);
-                    operands.add(posGroup);
-                    if (c.negated) posGroup.put("exclude", "true");
-                    ArrayList<Object> posOperands = new ArrayList<Object>();
+				// ... or the query has several conditions specified, like #BED(XY, sa,-pa). In that case,
+				//     use 'focus' operations to create nested conditions
+			} else {
+				// node has several conditions (like 'sa, -pa')
+				// -> create identity position group and embed all position groups there
+				LinkedHashMap<String, Object> conjunct = makePosition(new String[]{"frames:matches"}, new String[]{"classRefCheck: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>();
 
-                    // make class group
-                    LinkedHashMap<String, Object> classGroup = makeSpanClass(classCounter++);
-                    classGroup.put("operands", distributedOperands);
+				for (int i = 0; i < conditions.getChildCount(); i++) {
+					// for each condition, create a position group containing a class group.
+					// make position group
+					CosmasCondition c = new CosmasCondition(conditions.getChild(i));
+					String[] frames = new String[]{c.position};
+					String[] sharedClasses = new String[]{};  // OPBED only defines frame constraint, neglects intersection type
+					LinkedHashMap<String,Object> posGroup = makePosition(frames, sharedClasses);
+					operands.add(posGroup);
+					if (c.negated) posGroup.put("exclude", "true");
+					ArrayList<Object> posOperands = new ArrayList<Object>();
 
-                    // put the span and the class group into the position group
-                    posGroup.put("operands", posOperands);
-                    LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
-                    posOperands.add(span);
-                    posOperands.add(classGroup);
-                    span.put("@type", "korap:span");
-                    span.put("key", c.elem);
-                    objectStack.push(classGroup);
-                }
-                submatchoperands.add(conjunct);
-            }
+					// make class group
+					LinkedHashMap<String, Object> classGroup = makeSpanClass(classCounter++);
+					classGroup.put("operands", distributedOperands);
 
-        }
-        objectsToPop.push(stackedObjects);
-        toWrapsToPop.push(stackedToWrap);
-		
+					// put the span and the class group into the position group
+					posGroup.put("operands", posOperands);
+					LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
+					posOperands.add(span);
+					posOperands.add(classGroup);
+					span.put("@type", "korap:span");
+					span.put("key", c.elem);
+					objectStack.push(classGroup);
+				}
+				submatchoperands.add(conjunct);
+			}
+
+		}
+		objectsToPop.push(stackedObjects);
+		toWrapsToPop.push(stackedToWrap);
+
 		/*
 		 ****************************************************************
 		 **************************************************************** 
@@ -702,458 +683,460 @@
 		 ****************************************************************
 		 ****************************************************************
 		 */
-        for (int i = 0; i < node.getChildCount(); i++) {
-            Tree child = node.getChild(i);
-            processNode(child);
-        }
-		
+		for (int i = 0; i < node.getChildCount(); i++) {
+			Tree child = node.getChild(i);
+			processNode(child);
+		}
+
 		/*
 		 **************************************************************
 		 * Stuff that happens after processing the children of a node *
 		 **************************************************************
 		 */
 
-        // remove sequence from object stack if node is implicitly sequenced
-        if (sequencedNodes.size() > 0) {
-            if (node == sequencedNodes.getFirst()) {
-                objectStack.pop();
-                sequencedNodes.pop();
-            }
-        }
+		// remove sequence from object stack if node is implicitly sequenced
+		if (sequencedNodes.size() > 0) {
+			if (node == sequencedNodes.getFirst()) {
+				objectStack.pop();
+				sequencedNodes.pop();
+			}
+		}
 
-        for (int i = 0; i < objectsToPop.get(0); i++) {
-            objectStack.pop();
-        }
-        objectsToPop.pop();
-        
-        
-//        if (!toWrapStack.isEmpty()) System.err.println(toWrapStack.get(0)[0]);
-        for (int i = 0; i < toWrapsToPop.get(0); i++) {
-            putIntoSuperObject(wrap(toWrapStack.pop()));
-        }
-        toWrapsToPop.pop();
+		for (int i = 0; i < objectsToPop.get(0); i++) {
+			objectStack.pop();
+		}
+		objectsToPop.pop();
 
-        if (nodeCat.equals("ARG2") && openNodeCats.get(1).equals("OPNOT")) {
-            negate = false;
-        }
-        
-        if (nodeCat.equals("OPALL")) {
-        	inOPALL = false;
-        }
-        
-        openNodeCats.pop();
-    }
 
-    private void processSpanDistance(String meas, int min, int max) {
+		//        if (!toWrapStack.isEmpty()) System.err.println(toWrapStack.get(0)[0]);
+		for (int i = 0; i < toWrapsToPop.get(0); i++) {
+			putIntoSuperObject(wrap(toWrapStack.pop()));
+		}
+		toWrapsToPop.pop();
+
+		if (nodeCat.equals("ARG2") && openNodeCats.get(1).equals("OPNOT")) {
+			negate = false;
+		}
+
+		if (nodeCat.equals("OPALL")) {
+			inOPALL = false;
+		}
+
+		openNodeCats.pop();
+	}
+
+	private void processSpanDistance(String meas, int min, int max) {
 		// TODO Do stuff here in case we'll decide one day to treat span distances in a special way.
 	}
 
 	/**
-     * Registers an entry in the {@link #operandWrap} table in order to allow an operator's arguments
-     * (or only one of them) to be wrapped in a class group.
-     * @param node The operator node (parent node of the ARG1/ARG2 node)
-     * @param arg The argument number (1 or 2)
-     * @param cls The class id.
-     */
-    private void wrapOperandInClass(Tree node, int arg, int cls) {
-    	LinkedHashMap<String,Object> clsGroup = makeSpanClass(cls);
+	 * Registers an entry in the {@link #operandWrap} table in order to allow an operator's arguments
+	 * (or only one of them) to be wrapped in a class group.
+	 * @param node The operator node (parent node of the ARG1/ARG2 node)
+	 * @param arg The argument number (1 or 2)
+	 * @param cls The class id.
+	 */
+	private void wrapOperandInClass(Tree node, int arg, int cls) {
+		LinkedHashMap<String,Object> clsGroup = makeSpanClass(cls);
 		wrapOperand(node,arg,clsGroup);
 	}
 
-    /**
-     * Registers an entry in the {@link #operandWrap} table in order to allow an operator's arguments
-     * (or only one of them) to be wrapped in an arbitrary object, e.g. a reference group.
-     * @param node The operator node (parent node of the ARG1/ARG2 node)
-     * @param arg The argument number (1 or 2)
-     * @param container The object in whose operand list the argument shall be wrapped.
-     */
-    private void wrapOperand(Tree node, int arg, LinkedHashMap<String, Object> container) {
-    	operandWrap.put(node, arg, container);
-  	}
+	/**
+	 * Registers an entry in the {@link #operandWrap} table in order to allow an operator's arguments
+	 * (or only one of them) to be wrapped in an arbitrary object, e.g. a reference group.
+	 * @param node The operator node (parent node of the ARG1/ARG2 node)
+	 * @param arg The argument number (1 or 2)
+	 * @param container The object in whose operand list the argument shall be wrapped.
+	 */
+	private void wrapOperand(Tree node, int arg, LinkedHashMap<String, Object> container) {
+		operandWrap.put(node, arg, container);
+	}
 
 	private Object translateMorph(String layer) {
-        // todo: not very nicely solved! Does this require extension somehow? if not, why not use simple string comparison?!
-//        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
-//        map.put("ANA", "pos");
-//        if (map.containsKey(layer))
-//            return map.get(layer);
-//        else
-//            return layer;
-        if (layer.equals("ANA"))
-            return ResourceMapper.descriptor2policy("ANA");
-        else
-            return layer;
+		// todo: not very nicely solved! Does this require extension somehow? if not, why not use simple string comparison?!
+		//        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
+		//        map.put("ANA", "pos");
+		//        if (map.containsKey(layer))
+		//            return map.get(layer);
+		//        else
+		//            return layer;
+		if (layer.equals("ANA"))
+			return ResourceMapper.descriptor2policy("ANA");
+		else
+			return layer;
 
-    }
+	}
 
-    @SuppressWarnings("unchecked")
+	@SuppressWarnings("unchecked")
 	private LinkedHashMap<String, Object> parseOPINOptions(Tree node) {
-        Tree posnode = getFirstChildWithCat(node, "POS");
-        Tree rangenode = getFirstChildWithCat(node, "RANGE");
-        Tree exclnode = getFirstChildWithCat(node, "EXCL");
-        Tree groupnode = getFirstChildWithCat(node, "GROUP");
-        boolean negatePosition = false;
-        LinkedHashMap<String, Object> posOptions = new LinkedHashMap<String, Object>();
-        ArrayList<String> positions = new ArrayList<String>();
-        ArrayList<String> classRefCheck = new ArrayList<String>();
-        posOptions.put("matchall", false);
-        String frame = "";
-        String posOption = null; 
-        if (posnode != null) {
-            posOption = posnode.getChild(0).toStringTree();
-            switch (posOption) {
-            case "L":
-                positions.add("frames:startswith");
-                classRefCheck.add("classRefCheck:includes");
-                frame = "startswith";
-                break;
-            case "R":
-            	positions.add("frames:endswith");
-                classRefCheck.add("classRefCheck:includes");
-                frame = "endswith";
-                break;
-            case "F":
-            	positions.add("frames:matches");
-                classRefCheck.add("classRefCheck:includes");
-                frame = "matches";
-                break;
-            case "FE":
-            	positions.add("frames:matches");
-                classRefCheck.add("classRefCheck:equals");
-                frame = "matches";
-                break;
-            case "FI":
-            	positions.add("frames:matches");
-            	classRefCheck.add("classRefCheck:unequals");
-                classRefCheck.add("classRefCheck:includes");
-                frame = "matches-noident";
-                break;
-            case "N": 
-            	positions.add("frames:contains");
-                classRefCheck.add("classRefCheck:includes");
-                frame = "contains";
-                break;
-            }
-        } else {
-        	classRefCheck.add("classRefCheck:includes");
-        	frame = "contains";
-        }
-        posOptions.put("frames", positions);
-        posOptions.put("classRefCheck", classRefCheck);
-        posOptions.put("frame", "frame:"+frame);
-        announcements.add("Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. " +
+		Tree posnode = getFirstChildWithCat(node, "POS");
+		Tree rangenode = getFirstChildWithCat(node, "RANGE");
+		Tree exclnode = getFirstChildWithCat(node, "EXCL");
+		Tree groupnode = getFirstChildWithCat(node, "GROUP");
+		boolean negatePosition = false;
+		LinkedHashMap<String, Object> posOptions = new LinkedHashMap<String, Object>();
+		ArrayList<String> positions = new ArrayList<String>();
+		ArrayList<String> classRefCheck = new ArrayList<String>();
+		posOptions.put("matchall", false);
+		String frame = "";
+		String posOption = null; 
+		if (posnode != null) {
+			posOption = posnode.getChild(0).toStringTree();
+			switch (posOption) {
+			case "L":
+				positions.add("frames:startswith");
+				classRefCheck.add("classRefCheck:includes");
+				frame = "startswith";
+				break;
+			case "R":
+				positions.add("frames:endswith");
+				classRefCheck.add("classRefCheck:includes");
+				frame = "endswith";
+				break;
+			case "F":
+				positions.add("frames:matches");
+				classRefCheck.add("classRefCheck:includes");
+				frame = "matches";
+				break;
+			case "FE":
+				positions.add("frames:matches");
+				classRefCheck.add("classRefCheck:equals");
+				frame = "matches";
+				break;
+			case "FI":
+				positions.add("frames:matches");
+				classRefCheck.add("classRefCheck:unequals");
+				classRefCheck.add("classRefCheck:includes");
+				frame = "matches-noident";
+				break;
+			case "N": 
+				positions.add("frames:contains");
+				classRefCheck.add("classRefCheck:includes");
+				frame = "contains";
+				break;
+			}
+		} else {
+			classRefCheck.add("classRefCheck:includes");
+			frame = "contains";
+		}
+		posOptions.put("frames", positions);
+		posOptions.put("classRefCheck", classRefCheck);
+		posOptions.put("frame", "frame:"+frame);
+		announcements.add("Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. " +
 				"Position frames are now expressed through 'frames' and 'sharedClasses'");
-        
-        if (exclnode != null) {
-            if (exclnode.getChild(0).toStringTree().equals("YES")) {
-                negatePosition = !negatePosition;
-            }
-        }
-        
-        if (rangenode != null) {
-            String range = rangenode.getChild(0).toStringTree().toLowerCase();
-            if (range.equals("all")) {
-            	posOptions.put("matchall", true);
-//            	LinkedHashMap<String,Object> ref = makeResetReference(); // reset all defined classes
-//            	wrapOperand(node,2,ref);
-            }
-        }
 
-        if (negatePosition) {
-        	posOptions.put("exclude", "true");
-        }
+		if (exclnode != null) {
+			if (exclnode.getChild(0).toStringTree().equals("YES")) {
+				negatePosition = !negatePosition;
+			}
+		}
 
-        if (groupnode != null) {
-            String grouping = groupnode.getChild(0).toStringTree().equals("max") ? "true" : "false";
-            posOptions.put("grouping", grouping);
-        }
-        return posOptions;
-    }
+		if (rangenode != null) {
+			String range = rangenode.getChild(0).toStringTree().toLowerCase();
+			if (range.equals("all")) {
+				posOptions.put("matchall", true);
+				//            	LinkedHashMap<String,Object> ref = makeResetReference(); // reset all defined classes
+				//            	wrapOperand(node,2,ref);
+			}
+		}
 
-  
+		if (negatePosition) {
+			posOptions.put("exclude", "true");
+		}
+
+		if (groupnode != null) {
+			String grouping = groupnode.getChild(0).toStringTree().equals("max") ? "true" : "false";
+			posOptions.put("grouping", grouping);
+		}
+		return posOptions;
+	}
+
+
 
 	private LinkedHashMap<String, Object> parseOPOVOptions(Tree node) {
-    	boolean negatePosition = false;
-        Tree posnode = getFirstChildWithCat(node, "POS");
-        Tree rangenode = getFirstChildWithCat(node, "RANGE");
-        Tree exclnode = getFirstChildWithCat(node, "EXCL");
-        Tree groupnode = getFirstChildWithCat(node, "GROUP");
-        LinkedHashMap<String, Object> posOptions = new LinkedHashMap<String, Object>();
-        ArrayList<String> positions = new ArrayList<String>();
-        ArrayList<String> classRefCheck = new ArrayList<String>();
-        posOptions.put("matchall", false);
-        String frame = "";
-        String posOption = null; 
-        if (posnode != null) {
-            posOption = posnode.getChild(0).toStringTree();
-            switch (posOption) {
-            case "L":
-                positions.add("frames:startswith");
-                positions.add("frames:overlapsLeft");
-                classRefCheck.add("classRefCheck:intersects");
-                frame = "overlapsLeft";
-                break;
-            case "R":
-            	positions.add("frames:endswith");
-            	positions.add("frames:overlapsRight");
-                classRefCheck.add("classRefCheck:intersects");
-                frame = "overlapsRight";
-                break;
-            case "F":
-            	positions.add("frames:matches");
-                classRefCheck.add("classRefCheck:intersects");
-                frame = "matches";
-                break;
-            case "FE":
-            	positions.add("frames:matches");
-                classRefCheck.add("classRefCheck:equals");
-                frame = "matches";
-                break;
-            case "FI":
-            	positions.add("frames:matches");
-            	classRefCheck.add("classRefCheck:unequals");
-            	frame = "matches-noident";
-                break;
-            case "X": 
-            	positions.add("frames:contains");
-                classRefCheck.add("classRefCheck:intersects");
-                frame = "overlaps";
-                break;
-            }
-        } else {
-        	classRefCheck.add("classRefCheck:intersects");
-        	frame = "overlaps";
-        }
-        
-        posOptions.put("frames", positions);
-        posOptions.put("classRefCheck", classRefCheck);
-        posOptions.put("frame", "frame:"+frame);
-        announcements.add("Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. " +
+		boolean negatePosition = false;
+		Tree posnode = getFirstChildWithCat(node, "POS");
+		Tree rangenode = getFirstChildWithCat(node, "RANGE");
+		Tree exclnode = getFirstChildWithCat(node, "EXCL");
+		Tree groupnode = getFirstChildWithCat(node, "GROUP");
+		LinkedHashMap<String, Object> posOptions = new LinkedHashMap<String, Object>();
+		ArrayList<String> positions = new ArrayList<String>();
+		ArrayList<String> classRefCheck = new ArrayList<String>();
+		posOptions.put("matchall", false);
+		String frame = "";
+		String posOption = null; 
+		if (posnode != null) {
+			posOption = posnode.getChild(0).toStringTree();
+			switch (posOption) {
+			case "L":
+				positions.add("frames:startswith");
+				positions.add("frames:overlapsLeft");
+				classRefCheck.add("classRefCheck:intersects");
+				frame = "overlapsLeft";
+				break;
+			case "R":
+				positions.add("frames:endswith");
+				positions.add("frames:overlapsRight");
+				classRefCheck.add("classRefCheck:intersects");
+				frame = "overlapsRight";
+				break;
+			case "F":
+				positions.add("frames:matches");
+				classRefCheck.add("classRefCheck:intersects");
+				frame = "matches";
+				break;
+			case "FE":
+				positions.add("frames:matches");
+				classRefCheck.add("classRefCheck:equals");
+				frame = "matches";
+				break;
+			case "FI":
+				positions.add("frames:matches");
+				classRefCheck.add("classRefCheck:unequals");
+				frame = "matches-noident";
+				break;
+			case "X": 
+				positions.add("frames:contains");
+				classRefCheck.add("classRefCheck:intersects");
+				frame = "overlaps";
+				break;
+			}
+		} else {
+			classRefCheck.add("classRefCheck:intersects");
+			frame = "overlaps";
+		}
+
+		posOptions.put("frames", positions);
+		posOptions.put("classRefCheck", classRefCheck);
+		posOptions.put("frame", "frame:"+frame);
+		announcements.add("Deprecated 2014-09-22: 'frame' only to be supported until 3 months from deprecation date. " +
 				"Position frames are now expressed through 'frames' and 'sharedClasses'");
 
-        if (exclnode != null) {
-            if (exclnode.getChild(0).toStringTree().equals("YES")) {
-                negatePosition = !negatePosition;
-            }
-        }
-        
-        if (rangenode != null) {
-            String range = rangenode.getChild(0).toStringTree().toLowerCase();
-            if (range.equals("all")) {
-            	posOptions.put("matchall", true);
-//            	LinkedHashMap<String,Object> ref = makeResetReference(); // reset all defined classes
-//            	wrapOperand(node,2,ref);
-            }
-        }
+		if (exclnode != null) {
+			if (exclnode.getChild(0).toStringTree().equals("YES")) {
+				negatePosition = !negatePosition;
+			}
+		}
 
-        if (negatePosition) {
-        	posOptions.put("exclude", "true");
-        }
+		if (rangenode != null) {
+			String range = rangenode.getChild(0).toStringTree().toLowerCase();
+			if (range.equals("all")) {
+				posOptions.put("matchall", true);
+				//            	LinkedHashMap<String,Object> ref = makeResetReference(); // reset all defined classes
+				//            	wrapOperand(node,2,ref);
+			}
+		}
 
-        if (groupnode != null) {
-            String grouping = groupnode.getChild(0).toStringTree().equals("max") ? "true" : "false";
-            posOptions.put("grouping", grouping);
-        }
-        return posOptions;
-    }
+		if (negatePosition) {
+			posOptions.put("exclude", "true");
+		}
 
-    @SuppressWarnings({ "unchecked" })
+		if (groupnode != null) {
+			String grouping = groupnode.getChild(0).toStringTree().equals("max") ? "true" : "false";
+			posOptions.put("grouping", grouping);
+		}
+		return posOptions;
+	}
+
+	@SuppressWarnings({ "unchecked" })
 	private LinkedHashMap<String,Object> wrap(LinkedHashMap[] wrapCascade) {
-    	int i;
-    	for (i=0; i<wrapCascade.length-1; i++) {
-    		ArrayList<Object> containerOperands = (ArrayList<Object>) wrapCascade[i+1].get("operands");
-    		containerOperands.add(0,wrapCascade[i]);
-    	}
-    	return wrapCascade[i];
-    }
-    
-    private LinkedHashMap<String,Object> processPositionOption(String posOption) {
-    	LinkedHashMap<String,Object> posgroup = null;
+		int i;
+		for (i=0; i<wrapCascade.length-1; i++) {
+			ArrayList<Object> containerOperands = (ArrayList<Object>) wrapCascade[i+1].get("operands");
+			containerOperands.add(0,wrapCascade[i]);
+		}
+		return wrapCascade[i];
+	}
 
-    	if (posOption.equals("F") || posOption.equals("FI")) {
-    		posgroup = makePosition("startswith");
-    		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};
-    		}
+	private LinkedHashMap<String,Object> processPositionOption(String posOption) {
+		LinkedHashMap<String,Object> posgroup = null;
 
-    		toWrapStack.push(toWrap);
-    		stackedToWrap++;
-//    		wrapOperandInClass(node,1,classCounter+1);
-//    		wrapOperandInClass(node,2,classCounter);
-//    		wrapFirstOpInClass = classCounter+1;
-//    		wrapSecondOpInClass = classCounter;
-    	}
-    	
-    	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 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;
-//    }
+		if (posOption.equals("F") || posOption.equals("FI")) {
+			posgroup = makePosition("startswith");
+			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};
+			}
 
-    LinkedList<ArrayList<Object>> nestedDistOperands = new LinkedList<ArrayList<Object>>();  
-    
-    @SuppressWarnings("unchecked")
-    private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
+			toWrapStack.push(toWrap);
+			stackedToWrap++;
+			//    		wrapOperandInClass(node,1,classCounter+1);
+			//    		wrapOperandInClass(node,2,classCounter);
+			//    		wrapFirstOpInClass = classCounter+1;
+			//    		wrapSecondOpInClass = classCounter;
+		}
+
+		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 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>>();  
+
+	@SuppressWarnings("unchecked")
+	private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
 		if (objectStack.size() > objStackPosition) {
-    		ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
-    		if (!invertedOperandsLists.contains(topObjectOperands)) {
-    			topObjectOperands.add(object);
-    		} else {
-    			topObjectOperands.add(0, object);
-    		}
+			ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
+			if (!invertedOperandsLists.contains(topObjectOperands)) {
+				topObjectOperands.add(object);
+			} else {
+				topObjectOperands.add(0, object);
+			}
 
-    	} else {
-    		requestMap.put("query", object);
-    	}
-    }
+		} else {
+			requestMap.put("query", object);
+		}
+	}
 
-    private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
-        putIntoSuperObject(object, 0);
-    }
+	private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
+		putIntoSuperObject(object, 0);
+	}
 
 
-    private Tree parseCosmasQuery(String q) throws RecognitionException {
-        q = rewritePositionQuery(q);
-    	
-        Tree tree = null;
-        ANTLRStringStream ss = new ANTLRStringStream(q);
-        c2psLexer lex = new c2psLexer(ss);
-        org.antlr.runtime.CommonTokenStream tokens = new org.antlr.runtime.CommonTokenStream(lex);  //v3
-        parser = new c2psParser(tokens);
-        c2psParser.c2ps_query_return c2Return = ((c2psParser) parser).c2ps_query();  // statt t().
-        // AST Tree anzeigen:
-        tree = (Tree) c2Return.getTree();
+	private Tree parseCosmasQuery(String q) throws RecognitionException {
+		q = rewritePositionQuery(q);
 
-        String treestring = tree.toStringTree();
-        if (treestring.contains("<mismatched token") || treestring.contains("<error") || treestring.contains("<unexpected")) {
-            log.error("Invalid tree. Could not parse Cosmas query. Make sure it is well-formed.");
-            throw new RecognitionException();
-        }
+		Tree tree = null;
+		ANTLRStringStream ss = new ANTLRStringStream(q);
+		c2psLexer lex = new c2psLexer(ss);
+		org.antlr.runtime.CommonTokenStream tokens = new org.antlr.runtime.CommonTokenStream(lex);  //v3
+		parser = new c2psParser(tokens);
+		c2psParser.c2ps_query_return c2Return = ((c2psParser) parser).c2ps_query();  // statt t().
+		// AST Tree anzeigen:
+		tree = (Tree) c2Return.getTree();
 
-        return tree;
-    }
+		String treestring = tree.toStringTree();
+		if (treestring.contains("<mismatched token") || treestring.contains("<error") || treestring.contains("<unexpected")) {
+			log.error("Invalid tree. Could not parse Cosmas query. Make sure it is well-formed.");
+			throw new RecognitionException();
+		}
 
-    /**
-     * Normalises position operators to equivalents using #BED  
-     */
-    private String rewritePositionQuery(String q) {
-    	Pattern p = Pattern.compile("(\\w+):((\\+|-)?(sa|se|pa|pe|ta|te),?)+");
-        Matcher m = p.matcher(q);
-      
-        String rewrittenQuery = q;
-        while (m.find()) {
-            String match = m.group();
-            String conditionsString = match.split(":")[1];
-            Pattern conditionPattern = Pattern.compile("(\\+|-)?(sa|se|pa|pe|ta|te)");
-            Matcher conditionMatcher = conditionPattern.matcher(conditionsString);
-            String replacement = "#BED(" + m.group(1) + " , ";
-            while (conditionMatcher.find()) {
-                replacement = replacement + conditionMatcher.group() + ",";
-            }
-            replacement = replacement.substring(0, replacement.length() - 1) + ")"; //remove trailing comma and close parenthesis
-            rewrittenQuery = rewrittenQuery.replace(match, replacement);
-        }
-        return rewrittenQuery;
+		return tree;
 	}
 
 	/**
-     * @param args
-     */
-    public static void main(String[] args) {
+	 * Normalises position operators to equivalents using #BED  
+	 */
+	private String rewritePositionQuery(String q) {
+		Pattern p = Pattern.compile("(\\w+):((\\+|-)?(sa|se|pa|pe|ta|te),?)+");
+		Matcher m = p.matcher(q);
+
+		String rewrittenQuery = q;
+		while (m.find()) {
+			String match = m.group();
+			String conditionsString = match.split(":")[1];
+			Pattern conditionPattern = Pattern.compile("(\\+|-)?(sa|se|pa|pe|ta|te)");
+			Matcher conditionMatcher = conditionPattern.matcher(conditionsString);
+			String replacement = "#BED(" + m.group(1) + " , ";
+			while (conditionMatcher.find()) {
+				replacement = replacement + conditionMatcher.group() + ",";
+			}
+			replacement = replacement.substring(0, replacement.length() - 1) + ")"; //remove trailing comma and close parenthesis
+			rewrittenQuery = rewrittenQuery.replace(match, replacement);
+		}
+		return rewrittenQuery;
+	}
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
 		/*
 		 * For debugging
 		 */
-        String[] queries = new String[]{
+		String[] queries = new String[]{
 				/* COSMAS 2 */
-//                "wegen #OV(x) <s>",
-//                "wegen #IN(L) <s>",
-//                "#NHIT(gehen /w1:10 voran)",
-//                "wegen #OV(FI) <s>",
-//                "Sonne /+w4 Mond",
-//                "#BEG(der /w3:5 Mann) /+w10 kommt",
-//                "Sonne /s0 Mond"
-//                "Sonne /+w4 Mond",
-//                "#BED(der Mann , sa,-pa)",
-//        		"Sonne /+w1:4 Mond /-w1:7 Sterne",
-//        		"wegen #IN('FE,ALL,%,MIN') <s>",
-//        		"#NHIT(gehen /w1:10 voran)"
-//        		"MORPH(V PRES IND)",
-//                "wegen #OV(F) <s>"
-//        		"Sonne /s0 Mond",
-        		"Sonne /+w1:4 Mond /-w1:7 Sterne",
-        		"Der:ta",
-        		"&mond-",
-        		"gehen /+w10 voran %w10 Beispiel",
-        		"(gehen /+w10 voran) %w10 Beispiel",
-        		"#BED(der Mann , sa,-pa)"
-        };
-//		CosmasTree.verbose=true;
-        for (String q : queries) {
-            try {
-                System.out.println(q);
-                try {
-                    CosmasTree act = new CosmasTree(q);
-                    System.out.println(act.parseCosmasQuery(q).toStringTree());
-                } catch (QueryException e) {
-                    e.printStackTrace();
-                } catch (RecognitionException e) {
-                    e.printStackTrace();
-                }
-                System.out.println();
+				//                "wegen #OV(x) <s>",
+				//                "wegen #IN(L) <s>",
+				//                "#NHIT(gehen /w1:10 voran)",
+				//                "wegen #OV(FI) <s>",
+				//                "Sonne /+w4 Mond",
+				//                "#BEG(der /w3:5 Mann) /+w10 kommt",
+				//                "Sonne /s0 Mond"
+				//                "Sonne /+w4 Mond",
+				//                "#BED(der Mann , sa,-pa)",
+				//        		"Sonne /+w1:4 Mond /-w1:7 Sterne",
+				//        		"wegen #IN('FE,ALL,%,MIN') <s>",
+				//        		"#NHIT(gehen /w1:10 voran)"
+				//        		"MORPH(V PRES IND)",
+				//                "wegen #OV(F) <s>"
+				//        		"Sonne /s0 Mond",
+				"Sonne /+w1:4 Mond /-w1:7 Sterne",
+				"Der:ta",
+				"&mond-",
+				"gehen /+w10 voran %w10 Beispiel",
+				"(gehen /+w10 voran) %w10 Beispiel",
+				"#BED(der Mann , sa,-pa)",
+				"MORPH(foundry/layer=key)",
+				"MORPH(f/l!=k &f/l!=k)",
+		};
+		//		CosmasTree.verbose=true;
+		for (String q : queries) {
+			try {
+				System.out.println(q);
+				try {
+					CosmasTree act = new CosmasTree(q);
+					System.out.println(act.parseCosmasQuery(q).toStringTree());
+				} catch (QueryException e) {
+					e.printStackTrace();
+				} catch (RecognitionException e) {
+					e.printStackTrace();
+				}
+				System.out.println();
 
-            } catch (NullPointerException npe) {
-                npe.printStackTrace();
-                System.out.println("null\n");
-            }
-        }
-    }
+			} catch (NullPointerException npe) {
+				npe.printStackTrace();
+				System.out.println("null\n");
+			}
+		}
+	}
 }
\ No newline at end of file
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 8124abc..bb78e03 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
@@ -20,6 +20,7 @@
 public class PoliqarpPlusTree extends Antlr4AbstractSyntaxTree {
 
 	private static Logger log = LoggerFactory.getLogger(PoliqarpPlusTree.class);
+	private int classCounter = 1024;
 
 	/**
 	 * Most centrally, this class maintains a set of nested maps and lists which represent the JSON tree, which is built by the JSON serialiser
@@ -101,7 +102,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]);
@@ -115,7 +116,7 @@
 			objectStack.push(sequence);
 			stackedObjects++;
 		}
-		
+
 		/*
 		 * empty tokens at beginning/end of sequence
 		 */
@@ -134,7 +135,7 @@
 			objectStack.push(object);
 			stackedObjects++;
 		}
-		
+
 		if (nodeCat.equals("emptyTokenSequenceClass")) {
 			Integer[] minmax = parseDistance(node);
 			int classId = 0;
@@ -146,7 +147,7 @@
 			objectStack.push(classGroup);
 			stackedObjects++;
 		}
-		
+
 
 		if (nodeCat.equals("token")) {
 			LinkedHashMap<String,Object> token = makeToken();
@@ -158,7 +159,7 @@
 			if (getNodeCat(node.getChild(0)).equals("key")) {
 				// no 'term' child, but direct key specification: process here
 				LinkedHashMap<String,Object> term = makeTerm();
-				
+
 				String key = node.getChild(0).getText();
 				if (getNodeCat(node.getChild(0).getChild(0)).equals("regex")) {
 					isRegex = true;
@@ -196,10 +197,23 @@
 		}
 
 		if (nodeCat.equals("alignment")) {
-			LinkedHashMap<String,Object> aligned = makeGroup("alignment");
-			aligned.put("align", "align:left");
-			putIntoSuperObject(aligned);
-			objectStack.push(aligned);
+			LinkedHashMap<String,Object> alignClass = makeSpanClass(++classCounter,false);
+			LinkedHashMap<String,Object> metaMap = (LinkedHashMap<String, Object>) requestMap.get("meta");
+			if (metaMap.containsKey("alignment")) {
+				ArrayList<Integer> alignedClasses = new ArrayList<Integer>();
+				try {
+					alignedClasses = (ArrayList<Integer>) metaMap.get("alignment"); 
+				} catch (ClassCastException cce) {
+					alignedClasses.add((Integer) metaMap.get("alignment"));
+				}
+				alignedClasses.add(classCounter);
+				metaMap.put("alignment", alignedClasses);
+			} else {
+				metaMap.put("alignment", classCounter);
+			}
+
+			putIntoSuperObject(alignClass);
+			objectStack.push(alignClass);
 			stackedObjects++;
 		}
 
@@ -281,7 +295,7 @@
 			objectStack.push(relationGroup);
 			stackedObjects++;
 		}
-		
+
 		if (nodeCat.equals("spanclass")) {
 			// Step I: get info
 			int classId = 0;
@@ -371,7 +385,7 @@
 			stackedObjects++;
 			visited.add(node.getChild(0));
 		}
-		
+
 		if (nodeCat.equals("meta")) {
 			LinkedHashMap<String, Object> metaFilter = new LinkedHashMap<String, Object>();
 			requestMap.put("meta", metaFilter);
@@ -455,26 +469,26 @@
 	private LinkedHashMap<String,Object> parseFrame(ParseTree node) {
 		String operator = node.toStringTree(parser).toLowerCase();
 		String[] frames = new String[]{""};
-		String[] sharedClasses = new String[]{"sharedClasses:includes"};
+		String[] classRefCheck = new String[]{"classRefCheck:includes"};
 		switch (operator) {
-			case "contains":
-				frames = new String[]{};
-				break;
-			case "matches":
-				frames = new String[]{"frame:matches"};
-				break;
-			case "startswith":
-				frames = new String[]{"frame:startswith"};
-				break;
-			case "endswith":
-				frames = new String[]{"frame:endswith"};
-				break;	
-			case "overlaps":
-				frames = new String[]{"frame:overlapsLeft","frame:overlapsRight"};
-				sharedClasses = new String[]{"sharedClasses:intersects"};
-				break;
+		case "contains":
+			frames = new String[]{"frames:contains"};
+			break;
+		case "matches":
+			frames = new String[]{"frames:matches"};
+			break;
+		case "startswith":
+			frames = new String[]{"frames:startswith"};
+			break;
+		case "endswith":
+			frames = new String[]{"frames:endswith"};
+			break;	
+		case "overlaps":
+			frames = new String[]{"frames:overlapsLeft","frames:overlapsRight"};
+			classRefCheck = new String[]{"classRefCheck:intersects"};
+			break;
 		}
-		return makePosition(frames,sharedClasses);
+		return makePosition(frames,classRefCheck);
 	}
 
 
@@ -482,7 +496,7 @@
 			ParseTree node, boolean negated) {
 		return parseTermOrTermGroup(node, negated, "token");
 	}
-	
+
 	/**
 	 * Parses a (term) or (termGroup) node
 	 * @param node
@@ -611,11 +625,11 @@
 		Integer max = minmax[1];
 		min++;
 		if (max != null) max++;
-//		min = cropToMaxValue(min);
-//		max = cropToMaxValue(max);
+		//		min = cropToMaxValue(min);
+		//		max = cropToMaxValue(max);
 		return new Integer[]{min, max};
 	}
-	
+
 	private Integer[] parseEmptySegments(ParseTree emptySegments) {
 		Integer min = 0;
 		Integer max = 0;
@@ -638,8 +652,8 @@
 				}
 			}
 		}
-//		min = cropToMaxValue(min);
-//		max = cropToMaxValue(max);
+		//		min = cropToMaxValue(min);
+		//		max = cropToMaxValue(max);
 		return new Integer[]{min, max};
 	}
 
diff --git a/src/test/java/AqlTreeTest.java b/src/test/java/AqlTreeTest.java
index b3ad0fc..d10b07c 100644
--- a/src/test/java/AqlTreeTest.java
+++ b/src/test/java/AqlTreeTest.java
@@ -20,7 +20,7 @@
 	
 	@Test
 	public void testContext() throws QueryException {
-		String contextString = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld";
+		String contextString = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld";
 		aqlt = new AqlTree("Test");
 		assertEquals(contextString.replaceAll(" ", ""), aqlt.getRequestMap().get("@context").toString().replaceAll(" ", ""));
 	}
@@ -194,7 +194,7 @@
 						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 							"{@type=korap:group, operation=operation:relation, operands=[" +
 								"{@type=korap:span, layer=cat, key=CP, match=match:eq}," +
-								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 									"{@type=korap:span, layer=cat, key=VP, match=match:eq}" +
 								"]}" +
 							"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
@@ -214,12 +214,12 @@
 								"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 									"{@type=korap:group, operation=operation:relation, operands=[" +
 										"{@type=korap:span, layer=cat, key=CP, match=match:eq}," +
-										"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+										"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 											"{@type=korap:span, layer=cat, key=VP, match=match:eq}" +
 										"]}" +
 									"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
 								"]}," +
-								"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 									"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
 								"]}" +
 							"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
@@ -308,7 +308,7 @@
 						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 							"{@type=korap:group, operation=operation:sequence, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sonne, match=match:eq}}," +
-								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 									"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mond, match=match:eq}}" +
 								"]}" +
 							"], distances=[" +
@@ -330,7 +330,7 @@
 						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 							"{@type=korap:group, operation=operation:sequence, operands=[" +
 								"{@type=korap:span}," +
-								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 									"{@type=korap:span}" +
 								"]} "+
 							"], inOrder=true}" +
@@ -352,14 +352,14 @@
 							"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 								"{@type=korap:group, operation=operation:sequence, operands=[" +
 									"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sonne, match=match:eq}}," +
-									"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mond, match=match:eq}}" +
 									"]}" +
 								"], distances=[" +
 									"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=0, max=2}, min=0, max=2}" +
 								"], inOrder=true}" +
 							"]}," +	
-							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sterne, match=match:eq}}" +
 							"]}" +
 						"],distances=[" +
@@ -381,7 +381,7 @@
 							"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 									"{@type=korap:group, operation=operation:relation, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sonne, match=match:eq}}," +
-										"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+										"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 											"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mond, match=match:eq}}" +
 										"]}" +
 									"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
@@ -401,7 +401,7 @@
 							"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 									"{@type=korap:group, operation=operation:relation, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Sonne, match=match:eq}}," +
-										"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+										"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 											"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mond, match=match:eq}}" +
 										"]}" +
 									"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
@@ -422,13 +422,13 @@
 						"{@type=korap:group, operation=operation:relation, operands=[" +
 							"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 								"{@type=korap:group, operation=operation:relation, operands=[" +
-									"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 										"{@type=korap:span}" +
 									"]}," +
 									"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
 								"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
 							"]}," +
-							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 								"{@type=korap:span, layer=cat, key=VP, match=match:eq}" +
 							"]}" +
 						"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}" +
@@ -449,10 +449,10 @@
 		String eq2 =
 				"{@type=korap:group, operation=operation:position, frames=[frame:startswith], sharedClasses=[sharedClasses:includes], operands=[" +
 						"{@type=korap:group, operation=operation:relation, operands=[" +
-							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=, classOut=1025, operands=[" +
 								"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
 							"]}," +
-							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=, classOut=1025, operands=[" +
 								"{@type=korap:span, layer=cat, key=VP, match=match:eq}" +
 							"]}" +
 						"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}," +
@@ -530,7 +530,7 @@
 			"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=N, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=V, match=match:eq}}" +
 					"]}" +
 				"], inOrder=true}" +
@@ -548,7 +548,7 @@
 			"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=N, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=V, match=match:eq}}" +
 					"]}" +
 				"], inOrder=true}" +
@@ -564,7 +564,7 @@
 			"{@type=korap:group, operation=operation:relation, operands=[" +
 				"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 					"{@type=korap:group, operation=operation:relation, operands=[" +
-						"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+						"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=N, match=match:eq}}" +
 						"]}," +
 						"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=V, match=match:eq}}" +
@@ -585,16 +585,16 @@
 							// dominance relation #1 > #2 is reduced to #1, for expressing #1 > #3
 							"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 								"{@type=korap:group, operation=operation:relation, operands=[" +
-									"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 										"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
 									"]}," +
-									"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=V, match=match:eq}}" +
 									"]}" +
 								"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
 							"]}," +
 							// establish class 2 around P for later reference
-							"{@type=korap:group, operation=operation:class, class=2, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1026, classOut=1026, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=P, match=match:eq}}" +
 							"]}" +
 						"], relation={@type=korap:relation, wrap={@type=korap:term, layer=c}}}" +
@@ -649,7 +649,7 @@
 				"{@type=korap:group, operation=operation:relation, operands=[" +
 						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 							"{@type=korap:group, operation=operation:relation, operands=[" +
-								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 									"{@type=korap:span}" +
 								"]}," +
 								"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
@@ -669,7 +669,7 @@
 						"{@type=korap:group, operation=operation:relation, operands=[" +
 							"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 								"{@type=korap:group, operation=operation:relation, operands=[" +
-									"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 										"{@type=korap:span}" +
 									"]}," +
 									"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
@@ -695,7 +695,7 @@
 								"{@type=korap:group, operation=operation:relation, operands=[" +
 									"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 										"{@type=korap:group, operation=operation:relation, operands=[" +
-											"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+											"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 												"{@type=korap:span}" +
 											"]}," +
 											"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
@@ -720,7 +720,7 @@
 				"{@type=korap:group, operation=operation:relation, operands=[" +
 						"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 							"{@type=korap:group, operation=operation:relation, operands=[" +
-								"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+								"{@type=korap:group, operation=operation:class, class=1024, classOut=1024, operands=[" +
 									"{@type=korap:span}" +
 								"]}," +
 								"{@type=korap:span, layer=cat, key=NP, match=match:eq}" +
diff --git a/src/test/java/CosmasTreeTest.java b/src/test/java/CosmasTreeTest.java
index e074ee8..2f8fe07 100644
--- a/src/test/java/CosmasTreeTest.java
+++ b/src/test/java/CosmasTreeTest.java
@@ -168,7 +168,7 @@
 		query="(Sonne oder Mond) und scheint";
 		String orand1 = 
 				"{@type=korap:group, operation=operation:sequence, distances=[" +
-					"{@type=korap:distance, key=t, min=0, max=0}" +
+					"{@type=cosmas:distance, key=t, min=0, max=0}" +
 					"], operands=[" +
 						"{@type=korap:group, operation=operation:or, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, key=Sonne, layer=orth, match=match:eq}}," +
@@ -183,7 +183,7 @@
 		query="scheint und (Sonne oder Mond)";
 		String orand2 = 
 				"{@type=korap:group, operation=operation:sequence, distances=[" +
-						"{@type=korap:distance, key=t, min=0, max=0}" +
+						"{@type=cosmas:distance, key=t, min=0, max=0}" +
 					"], operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, key=scheint, layer=orth, match=match:eq}}," +
 						"{@type=korap:group, operation=operation:or, operands=[" +
@@ -198,11 +198,11 @@
 		query="Regen und scheint und (Sonne oder Mond)";
 		String orand3 = 
 				"{@type=korap:group, operation=operation:sequence, distances=[" +
-						"{@type=korap:distance, key=t, min=0, max=0}" +
+						"{@type=cosmas:distance, key=t, min=0, max=0}" +
 				"], operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, key=Regen, layer=orth, match=match:eq}}," +
 					"{@type=korap:group, operation=operation:sequence, distances=[" +
-							"{@type=korap:distance, key=t, min=0, max=0}" +
+							"{@type=cosmas:distance, key=t, min=0, max=0}" +
 						"], operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, key=scheint, layer=orth, match=match:eq}}," +
 							"{@type=korap:group, operation=operation:or, operands=[" +
@@ -253,8 +253,8 @@
 						"], 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}" +
+							"{@type=cosmas:distance, key=s, boundary={@type=korap:boundary, min=0, max=0}, min=0, max=0}," +
+							"{@type=cosmas:distance, key=p, boundary={@type=korap:boundary, min=1, max=3}, min=1, max=3}" +
 						"]" +
 					"}" +
 				"]}";
@@ -276,8 +276,8 @@
 						"], 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}" +
+							"{@type=cosmas:distance, key=s, boundary={@type=korap:boundary, min=0, max=0}, min=0, max=0, exclude=true}," +
+							"{@type=cosmas:distance, key=p, boundary={@type=korap:boundary, min=1, max=3}, min=1, max=3, exclude=true}" +
 						"]" +
 					"}" +
 				"]}";
@@ -801,7 +801,7 @@
 		query="Sonne nicht Mond";
 		String opnot1 = 
 					"{@type=korap:group, operation=operation:sequence, distances=[" +
-						"{@type=korap:distance, key=t, min=0, max=0, exclude=true}" +
+						"{@type=cosmas:distance, key=t, min=0, max=0, exclude=true}" +
 					"], 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}}" +
@@ -1175,23 +1175,6 @@
 	@Test
 	public void testOPNHIT() throws QueryException {
 		query="#NHIT(gehen /w1:10 voran)";
-//		String nhit1 = 
-//				"{@type=korap:reference, operation=operation:focus, classRef=[1025], classRefOp=classRefOp:inversion, operands=[" +
-//					"{@type=korap:group, operation=operation:sequence, " +
-//						"operands=[" +
-//							"{@type=korap:group, operation=operation:class, class= , classOut=1025, operands=[" +
-//								"{@type=korap:token, wrap={@type=korap:term, key=gehen, layer=orth, match=match:eq}}" +
-//							"]}," +
-//							"{@type=korap:group, operation=operation:class, class= , classOut=1025, operands=[" +
-//								"{@type=korap:token, wrap={@type=korap:term, key=voran, layer=orth, match=match:eq}}" +
-//							"]}" +
-//						"], inOrder=false, " +
-//						"distances=[" +
-//							"{@type=korap:distance, key=w, boundary={@type=korap:boundary, min=1, max=10}, min=1, max=10}" +
-//						"]" +
-//					"}" +
-//				"]}";
-//		
 		String nhit1 = 
 				"{@type=korap:reference, operation=operation:focus, classRef=[1025], operands=[" +
 					"{@type=korap:group, operation=operation:class, classRefOp=classRefOp:inversion, classIn=[1026,1027], classOut=1025, operands=[" +
@@ -1213,7 +1196,7 @@
 		ct = new CosmasTree(query);
 		map = ct.getRequestMap().get("query").toString();
 		assertEquals(nhit1.replaceAll(" ", ""), map.replaceAll(" ", ""));
-//		
+
 //		query="#NHIT(gehen %w1:10 voran)";
 //		String nhit2 = 
 //				"{@type=korap:reference, operation=operation:focus, classRef=1025, operands=[" +
diff --git a/src/test/java/PoliqarpPlusTreeTest.java b/src/test/java/PoliqarpPlusTreeTest.java
index 53145d8..3a79aaa 100644
--- a/src/test/java/PoliqarpPlusTreeTest.java
+++ b/src/test/java/PoliqarpPlusTreeTest.java
@@ -10,6 +10,8 @@
 	PoliqarpPlusTree ppt;
 	String map;
 	String expected;
+	String metaExpected;
+	String metaMap;
 	String query;
 	
 	private boolean equalsQueryContent(String res, String query) throws QueryException {
@@ -21,14 +23,13 @@
 	
 	@Test
 	public void testContext() throws QueryException {
-		String contextString = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld";
+		String contextString = "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld";
 		ppt = new PoliqarpPlusTree("Test");
 		assertEquals(contextString.replaceAll(" ", ""), ppt.getRequestMap().get("@context").toString().replaceAll(" ", ""));
 	}
 	
 	@Test
 	public void testSingleTokens() throws QueryException {
-		String query;
 		// [base=Mann]
 		String token1 = "{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Mann, match=match:eq}}";
 		assertTrue(equalsQueryContent(token1, "[base=Mann]"));
@@ -60,8 +61,6 @@
 	
 	@Test
 	public void testValue() throws QueryException {
-		String query;
-		
 		query = "[mate/m=temp:pres]";
 		String value1 = "{@type=korap:token, wrap={@type=korap:term, foundry=mate, layer=m, key=temp, value=pres, match=match:eq}}";
 		ppt = new PoliqarpPlusTree(query);
@@ -71,7 +70,7 @@
 	
 	@Test
 	public void testRegex() throws QueryException {
-		String query = "[orth=\"M(a|ä)nn(er)?\"]";
+		query = "[orth=\"M(a|ä)nn(er)?\"]";
 		String re1 = "{@type=korap:token, wrap={@type=korap:term, layer=orth, type=type:regex, key=M(a|ä)nn(er)?, match=match:eq}}";
 		ppt = new PoliqarpPlusTree(query);
 		map = ppt.getRequestMap().get("query").toString();
@@ -110,7 +109,7 @@
 	
 	@Test
 	public void testCaseSensitivityFlag() throws QueryException {
-		String query="[orth=deutscher/i]";
+		query="[orth=deutscher/i]";
 		String cs1 = 
 				"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=deutscher, match=match:eq, caseInsensitive=true}}";
 		ppt = new PoliqarpPlusTree(query);
@@ -386,7 +385,7 @@
 				"{@type=korap:group, operation=operation:sequence, " +
 				"operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=der, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+					"{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 					  "{@type=korap:span, key=s}," +
 					  "{@type=korap:span, key=np}" +
 					"], frame=frame:contains}" +
@@ -405,7 +404,7 @@
 		expected = 
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=der, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 						"{@type=korap:token}" +
 					"]}," +
 					"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Mann, match=match:eq}}" +
@@ -417,7 +416,7 @@
 		query = "{1:[]}[base=der][base=Mann]";
 		expected = 
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
-					"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 						"{@type=korap:token}" +
 					"]}," +
 					"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=der, match=match:eq}}," +
@@ -432,7 +431,7 @@
 	public void testLeadingTrailingEmptyTokens() throws QueryException {
 		// startswith(<s>, [][base=Mann]
 		String et1 = 
-			"{@type=korap:group, operation=operation:position, frames=[frame:startswith],sharedClasses=[sharedClasses:includes], operands=[" +	
+			"{@type=korap:group, operation=operation:position, frames=[frames:startswith], operands=[" +	
 				"{@type=korap:span, key=s}," +
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token}," +
@@ -498,7 +497,7 @@
 					"{@type=korap:group, operation=operation:repetition, operands=[" +
 						"{@type=korap:token}" +
 					"], boundary={@type=korap:boundary, min=1}, min=1}," +
-					"{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+					"{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 					  "{@type=korap:span, key=s}," +
 					  "{@type=korap:span, key=np}" +
 					"], frame=frame:contains}," +
@@ -874,7 +873,7 @@
 	public void testClasses() throws QueryException {
 		String query;
 		// {[base=Mann]}
-		String cls1 = "{@type=korap:group, operation=operation:class, class=0, operands=[" +
+		String cls1 = "{@type=korap:group, operation=operation:class, class=0, classOut=0, operands=[" +
 				"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Mann, match=match:eq}}" +
 				"]}";
 		ppt = new PoliqarpPlusTree("{[base=Mann]}");
@@ -883,7 +882,7 @@
 		
 		// {[base=Mann][orth=Frau]}
 		query = "{[base=Mann][orth=Frau]}";
-		String cls2 = "{@type=korap:group, operation=operation:class, class=0, operands=[" +
+		String cls2 = "{@type=korap:group, operation=operation:class, class=0, classOut=0, operands=[" +
 				 "{@type=korap:group, operation=operation:sequence, operands=[" +
 				  "{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Mann, match=match:eq}}," +
 				  "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Frau, match=match:eq}}" +
@@ -896,7 +895,7 @@
 		// [p=NN]{[base=Mann][orth=Frau]}
 		String cls3 = "{@type=korap:group, operation=operation:sequence, operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, layer=p, key=NN, match=match:eq}}," +
-						"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+						"{@type=korap:group, operation=operation:class, class=0, classOut=0, operands=[" +
 							"{@type=korap:group, operation=operation:sequence, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Mann, match=match:eq}}," +
 								"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Frau, match=match:eq}}" +
@@ -909,7 +908,7 @@
 		
 		// {[base=Mann][orth=Frau]}[p=NN]
 		String cls4 = "{@type=korap:group, operation=operation:sequence, operands=[" +
-						"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+						"{@type=korap:group, operation=operation:class, class=0, classOut=0, operands=[" +
 						   "{@type=korap:group, operation=operation:sequence, operands=[" +
 						     "{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Mann, match=match:eq}}," +
 						     "{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Frau, match=match:eq}}" +
@@ -922,9 +921,9 @@
 		assertEquals(cls4.replaceAll(" ", ""), map.replaceAll(" ", ""));
 
 		// {2:{1:[tt/p=ADJA]}[mate/p=NN]}"
-		String cls5 = "{@type=korap:group, operation=operation:class, class=2, operands=[" +
+		String cls5 = "{@type=korap:group, operation=operation:class, class=2, classOut=2, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
-						   "{@type=korap:group, operation=operation:class, class=1, operands=[" +
+						   "{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 						     "{@type=korap:token, wrap={@type=korap:term, foundry=tt, layer=p, key=ADJA, match=match:eq}}" +
 						   "]}," +
 						   "{@type=korap:token, wrap={@type=korap:term, foundry=mate, layer=p, key=NN, match=match:eq}}" + 
@@ -938,21 +937,21 @@
 	@Test
 	public void testPositions() throws QueryException {
 		// contains(<s>,<np>)
-		String pos1 = "{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+		String pos1 = "{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 				  "{@type=korap:span, key=s}," +
 				  "{@type=korap:span, key=np}" +
 				"], frame=frame:contains}";
 		assertTrue(equalsQueryContent(pos1, "contains(<s>,<np>)"));
 		
 		// contains(<s>,[base=Mann])
-		String pos2 = "{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+		String pos2 = "{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 				  "{@type=korap:span, key=s}," +
 				  "{@type=korap:token, wrap= {@type=korap:term, layer=lemma, key=Mann, match=match:eq}}" +
 				"], frame=frame:contains}";
 		assertTrue(equalsQueryContent(pos2, "contains(<s>,[base=Mann])"));
 		
 		// contains(<s>,[orth=der][orth=Mann])
-		String pos3 = "{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+		String pos3 = "{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 				  	"{@type=korap:span, key=s}," +
 				  	"{@type=korap:group, operation=operation:sequence, operands=[" +
 				  		"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=der, match=match:eq}}," +
@@ -967,7 +966,7 @@
 		String pos4 = 
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Auto, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+					"{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 				  		"{@type=korap:span, key=s}," +
 				  		"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Mann, match=match:eq}}" +
 				  	"], frame=frame:contains}" +
@@ -978,7 +977,7 @@
 		
 		// contains(<s>,[pos=N]*)
 		String pos5 = 
-					"{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+					"{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 				  		"{@type=korap:span, key=s}," +
 				  		"{@type=korap:group, operation=operation:repetition, " +
 				  			"operands=[{@type=korap:token, wrap={@type=korap:term, layer=pos, key=N, match=match:eq}}" +
@@ -993,7 +992,7 @@
 		String pos6 = 
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Auto, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+					"{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 				  		"{@type=korap:span, key=s}," +
 				  		"{@type=korap:group, operation=operation:repetition, " +
 				  			"operands=[{@type=korap:token, wrap={@type=korap:term, layer=pos, key=N, match=match:eq}}" +
@@ -1010,9 +1009,9 @@
 	public void testNestedPositions() throws QueryException {
 		// contains(<s>,startswith(<np>,[orth=Der]))
 		String npos1 = 
-			"{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+			"{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 				"{@type=korap:span, key=s}," +
-				"{@type=korap:group, operation=operation:position, frames=[frame:startswith],sharedClasses=[sharedClasses:includes], operands=[" +
+				"{@type=korap:group, operation=operation:position, frames=[frames:startswith], operands=[" +
 					"{@type=korap:span, key=np}," +
 					"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Der, match=match:eq}}" +
 				"], frame=frame:startswith}" +
@@ -1029,7 +1028,7 @@
 			"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Der, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=0, classOut=0, operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mann, match=match:eq}}" +
 					"]}" +
 				"]}" +
@@ -1043,7 +1042,7 @@
 			"{@type=korap:reference, operation=operation:focus, classRef=[0], operands=[" +
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Der, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=0, classOut=0, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mann, match=match:eq}}," +
 							"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=geht, match=match:eq}}" +
@@ -1060,7 +1059,7 @@
 			"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Der, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mann, match=match:eq}}," +
 							"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=geht, match=match:eq}}" +
@@ -1075,9 +1074,9 @@
 		// focus(1:startswith(<s>,{1:<np>}))
 		String shr4 = 
 			"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
-				"{@type=korap:group, operation=operation:position, frames=[frame:startswith],sharedClasses=[sharedClasses:includes], operands=[" +
+				"{@type=korap:group, operation=operation:position, frames=[frames:startswith], operands=[" +
 					"{@type=korap:span, key=s}," +
-					"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 						"{@type=korap:span, key=np}" +
 					"]}" +
 				"], frame=frame:startswith}" +
@@ -1089,15 +1088,15 @@
 		// focus(3: startswith(<s>, {3:[base=der]{1:[mate/p=ADJA]{2:[tt/p=NN]}}})) 
 		String shr5 = 
 			"{@type=korap:reference, operation=operation:focus, classRef=[3], operands=[" +
-				"{@type=korap:group, operation=operation:position, frames=[frame:startswith],sharedClasses=[sharedClasses:includes], operands=[" +
+				"{@type=korap:group, operation=operation:position, frames=[frames:startswith], operands=[" +
 					"{@type=korap:span, key=s}," +
-					"{@type=korap:group, operation=operation:class, class=3, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=3, classOut=3, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=der, match=match:eq}}," +
-							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 								"{@type=korap:group, operation=operation:sequence, operands=[" +
 									"{@type=korap:token, wrap={@type=korap:term, foundry=mate, layer=p, key=ADJA, match=match:eq}}," +
-									"{@type=korap:group, operation=operation:class, class=2, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=2, classOut=2, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, foundry=tt, layer=p, key=NN, match=match:eq}}" +
 									"]}" + 
 								"]}" +
@@ -1113,15 +1112,15 @@
 		// split(3: startswith(<s>, {3:[base=der]{1:[mate/p=ADJA]{2:[tt/p=NN]}}})) 
 		String shr6 = 
 			"{@type=korap:reference, operation=operation:split, classRef=[3], operands=[" +
-				"{@type=korap:group, operation=operation:position, frames=[frame:startswith],sharedClasses=[sharedClasses:includes], operands=[" +
+				"{@type=korap:group, operation=operation:position, frames=[frames:startswith], operands=[" +
 					"{@type=korap:span, key=s}," +
-					"{@type=korap:group, operation=operation:class, class=3, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=3, classOut=3, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=der, match=match:eq}}," +
-							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 								"{@type=korap:group, operation=operation:sequence, operands=[" +
 									"{@type=korap:token, wrap={@type=korap:term, foundry=mate, layer=p, key=ADJA, match=match:eq}}," +
-									"{@type=korap:group, operation=operation:class, class=2, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=2, classOut=2, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, foundry=tt, layer=p, key=NN, match=match:eq}}" +
 									"]}" + 
 								"]}" +
@@ -1137,15 +1136,15 @@
 		// split(2|3: startswith(<s>, {3:[base=der]{1:[mate/p=ADJA]{2:[tt/p=NN]}}})) 
 		String shr7 = 
 			"{@type=korap:reference, operation=operation:split, classRef=[2, 3], classRefOp=classRefOp:intersection, operands=[" +
-				"{@type=korap:group, operation=operation:position, frames=[frame:startswith],sharedClasses=[sharedClasses:includes], operands=[" +
+				"{@type=korap:group, operation=operation:position, frames=[frames:startswith], operands=[" +
 					"{@type=korap:span, key=s}," +
-					"{@type=korap:group, operation=operation:class, class=3, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=3, classOut=3, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=der, match=match:eq}}," +
-							"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 								"{@type=korap:group, operation=operation:sequence, operands=[" +
 									"{@type=korap:token, wrap={@type=korap:term, foundry=mate, layer=p, key=ADJA, match=match:eq}}," +
-									"{@type=korap:group, operation=operation:class, class=2, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=2, classOut=2, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, foundry=tt, layer=p, key=NN, match=match:eq}}" +
 									"]}" + 
 								"]}" +
@@ -1162,10 +1161,10 @@
 		String shr8 = 
 			"{@type=korap:reference, operation=operation:focus, classRef=[1], operands=[" +
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
-					"{@type=korap:group, operation=operation:class, class=0, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=0, classOut=0, operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=der, match=match:eq}}" +
 					"]}," +
-					"{@type=korap:group, operation=operation:class, class=1, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1, classOut=1, operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, layer=pos, key=ADJA, match=match:eq}}" +
 					"]}" +
 				"]}" +
@@ -1201,7 +1200,7 @@
 		query = "submatch(1,4:contains(<s>,[base=Haus]))";
 		expected = 
 			"{@type=korap:reference, operation=operation:focus, operands=[" +
-				"{@type=korap:group, operation=operation:position, frames=[],sharedClasses=[sharedClasses:includes], operands=[" +
+				"{@type=korap:group, operation=operation:position, frames=[frames:contains], operands=[" +
 					"{@type=korap:span, key=s}," +
 					"{@type=korap:token, wrap= {@type=korap:term, layer=lemma, key=Haus, match=match:eq}}" +
 				"], frame=frame:contains}" +
@@ -1308,85 +1307,106 @@
 	@Test
 	public void testAlign() throws QueryException {
 		// [orth=der]^[orth=Mann]
-		String align1 = 
+		query = "[orth=der]^[orth=Mann]";
+		expected = 
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=der, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:alignment, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 						"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mann, match=match:eq}}" +
-					"], align=align:left}" +
+					"]}" +
 				"]}";
-		ppt = new PoliqarpPlusTree("[orth=der]^[orth=Mann]");
+		metaExpected = 
+				"{alignment=1025}";
+		ppt = new PoliqarpPlusTree(query);
 		map = ppt.getRequestMap().get("query").toString();
-		assertEquals(align1.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		metaMap = ppt.getRequestMap().get("meta").toString();
+		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		assertEquals(metaExpected.replaceAll(" ", ""), metaMap.replaceAll(" ", ""));
 		
 		// [orth=der]^[orth=große][orth=Mann]
-		String query = "[orth=der]^[orth=große][orth=Mann]";
-		String align1b = 
+		query = "[orth=der]^[orth=große][orth=Mann]";
+		String expected = 
 				"{@type=korap:group, operation=operation:sequence, operands=[" +
 					"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=der, match=match:eq}}," +
-					"{@type=korap:group, operation=operation:alignment, operands=[" +
+					"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=große, match=match:eq}}," +
 							"{@type=korap:token, wrap={@type=korap:term, layer=orth, key=Mann, match=match:eq}}" +
 						"]}" +
-					"], align=align:left}" +
+					"]}" +
 				"]}";
+		metaExpected = 
+				"{alignment=1025}";
 		ppt = new PoliqarpPlusTree(query);
 		map = ppt.getRequestMap().get("query").toString();
-		assertEquals(align1b.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		metaMap = ppt.getRequestMap().get("meta").toString();
+		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		assertEquals(metaExpected.replaceAll(" ", ""), metaMap.replaceAll(" ", ""));
 		
-		// "([base=a]^[base=b])|[base=c]",
-		String align2 = 
+		query = "([base=a]^[base=b])|[base=c]";
+		expected = 
 				"{@type=korap:group, operation=operation:or, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=a, match=match:eq}}," +
-							"{@type=korap:group, operation=operation:alignment, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 								"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=b, match=match:eq}}" +
-							"], align=align:left}" +
+							"]}" +
 						"]}," +
 						"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=c, match=match:eq}}" +
 				"]}";
-		ppt = new PoliqarpPlusTree("([base=a]^[base=b])|[base=c]");
+		metaExpected = 
+				"{alignment=1025}";
+		ppt = new PoliqarpPlusTree(query);
 		map = ppt.getRequestMap().get("query").toString();
-		assertEquals(align2.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		metaMap = ppt.getRequestMap().get("meta").toString();
+		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		assertEquals(metaExpected.replaceAll(" ", ""), metaMap.replaceAll(" ", ""));
 		
-		// "([base=a]^[base=b][base=c])|[base=d]",
-		String align3 = 
+		query = "([base=a]^[base=b][base=c])|[base=d]";
+		expected = 
 				"{@type=korap:group, operation=operation:or, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=a, match=match:eq}}," +
-							"{@type=korap:group, operation=operation:alignment, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 								"{@type=korap:group, operation=operation:sequence, operands=[" +
 									"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=b, match=match:eq}}," +
 									"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=c, match=match:eq}}" +
 								"]}" +
-							"], align=align:left}" +
+							"]}" +
 						"]}," +
 						"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=d, match=match:eq}}" +
 				"]}";
-		ppt = new PoliqarpPlusTree("([base=a]^[base=b][base=c])|[base=d]");
+		metaExpected = 
+				"{alignment=1025}";
+		ppt = new PoliqarpPlusTree(query);
 		map = ppt.getRequestMap().get("query").toString();
-		assertEquals(align3.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		metaMap = ppt.getRequestMap().get("meta").toString();
+		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		assertEquals(metaExpected.replaceAll(" ", ""), metaMap.replaceAll(" ", ""));
 		
-		// "([base=a]^[base=b]^[base=c])|[base=d]",
-		String align4 = 
+		query = "([base=a]^[base=b]^[base=c])|[base=d]";
+		expected = 
 				"{@type=korap:group, operation=operation:or, operands=[" +
 						"{@type=korap:group, operation=operation:sequence, operands=[" +
 							"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=a, match=match:eq}}," +
-							"{@type=korap:group, operation=operation:alignment, operands=[" +
+							"{@type=korap:group, operation=operation:class, class=1025, classOut=1025, operands=[" +
 								"{@type=korap:group, operation=operation:sequence, operands=[" +
 									"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=b, match=match:eq}}," +
-									"{@type=korap:group, operation=operation:alignment, operands=[" +
+									"{@type=korap:group, operation=operation:class, class=1026, classOut=1026, operands=[" +
 										"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=c, match=match:eq}}" +
-									"], align=align:left}" +
+									"]}" +
 								"]}" +
-							"], align=align:left}" +
+							"]}" +
 						"]}," +
 						"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=d, match=match:eq}}" +
 				"]}";
-		ppt = new PoliqarpPlusTree("([base=a]^[base=b]^[base=c])|[base=d]");
+		metaExpected = 
+				"{alignment=[1025,1026]}";
+		ppt = new PoliqarpPlusTree(query);
 		map = ppt.getRequestMap().get("query").toString();
-		assertEquals(align4.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		metaMap = ppt.getRequestMap().get("meta").toString();
+		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		assertEquals(metaExpected.replaceAll(" ", ""), metaMap.replaceAll(" ", ""));
 		
 		
 	}