diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java
index 34e8aac..2bd7273 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessor.java
@@ -31,713 +31,777 @@
  *
  */
 public class AnnisQueryProcessor extends Antlr4AbstractQueryProcessor {
-	private static Logger log = LoggerFactory.getLogger(AnnisQueryProcessor.class);
-	/**
-	 * Flag that indicates whether token fields or meta fields are currently being processed
-	 */
-	boolean inMeta = false;
-	/**
-	 * Keeps track of operands that are to be integrated into yet uncreated objects.
-	 */
-	LinkedList<LinkedHashMap<String,Object>> operandStack = new LinkedList<LinkedHashMap<String,Object>>();
-	/**
-	 * Keeps track of explicitly (by #-var definition) or implicitly (number as reference) introduced entities (for later reference by #-operator)
-	 */
-	Map<String, LinkedHashMap<String,Object>> nodeVariables = new LinkedHashMap<String, LinkedHashMap<String,Object>>(); 
-	/**
-	 * Counter for variable definitions.
-	 */
-	Integer variableCounter = 1;
-	/**
-	 * Marks the currently active token in order to know where to add flags (might already have been taken away from token stack).
-	 */
-	LinkedHashMap<String,Object> curToken = new LinkedHashMap<String,Object>();
-	/**
-	 * 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>>();
-	/**
-	 * Keeps track of operation:class numbers.
-	 */
-	int classCounter = 0;
-	/**
-	 * Keeps track of numers of relations processed (important when dealing with multiple predications).
-	 */
-	int relationCounter = 0;
-	/**
-	 * Keeps track of references to nodes that are operands of groups (e.g. tree relations). Those nodes appear on the top level of the parse tree
-	 * but are to be integrated into the AqlTree at a later point (namely as operands of the respective group). Therefore, store references to these
-	 * nodes here and exclude the operands from being written into the query map individually.   
-	 */
-	private List<ParseTree> globalLingTermNodes = new ArrayList<ParseTree>();
-	private int totalRelationCount;
-	/**
-	 * Keeps a record of reference-class-mapping, i.e. which 'class' has been assigned to which #n reference. This is important when introducing korap:reference 
-	 * spans to refer back to previously established classes for entities.
-	 */
-	private LinkedHashMap<String, Integer> refClassMapping = new LinkedHashMap<String, Integer>();
-	/**
-	 * Keeps track of the number of references to a node/token by means of #n. E.g. in the query 
-	 * <tt>tok="x" & tok="y" & tok="z" & #1 . #2 & #2 . #3</tt>, the 2nd token ("y") is referenced twice, the others once.
-	 */
-	private LinkedHashMap<String, Integer> nodeReferencesTotal = new LinkedHashMap<String, Integer>();
-	/**
-	 * Keeps track of the number of references to a node/token that have already been processed.
-	 */
-	private LinkedHashMap<String, Integer> nodeReferencesProcessed = new LinkedHashMap<String, Integer>();
+    private static Logger log = LoggerFactory.getLogger(AnnisQueryProcessor.class);
+    /**
+     * Flag that indicates whether token fields or meta fields are currently being processed
+     */
+    boolean inMeta = false;
+    /**
+     * Keeps track of operands that are to be integrated into yet uncreated objects.
+     */
+    LinkedList<LinkedHashMap<String,Object>> operandStack = new LinkedList<LinkedHashMap<String,Object>>();
+    /**
+     * Keeps track of explicitly (by #-var definition) or implicitly (number as reference) introduced entities (for later reference by #-operator)
+     */
+    Map<String, LinkedHashMap<String,Object>> nodeVariables = new LinkedHashMap<String, LinkedHashMap<String,Object>>(); 
+    /**
+     * Counter for variable definitions.
+     */
+    Integer variableCounter = 1;
+    /**
+     * Marks the currently active token in order to know where to add flags (might already have been taken away from token stack).
+     */
+    LinkedHashMap<String,Object> curToken = new LinkedHashMap<String,Object>();
+    /**
+     * 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>>();
+    /**
+     * Keeps track of operation:class numbers.
+     */
+    int classCounter = 0;
+    /**
+     * Keeps track of numers of relations processed (important when dealing with multiple predications).
+     */
+    int relationCounter = 0;
+    /**
+     * Keeps track of references to nodes that are operands of groups (e.g. tree relations). Those nodes appear on the top level of the parse tree
+     * but are to be integrated into the AqlTree at a later point (namely as operands of the respective group). Therefore, store references to these
+     * nodes here and exclude the operands from being written into the query map individually.   
+     */
+    private List<ParseTree> globalLingTermNodes = new ArrayList<ParseTree>();
+    private int totalRelationCount;
+    /**
+     * Keeps a record of reference-class-mapping, i.e. which 'class' has been assigned to which #n reference. This is important when introducing korap:reference 
+     * spans to refer back to previously established classes for entities.
+     */
+    private LinkedHashMap<String, Integer> refClassMapping = new LinkedHashMap<String, Integer>();
+    /**
+     * Keeps track of the number of references to a node/token by means of #n. E.g. in the query 
+     * <tt>tok="x" & tok="y" & tok="z" & #1 . #2 & #2 . #3</tt>, the 2nd token ("y") is referenced twice, the others once.
+     */
+    private LinkedHashMap<String, Integer> nodeReferencesTotal = new LinkedHashMap<String, Integer>();
+    /**
+     * Keeps track of the number of references to a node/token that have already been processed.
+     */
+    private LinkedHashMap<String, Integer> nodeReferencesProcessed = new LinkedHashMap<String, Integer>();
+    /**
+     * Keeps track of the operand references in the previously processed relation. Needed for the decision whether to postpone
+     * the processing of a relation (in case it does not share any operands with the previous relation).
+     */
+    private ArrayList<String> previousRelationOperandRefs = new ArrayList<String>();
+    /**
+     * Keeps track of queued relations. Relations sometimes cannot be processed directly, namely in case it does not share 
+     * any operands with the previous relation. Then wait until a relation with a shared operand has been processed.
+     */
+    private LinkedList<ParseTree> queuedRelations = new LinkedList<ParseTree>();
 
-	public AnnisQueryProcessor(String query) {
-		KoralObjectGenerator.setQueryProcessor(this);
-		process(query);
-	}
+    public AnnisQueryProcessor(String query) {
+        KoralObjectGenerator.setQueryProcessor(this);
+        process(query);
+    }
 
-	@Override
-	public void process(String query) {
-		ParseTree tree = parseAnnisQuery(query);
-		if (this.parser != null) {
-			super.parser = this.parser;
-		} else {
-			throw new NullPointerException("Parser has not been instantiated!"); 
-		}
-		log.info("Processing Annis query: "+query);
-		if (tree != null) {
-			log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
-			processNode(tree);
-		}
-	}
+    @Override
+    public void process(String query) {
+        ParseTree tree = parseAnnisQuery(query);
+        if (this.parser != null) {
+            super.parser = this.parser;
+        } else {
+            throw new NullPointerException("Parser has not been instantiated!"); 
+        }
+        log.info("Processing Annis query: "+query);
+        if (tree != null) {
+            log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
+            processNode(tree);
+            // Last check to see if all relations have left the queue
+            if (!queuedRelations.isEmpty()) {
+                ParseTree queued = queuedRelations.getFirst();
+                if (verbose) System.out.println("Taking off queue (last rel): "+ queued.getText());
+                processNode(queuedRelations.pop());   
+            }
+        }
+    }
 
-	private void processNode(ParseTree node) {
-		// Top-down processing
-		if (visited.contains(node)) return;
-		else visited.add(node);
+    private void processNode(ParseTree node) {
+        String nodeCat = getNodeCat(node);
 
-		String nodeCat = getNodeCat(node);
-		openNodeCats.push(nodeCat);
+        // Top-down processing
+        if (visited.contains(node)) return;
+        openNodeCats.push(nodeCat);
+        stackedObjects = 0;
 
-		stackedObjects = 0;
+        // Before doing anything else, check if any relations are queued
+        // and need to be processed first
+        if (nodeCat.equals("n_ary_linguistic_term")) {
+            if (!queuedRelations.isEmpty()) {
+                ParseTree queued = queuedRelations.getFirst();
+                if (checkOperandsProcessedPreviously(queued)) {
+                    if (verbose) System.out.println("Taking off queue: "+
+                            queued.getText());
+                    queuedRelations.removeFirst();
+                    processNode(queued);
+                }
+            }  
+        }
 
-		if (verbose) {
-			System.err.println(" "+objectStack);
-			System.err.println(" "+operandStack);
-			System.out.println(openNodeCats);
-		}
+        if (verbose) {
+            System.err.println(" "+objectStack);
+            System.err.println(" "+operandStack);
+            System.out.println(openNodeCats);
+        }
 
-		/*
-		 ****************************************************************
-		 **************************************************************** 
-		 * 			Processing individual node categories  				*
-		 ****************************************************************
-		 ****************************************************************
-		 */
-		if (nodeCat.equals("exprTop")) {
-			processExprTop(node);
-		}
+        /*
+         ****************************************************************
+         **************************************************************** 
+         * 			Processing individual node categories  				*
+         ****************************************************************
+         ****************************************************************
+         */
+        if (nodeCat.equals("exprTop")) {
+            processExprTop(node);
+        }
 
-		if (nodeCat.equals("andTopExpr")) {
-			processAndTopExpr(node);
-		}
+        if (nodeCat.equals("andTopExpr")) {
+            processAndTopExpr(node);
+        }
 
-		if (nodeCat.equals("unary_linguistic_term")) {
-			processUnary_linguistic_term(node);
-		}
+        if (nodeCat.equals("unary_linguistic_term")) {
+            processUnary_linguistic_term(node);
+        }
 
-		if (nodeCat.equals("n_ary_linguistic_term")) {
-			processN_ary_linguistic_term(node);
-		}
+        if (nodeCat.equals("n_ary_linguistic_term")) {
+            processN_ary_linguistic_term(node);
+        }
 
-		if (nodeCat.equals("variableExpr")) {
-			processVariableExpr(node);
-		}
+        if (nodeCat.equals("variableExpr")) {
+            processVariableExpr(node);
+        }
 
-		objectsToPop.push(stackedObjects);
+        objectsToPop.push(stackedObjects);
 
-		/*
-		 ****************************************************************
-		 **************************************************************** 
-		 *  recursion until 'request' node (root of tree) is processed  *
-		 ****************************************************************
-		 ****************************************************************
-		 */
-		for (int i=0; i<node.getChildCount(); i++) {
-			ParseTree child = node.getChild(i);
-			processNode(child);
-		}
+        /*
+         ****************************************************************
+         **************************************************************** 
+         *  recursion until 'request' node (root of tree) is processed  *
+         ****************************************************************
+         ****************************************************************
+         */
+        for (int i=0; i<node.getChildCount(); i++) {
+            ParseTree child = node.getChild(i);
+            processNode(child);
+        }
 
-		/*
-		 **************************************************************
-		 * Stuff that happens after processing the children of a node *
-		 **************************************************************
-		 */
-		if (!objectsToPop.isEmpty()) {
-			for (int i=0; i<objectsToPop.pop(); i++) {
-				objectStack.pop();
-			}
-		}
-		openNodeCats.pop();
-	}
-
-	private void processAndTopExpr(ParseTree node) {
-		// Before processing any child expr node, check if it has one or more "*ary_linguistic_term" nodes.
-		// Those nodes may use references to earlier established operand nodes.
-		// Those operand nodes are not to be included into the query map individually but
-		// naturally as operands of the relations/groups introduced by the 
-		// *node. For that purpose, this section mines all used references
-		// and stores them in a list for later reference.
-		for (ParseTree exprNode : getChildrenWithCat(node,"expr")) {
-			// Pre-process any 'variableExpr' such that the variableReferences map can be filled
-			List<ParseTree> definitionNodes = new ArrayList<ParseTree>();
-			definitionNodes.addAll(getChildrenWithCat(exprNode, "variableExpr"));
-			for (ParseTree definitionNode : definitionNodes) {
-				processNode(definitionNode);
-			}
-			// Then, mine all relations between nodes
-			List<ParseTree> lingTermNodes = new ArrayList<ParseTree>();
-			lingTermNodes.addAll(getChildrenWithCat(exprNode, "n_ary_linguistic_term"));
-			globalLingTermNodes.addAll(lingTermNodes);
-			totalRelationCount  = globalLingTermNodes.size();
-			// Traverse refOrNode nodes under *ary_linguistic_term nodes and extract references
-			for (ParseTree lingTermNode : lingTermNodes) {
-				for (ParseTree refOrNode : getChildrenWithCat(lingTermNode, "refOrNode")) {
-					String refOrNodeString = refOrNode.getChild(0).toStringTree(parser);
-					if (refOrNodeString.startsWith("#")) {
-						String ref = refOrNode.getChild(0).toStringTree(parser).substring(1);
-						if (nodeReferencesTotal.containsKey(ref)) {
-							nodeReferencesTotal.put(ref, nodeReferencesTotal.get(ref)+1);
-						} else {
-							nodeReferencesTotal.put(ref, 1);
-							nodeReferencesProcessed.put(ref, 0);
-						}
-					}
-				}
-			}
-		}
-		if (verbose) System.err.println(nodeVariables);
-	}
-
-	private void processUnary_linguistic_term(ParseTree node) {
-		LinkedHashMap<String, Object> unaryOperator = parseUnaryOperator(node);
-		String reference = node.getChild(0).toStringTree(parser).substring(1);
-		LinkedHashMap<String, Object> object = nodeVariables.get(reference);
-		object.putAll(unaryOperator);
-	}
-
-	private void processExprTop(ParseTree node) {
-		List<ParseTree> andTopExprs = getChildrenWithCat(node, "andTopExpr");
-		if (andTopExprs.size() > 1) {
-			LinkedHashMap<String, Object> topOr = KoralObjectGenerator.makeGroup("or");
-			requestMap.put("query", topOr);
-			objectStack.push(topOr);
-		}
-	}
-
-	private LinkedHashMap<String, Object> processVariableExpr(ParseTree node) {
-		// simplex word or complex assignment (like qname = textSpec)?
-		String firstChildNodeCat = getNodeCat(node.getChild(0));
-		LinkedHashMap<String, Object> object = null;
-		if (firstChildNodeCat.equals("node")) {
-			object = KoralObjectGenerator.makeSpan();
-		} else if (firstChildNodeCat.equals("tok")) {
-			object = KoralObjectGenerator.makeToken();
-			if (node.getChildCount() > 1) { // empty tokens do not wrap a term
-				LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
-				term.put("layer", "orth");
-				object.put("wrap", term);
-			}
-		} else if (firstChildNodeCat.equals("qName")) {	// only (foundry/)?layer specified
-			// may be token or span, depending on indicated layer! (e.g. cnx/cat=NP vs mate/pos=NN)
-			// TODO generalize the list below -> look up layers associated with tokens rather than spans somewhere
-			HashMap<String, Object> qNameParse = parseQNameNode(node.getChild(0));
-			if (Arrays.asList(new String[]{"p", "lemma", "m", "orth"}).contains(qNameParse.get("layer"))) { 
-				object = KoralObjectGenerator.makeToken();
-				LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
-				object.put("wrap", term);
-				term.putAll(qNameParse);
-			} else {
-				object = KoralObjectGenerator.makeSpan();
-				object.putAll(qNameParse);
-			}
-		} else if (firstChildNodeCat.equals("textSpec")) {
-			object = KoralObjectGenerator.makeToken();
-			LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
-			object.put("wrap", term);
-			term.put("layer", "orth");
-			term.putAll(parseTextSpec(node.getChild(0)));
-		}
-
-		if (node.getChildCount() == 3) {  			// (foundry/)?layer=key specification
-			if (object.get("@type").equals("korap:token")) {
-				@SuppressWarnings("unchecked")
-				HashMap<String, Object> term = (HashMap<String, Object>) object.get("wrap");
-				term.putAll(parseTextSpec(node.getChild(2)));
-				term.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
-			} else {
-				object.putAll(parseTextSpec(node.getChild(2)));
-				object.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
-			}
-		}
-
-		if (object != null) {
-//			if (! operandOnlyNodeRefs.contains(variableCounter.toString())) {
-//				putIntoSuperObject(object);
-//			}
-			if (! getNodeCat(node.getParent().getParent()).equals("n_ary_linguistic_term")) {
-				putIntoSuperObject(object);
-			}
-			ParseTree parentsFirstChild = node.getParent().getChild(0);
-			if (getNodeCat(parentsFirstChild).endsWith("#")) {
-				nodeVariables.put(getNodeCat(parentsFirstChild).replaceAll("#", ""), object);
-			}
-			nodeVariables.put(variableCounter.toString(), object);
-			variableCounter++;
-		}
-		return object;
-	}
-
-	/**
-	 * Processes an operand node, creating a map for the operand containing all its information
-	 * given in the node definition (referenced via '#'). If this node has been referred to and used earlier,
-	 * a reference is created in its place. 
-	 * The operand will be wrapped in a class group if necessary.
-	 * @param operandNode
-	 * @return A map object with the appropriate CQLF representation of the operand 
-	 */
-	private LinkedHashMap<String, Object> retrieveOperand(ParseTree operandNode) {
-		LinkedHashMap<String, Object> operand = null;
-		if (!getNodeCat(operandNode.getChild(0)).equals("variableExpr")) {
-			String ref = operandNode.getChild(0).toStringTree(parser).substring(1);
-			operand = nodeVariables.get(ref);
-			if (nodeReferencesTotal.get(ref) > 1) {
-				if (nodeReferencesProcessed.get(ref)==0) {
-					refClassMapping.put(ref, classCounter);
-					operand = KoralObjectGenerator.wrapInClass(operand, classCounter++);
-				} else if (nodeReferencesProcessed.get(ref)>0 && nodeReferencesTotal.get(ref)>1) {
-					try {
-						operand = KoralObjectGenerator.wrapInReference(operandStack.pop(), refClassMapping.get(ref), true);
-					} catch (NoSuchElementException e) {
-						operand = KoralObjectGenerator.makeReference(refClassMapping.get(ref), true);
-					}
-				}
-				nodeReferencesProcessed.put(ref, nodeReferencesProcessed.get(ref)+1);
-			}
-		} else {
-			operand = processVariableExpr(operandNode.getChild(0));
-		}
-		return operand;
-	}
-
-	@SuppressWarnings("unchecked")
-	private void processN_ary_linguistic_term(ParseTree node) {
-		relationCounter++;
-		// get operator and determine type of group (sequence/treeRelation/relation/...)
-		// It's possible in Annis QL to concatenate operators, so there may be several operators under one n_ary_linguistic_term node. 
-		// Counter 'i' will iteratively point to all operator nodes (odd-numbered) under this node.
-		for (int i=1; i<node.getChildCount(); i = i+2) {
-			ParseTree operandTree1 = node.getChild(i-1);
-			ParseTree operandTree2 = node.getChild(i+1);
-			String reltype = getNodeCat(node.getChild(i).getChild(0));
-
-			LinkedHashMap<String,Object> group = null;
-			ArrayList<Object> operands = null;
-			// Retrieve operands.
-			LinkedHashMap<String, Object> operand1 = retrieveOperand(operandTree1);
-			LinkedHashMap<String, Object> operand2 = retrieveOperand(operandTree2);
-			// 'Proper' n_ary_linguistic_operators receive a considerably different serialisation than 'commonparent' and 'commonancestor'.
-			// For the latter cases, a dummy span is introduced and declared as a span class that has a dominance relation towards
-			// the two operands, one after the other, thus resulting in two nested relations! A Poliqarp+ equivalent for A $ B would be
-			// contains(focus(1:contains({1:<>},A)), B).
-			// This is modeled here...
-			if (reltype.equals("commonparent") || reltype.equals("commonancestor")) {
-				// make an (outer) group and an inner group containing the dummy node or previous relations
-				group = KoralObjectGenerator.makeGroup("relation");
-				LinkedHashMap<String,Object> innerGroup = KoralObjectGenerator.makeGroup("relation");
-				LinkedHashMap<String,Object> relation = KoralObjectGenerator.makeRelation();
-				LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
-				term.put("layer", "c");
-				relation.put("wrap", term);
-				// commonancestor is an indirect commonparent relation
-				if (reltype.equals("commonancestor")) relation.put("boundary", KoralObjectGenerator.makeBoundary(1, null));
-				group.put("relation", relation);
-				innerGroup.put("relation", relation);
-				// Get operands list before possible re-assignment of 'group' (see following 'if')
-				ArrayList<Object> outerOperands  = (ArrayList<Object>) group.get("operands");
-				ArrayList<Object> innerOperands  = (ArrayList<Object>) innerGroup.get("operands");
-				// for lowest level, add the underspecified node as first operand and wrap it in a class group
-				if (i == 1) {
-					innerOperands.add(KoralObjectGenerator.wrapInClass(KoralObjectGenerator.makeSpan(), classCounter));
-					// add the first operand and wrap the whole group in a focusing reference 
-					innerOperands.add(operand1);
-					innerGroup = KoralObjectGenerator.wrapInReference(innerGroup, classCounter, true);
-					outerOperands.add(innerGroup);
-				} else {
-					outerOperands.add(operandStack.pop());
-				}
-				// Lookahead: if next operator is not commonparent or commonancestor, wrap in class for accessibility
-				if (i < node.getChildCount()-2 && !getNodeCat(node.getChild(i+2).getChild(0)).startsWith("common")) {
-					operand2 = KoralObjectGenerator.wrapInClass(operand2, ++classCounter);
-				}
-				outerOperands.add(operand2);
-
-				// Wrap in another reference object in case other relations are following
-				if (i < node.getChildCount()-2) {
-					group = KoralObjectGenerator.wrapInReference(group, classCounter, true);
-				}
-				// All other n-ary linguistic relations have special 'relation' attributes defined in CQLF and can be
-				// handled more easily...
-			} else {
-				LinkedHashMap<String, Object> operatorGroup = parseOperatorNode(node.getChild(i).getChild(0));
-				String groupType;
-				try {
-					groupType = (String) operatorGroup.get("groupType");
-				} catch (ClassCastException | NullPointerException n) {
-					groupType = "relation";
-				}
-				if (groupType.equals("relation") || groupType.equals("treeRelation")) {
-					group = KoralObjectGenerator.makeGroup(groupType);
-					LinkedHashMap<String, Object> relation = new LinkedHashMap<String, Object>();
-					putAllButGroupType(relation, operatorGroup);
-					group.put("relation", relation);
-				} else if (groupType.equals("sequence")) {
-					group = KoralObjectGenerator.makeGroup(groupType);
-					putAllButGroupType(group, operatorGroup);
-				} else if (groupType.equals("position")) {
-					group = new LinkedHashMap<String,Object>();
-					putAllButGroupType(group, operatorGroup);
-				}
-					
-				// Get operands list before possible re-assignment of 'group' (see following 'if')
-				operands  = (ArrayList<Object>) group.get("operands");
-				
-				ParseTree leftChildSpec = getFirstChildWithCat(node.getChild(i).getChild(0), "@l");
-				ParseTree rightChildSpec = getFirstChildWithCat(node.getChild(i).getChild(0), "@r");
-				if (leftChildSpec != null || rightChildSpec != null) {
-					String frame = (leftChildSpec!=null) ? "frames:startswith" : "frames:endswith";
-					LinkedHashMap<String,Object> positionGroup = KoralObjectGenerator.makePosition(new String[]{frame}, null);
-					operand2 = KoralObjectGenerator.wrapInClass(operand2, ++classCounter);
-					((ArrayList<Object>) positionGroup.get("operands")).add(group);
-					((ArrayList<Object>) positionGroup.get("operands")).add(KoralObjectGenerator.makeReference(classCounter,true));
-					group = positionGroup;
-				}
-				
-				// Wrap in reference object in case other relations are following
-				if (i < node.getChildCount()-2) {
-					group = KoralObjectGenerator.wrapInReference(group, classCounter, true);
-				}
-
-				// Inject operands.
-				// -> Case distinction:
-				if (node.getChildCount()==3) {
-					// Things are easy when there's just one operator (thus 3 children incl. operands)...
-					if (operand1 != null) operands.add(operand1);
-					if (operand2 != null) operands.add(operand2);
-				} else {
-					// ... but things get a little more complicated here. The AST is of this form: (operand1 operator1 operand2 operator2 operand3 operator3 ...)
-					// but we'll have to serialize it in a nested, binary way: (((operand1 operator1 operand2) operator2 operand3) operator3 ...)
-					// the following code will do just that:
-					if (i == 1) {
-						// for the first operator, include both operands
-						if (operand1 != null) operands.add(operand1);
-						if (operand2 != null) operands.add(KoralObjectGenerator.wrapInClass(operand2, classCounter++));
-						// Don't put this into the super object directly but store on operandStack 
-						// (because this group will have to be an operand of a subsequent operator)
-						operandStack.push(group);
-						// for all subsequent operators, only take the 2nd operand (first was already added by previous operator)
-					} else if (i < node.getChildCount()-2) {
-						// for all intermediate operators, include other previous groups and 2nd operand. Store this on the operandStack, too.
-						if (operand2 != null) operands.add(KoralObjectGenerator.wrapInClass(operand2, classCounter++));
-						operands.add(0, operandStack.pop());
-						operandStack.push(group);
-					} else if (i == node.getChildCount()-2) {
-						// This is the last operator. Include 2nd operand only
-						if (operand2 != null) operands.add(operand2);
-					}
-				}
-			}
-			// Final step: decide what to do with the 'group' object, depending on whether all relations have been processed
-			System.err.println(i == node.getChildCount()-2 && relationCounter == totalRelationCount);
-			if (i == node.getChildCount()-2 && relationCounter == totalRelationCount) {
-				putIntoSuperObject(group);
-				if (!operandStack.isEmpty()) {
-					operands.add(0, operandStack.pop());
-				}
-				objectStack.push(group);
-				stackedObjects++;
-			} else {
-				operandStack.push(group);
-			}
-		}
-	}
+        /*
+         **************************************************************
+         * Stuff that happens after processing the children of a node *
+         **************************************************************
+         */
+        if (!objectsToPop.isEmpty()) {
+            for (int i=0; i<objectsToPop.pop(); i++) {
+                objectStack.pop();   
+            }
+        }
+        openNodeCats.pop();
+    }
 
 
 
-	/**
-	 * Parses a unary_linguistic_operator node. Possible operators are: root, arity, tokenarity.
-	 * Operators are embedded into a korap:term, in turn wrapped by an 'attr' property in a korap:span.
-	 * @param node The unary_linguistic_operator node
-	 * @return A map containing the attr key, to be inserted into korap:span 
-	 */
-	private LinkedHashMap<String, Object> parseUnaryOperator(ParseTree node) {
-		LinkedHashMap<String, Object> attr = new LinkedHashMap<String, Object>();
-		LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
-		String op = node.getChild(1).toStringTree(parser).substring(1);
-		if (op.equals("arity") || op.equals("tokenarity")) {
-			LinkedHashMap<String, Object> boundary = boundaryFromRangeSpec(node.getChild(3), false);
-			term.put(op, boundary);
-		} else {
-			term.put(op, true);
-		}
-		attr.put("attr", term);
-		return attr;
-	}
+    private void processAndTopExpr(ParseTree node) {
+        // Before processing any child expr node, check if it has one or more "*ary_linguistic_term" nodes.
+        // Those nodes may use references to earlier established operand nodes.
+        // Those operand nodes are not to be included into the query map individually but
+        // naturally as operands of the relations/groups introduced by the 
+        // *node. For that purpose, this section mines all used references
+        // and stores them in a list for later reference.
+        for (ParseTree exprNode : getChildrenWithCat(node,"expr")) {
+            // Pre-process any 'variableExpr' such that the variableReferences map can be filled
+            List<ParseTree> definitionNodes = new ArrayList<ParseTree>();
+            definitionNodes.addAll(getChildrenWithCat(exprNode, "variableExpr"));
+            for (ParseTree definitionNode : definitionNodes) {
+                processNode(definitionNode);
+            }
+            // Then, mine all relations between nodes
+            List<ParseTree> lingTermNodes = new ArrayList<ParseTree>();
+            lingTermNodes.addAll(getChildrenWithCat(exprNode, "n_ary_linguistic_term"));
+            globalLingTermNodes.addAll(lingTermNodes);
+            totalRelationCount  = globalLingTermNodes.size();
+            // Traverse refOrNode nodes under *ary_linguistic_term nodes and extract references
+            for (ParseTree lingTermNode : lingTermNodes) {
+                for (ParseTree refOrNode : getChildrenWithCat(lingTermNode, "refOrNode")) {
+                    String refOrNodeString = refOrNode.getChild(0).toStringTree(parser);
+                    if (refOrNodeString.startsWith("#")) {
+                        String ref = refOrNode.getChild(0).toStringTree(parser).substring(1);
+                        if (nodeReferencesTotal.containsKey(ref)) {
+                            nodeReferencesTotal.put(ref, nodeReferencesTotal.get(ref)+1);
+                        } else {
+                            nodeReferencesTotal.put(ref, 1);
+                            nodeReferencesProcessed.put(ref, 0);
+                        }
+                    }
+                }
+            }
+        }
+        if (verbose) System.err.println(nodeVariables);
+    }
 
-	@SuppressWarnings("unchecked")
-	private LinkedHashMap<String, Object> parseOperatorNode(ParseTree operatorNode) {
-		LinkedHashMap<String, Object> relation = null;
-		String operator = getNodeCat(operatorNode);
-		// DOMINANCE
-		if (operator.equals("dominance")) {
-			relation = KoralObjectGenerator.makeRelation();
-			relation.put("groupType", "relation");
-			ParseTree qName = getFirstChildWithCat(operatorNode, "qName");
-			ParseTree edgeSpecNode = getFirstChildWithCat(operatorNode, "edgeSpec");
-			ParseTree star = getFirstChildWithCat(operatorNode, "*");
-			ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
-			LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
-			term.put("layer", "c");
-			if (qName != null) term = parseQNameNode(qName);
-			if (edgeSpecNode != null) {
-				LinkedHashMap<String,Object> edgeSpec = parseEdgeSpec(edgeSpecNode);
-				String edgeSpecType = (String) edgeSpec.get("@type");
-				if (edgeSpecType.equals("korap:termGroup")) {
-					((ArrayList<Object>) edgeSpec.get("operands")).add(term);
-					term = edgeSpec;
-				} else {
-					term = KoralObjectGenerator.makeTermGroup("and");
-					ArrayList<Object> termGroupOperands = (ArrayList<Object>) term.get("operands");
-					termGroupOperands.add(edgeSpec);
-					LinkedHashMap<String,Object> constTerm = KoralObjectGenerator.makeTerm();
-					constTerm.put("layer", "c");
-					termGroupOperands.add(constTerm);
-				}
-			}
-			if (star != null) relation.put("boundary", KoralObjectGenerator.makeBoundary(0, null));
-			if (rangeSpec != null) relation.put("boundary", boundaryFromRangeSpec(rangeSpec));
-			relation.put("wrap", term);
-		}
-		else if (operator.equals("pointing")) {
-			//			String reltype = operatorNode.getChild(1).toStringTree(parser);
-			relation = KoralObjectGenerator.makeRelation();
-			relation.put("groupType", "relation");
-			ParseTree qName = getFirstChildWithCat(operatorNode, "qName");
-			ParseTree edgeSpec = getFirstChildWithCat(operatorNode, "edgeSpec");
-			ParseTree star = getFirstChildWithCat(operatorNode, "*");
-			ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
-			//			if (qName != null) relation.putAll(parseQNameNode(qName));
-			LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
-			if (qName != null) term.putAll(parseQNameNode(qName));
-			if (edgeSpec != null) term.putAll(parseEdgeSpec(edgeSpec));
-			if (star != null) relation.put("boundary", KoralObjectGenerator.makeBoundary(0, null));
-			if (rangeSpec != null) relation.put("boundary", boundaryFromRangeSpec(rangeSpec));
-			relation.put("wrap", term);
-		}
-		else if (operator.equals("precedence")) {
-			relation = new LinkedHashMap<String, Object>();
-			relation.put("groupType", "sequence");
-			ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
-			ParseTree star = getFirstChildWithCat(operatorNode, "*");
-			ArrayList<Object> distances = new ArrayList<Object>();
-			if (star != null) {
-				distances.add(KoralObjectGenerator.makeDistance("w", 0, null));
-				relation.put("distances", distances);
-			}
-			if (rangeSpec != null) {
-				distances.add(parseDistance(rangeSpec));
-				relation.put("distances", distances);
-			}
-			relation.put("inOrder", true);
-		}
-		else if (operator.equals("spanrelation")) {
-//			relation = makeGroup("position");
-//			relation.put("groupType", "position");
-			String reltype = operatorNode.getChild(0).toStringTree(parser);
-			String[] frames = new String[]{};
-			switch (reltype) {
-			case "_=_":
-				frames = new String[]{"frames:matches"}; 
-				break;
-			case "_l_":
-				frames = new String[]{"frames:startswith"};
-				break;
-			case "_r_":
-				frames = new String[]{"frames:endswith"};
-				break;
-			case "_i_":
-				frames = new String[]{"frames:contains"};break;
-			case "_o_":
-				frames = new String[]{"frames:overlapsLeft", "frames:overlapsRight"};
-				break;
-			case "_ol_":
-				frames = new String[]{"frames:overlapsLeft"};
-				break;
-			case "_or_":
-				frames = new String[]{"frames:overlapsRight"};
-				break;
-			}
-//			relation.put("frames", frames);
-//			relation.put("sharedClasses", sharedClasses);
-			relation = KoralObjectGenerator.makePosition(frames, new String[]{});
-			relation.put("groupType", "position");
-		}
-		else if (operator.equals("identity")) {
-			//TODO since ANNIS v. 3.1.6
-		}
-		else if (operator.equals("equalvalue")) {
-			//TODO since ANNIS v. 3.1.6
-		}
-		else if (operator.equals("notequalvalue")) {
-			//TODO since ANNIS v. 3.1.6
-		}
-		return relation;
-	}
+    private void processUnary_linguistic_term(ParseTree node) {
+        LinkedHashMap<String, Object> unaryOperator = parseUnaryOperator(node);
+        String reference = node.getChild(0).toStringTree(parser).substring(1);
+        LinkedHashMap<String, Object> object = nodeVariables.get(reference);
+        object.putAll(unaryOperator);
+    }
 
-	@SuppressWarnings("unchecked")
-	private LinkedHashMap<String,Object> parseEdgeSpec(ParseTree edgeSpec) {
-		List<ParseTree> annos = getChildrenWithCat(edgeSpec, "edgeAnno");
-		if (annos.size() == 1) return parseEdgeAnno(annos.get(0));
-		else {
-			LinkedHashMap<String,Object> termGroup = KoralObjectGenerator.makeTermGroup("and");
-			ArrayList<Object> operands = (ArrayList<Object>) termGroup.get("operands");
-			for (ParseTree anno : annos) {
-				operands.add(parseEdgeAnno(anno));
-			}
-			return termGroup;
-		}
-	}
+    private void processExprTop(ParseTree node) {
+        List<ParseTree> andTopExprs = getChildrenWithCat(node, "andTopExpr");
+        if (andTopExprs.size() > 1) {
+            LinkedHashMap<String, Object> topOr = KoralObjectGenerator.makeGroup("or");
+            requestMap.put("query", topOr);
+            objectStack.push(topOr);
+        }
+    }
 
-	private LinkedHashMap<String, Object> parseEdgeAnno(ParseTree edgeAnnoSpec) {
-		LinkedHashMap<String, Object> edgeAnno = new LinkedHashMap<String, Object>();
-		edgeAnno.put("@type", "korap:term");
-		ParseTree textSpecNode = getFirstChildWithCat(edgeAnnoSpec, "textSpec");
-		ParseTree layerNode = getFirstChildWithCat(edgeAnnoSpec, "layer");
-		ParseTree foundryNode = getFirstChildWithCat(edgeAnnoSpec, "foundry");
-		ParseTree matchOperatorNode = getFirstChildWithCat(edgeAnnoSpec, "eqOperator");
-		if (foundryNode!=null) edgeAnno.put("foundry", foundryNode.getChild(0).toStringTree(parser));
-		if (layerNode!=null) edgeAnno.put("layer", layerNode.getChild(0).toStringTree(parser));
-		edgeAnno.putAll(parseTextSpec(textSpecNode));
-		edgeAnno.put("match", parseMatchOperator(matchOperatorNode));
-		return edgeAnno;
-	}
+    private LinkedHashMap<String, Object> processVariableExpr(ParseTree node) {
+        // simplex word or complex assignment (like qname = textSpec)?
+        String firstChildNodeCat = getNodeCat(node.getChild(0));
+        LinkedHashMap<String, Object> object = null;
+        if (firstChildNodeCat.equals("node")) {
+            object = KoralObjectGenerator.makeSpan();
+        } else if (firstChildNodeCat.equals("tok")) {
+            object = KoralObjectGenerator.makeToken();
+            if (node.getChildCount() > 1) { // empty tokens do not wrap a term
+                LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
+                term.put("layer", "orth");
+                object.put("wrap", term);
+            }
+        } else if (firstChildNodeCat.equals("qName")) {	// only (foundry/)?layer specified
+            // may be token or span, depending on indicated layer! (e.g. cnx/cat=NP vs mate/pos=NN)
+            // TODO generalize the list below -> look up layers associated with tokens rather than spans somewhere
+            HashMap<String, Object> qNameParse = parseQNameNode(node.getChild(0));
+            if (Arrays.asList(new String[]{"p", "lemma", "m", "orth"}).contains(qNameParse.get("layer"))) { 
+                object = KoralObjectGenerator.makeToken();
+                LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
+                object.put("wrap", term);
+                term.putAll(qNameParse);
+            } else {
+                object = KoralObjectGenerator.makeSpan();
+                object.putAll(qNameParse);
+            }
+        } else if (firstChildNodeCat.equals("textSpec")) {
+            object = KoralObjectGenerator.makeToken();
+            LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
+            object.put("wrap", term);
+            term.put("layer", "orth");
+            term.putAll(parseTextSpec(node.getChild(0)));
+        }
 
-	private LinkedHashMap<String, Object> boundaryFromRangeSpec(ParseTree rangeSpec) {
-		return boundaryFromRangeSpec(rangeSpec, true); 
-	}
+        if (node.getChildCount() == 3) {  			// (foundry/)?layer=key specification
+            if (object.get("@type").equals("korap:token")) {
+                @SuppressWarnings("unchecked")
+                HashMap<String, Object> term = (HashMap<String, Object>) object.get("wrap");
+                term.putAll(parseTextSpec(node.getChild(2)));
+                term.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
+            } else {
+                object.putAll(parseTextSpec(node.getChild(2)));
+                object.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
+            }
+        }
 
-	private LinkedHashMap<String, Object> boundaryFromRangeSpec(ParseTree rangeSpec, boolean expandToMax) {
-		Integer min = Integer.parseInt(rangeSpec.getChild(0).toStringTree(parser));
-		Integer max = min;
-		if (expandToMax) max = null;
-		if (rangeSpec.getChildCount()==3) 
-			max = Integer.parseInt(rangeSpec.getChild(2).toStringTree(parser));
-		return KoralObjectGenerator.makeBoundary(min, max);
-	}
+        if (object != null) {
+            ParseTree grandparent = node.getParent().getParent();
+            if (getNodeCat(grandparent).equals("andTopExpr") && 
+                    grandparent.getChildCount()==1) { 
+                // query: object only, no relation
+                putIntoSuperObject(object);
+            }
+            ParseTree parentsFirstChild = node.getParent().getChild(0);
+            if (getNodeCat(parentsFirstChild).endsWith("#")) {
+                nodeVariables.put(getNodeCat(parentsFirstChild).replaceAll("#", ""), object);
+            }
+            nodeVariables.put(variableCounter.toString(), object);
+            variableCounter++;
+        }
+        return object;
+    }
 
-	private LinkedHashMap<String, Object> parseDistance(ParseTree rangeSpec) {
-		Integer min = Integer.parseInt(rangeSpec.getChild(0).toStringTree(parser));
-		Integer max = null;
-		if (rangeSpec.getChildCount()==3) 
-			max = Integer.parseInt(rangeSpec.getChild(2).toStringTree(parser));
-		return KoralObjectGenerator.makeDistance("w", min, max);
-	}
+    /**
+     * Processes an operand node, creating a map for the operand containing all its information
+     * given in the node definition (referenced via '#'). If this node has been referred to and used earlier,
+     * a reference is created in its place. 
+     * The operand will be wrapped in a class group if necessary.
+     * @param operandNode
+     * @return A map object with the appropriate CQLF representation of the operand 
+     */
+    private LinkedHashMap<String, Object> retrieveOperand(ParseTree operandNode) {
+        LinkedHashMap<String, Object> operand = null;
+        if (!getNodeCat(operandNode.getChild(0)).equals("variableExpr")) {
+            String ref = operandNode.getChild(0).toStringTree(parser).substring(1);
+            operand = nodeVariables.get(ref);
+            if (nodeReferencesTotal.get(ref) > 1) {
+                if (nodeReferencesProcessed.get(ref)==0) {
+                    refClassMapping.put(ref, classCounter);
+                    operand = KoralObjectGenerator.wrapInClass(operand, classCounter++);
+                } else if (nodeReferencesProcessed.get(ref)>0 && nodeReferencesTotal.get(ref)>1) {
+                    try {
+                        operand = KoralObjectGenerator.wrapInReference(operandStack.pop(), refClassMapping.get(ref), true);
+                    } catch (NoSuchElementException e) {
+                        operand = KoralObjectGenerator.makeReference(refClassMapping.get(ref), true);
+                    }
+                }
+                nodeReferencesProcessed.put(ref, nodeReferencesProcessed.get(ref)+1);
+            }
+        } else {
+            operand = processVariableExpr(operandNode.getChild(0));
+        }
+        return operand;
+    }
 
-	private LinkedHashMap<String, Object> parseTextSpec(ParseTree node) {
-		LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
-		if (hasChild(node, "regex")) {
-			term.put("type", "type:regex");
-			term.put("key", node.getChild(0).getChild(0).toStringTree(parser).replaceAll("/", ""));
-		} else {
-			term.put("key", node.getChild(1).toStringTree(parser));
-		}
-		term.put("match", "match:eq");
-		return term;
-	}
+    /**
+     * @param node
+     * @return
+     */
+    private boolean checkOperandsProcessedPreviously(ParseTree node) {
+        // We can assume two operands.
+        ParseTree operand1 = node.getChild(0);
+        ParseTree operand2 = node.getChild(2);
 
-	/**
-	 * Parses the match operator (= or !=)
-	 * @param node
-	 * @return
-	 */
-	private String parseMatchOperator(ParseTree node) {
-		if (node.getChildCount()>0) {
-			return node.getChild(0).toStringTree(parser).equals("=") ? "match:eq" : "match:ne";
-		}
-		return null;
-	}
+        String operandRef1 = operand1.getText();
+        String operandRef2 = operand2.getText();
+        // only if they're both references...
+        if (operandRef1.startsWith("#") && operandRef2.startsWith("#")) {
+            operandRef1 = operandRef1.substring(1, operandRef1.length());
+            operandRef2 = operandRef2.substring(1, operandRef2.length());
+            if (nodeReferencesProcessed.get(operandRef1) > 0 || 
+                    nodeReferencesProcessed.get(operandRef2) > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 
-	private LinkedHashMap<String, Object> parseQNameNode(ParseTree node) {
-		LinkedHashMap<String, Object> fields = new LinkedHashMap<String, Object>();
-		ParseTree layerNode = getFirstChildWithCat(node, "layer");
-		ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
-		if (foundryNode != null) fields.put("foundry", foundryNode.getChild(0).toStringTree(parser));
-		String layer = layerNode.getChild(0).toStringTree(parser);
-		if (layer.equals("pos")) layer = "p";
-		if (layer.equals("cat")) layer = "c";
-		fields.put("layer", layer);
-		return fields;
-	}
+    @SuppressWarnings("unchecked")
+    private void processN_ary_linguistic_term(ParseTree node) {
+        relationCounter++;
+        // get operator and determine type of group (sequence/treeRelation/relation/...)
+        // It's possible in Annis QL to concatenate operators, so there may be several operators under one n_ary_linguistic_term node. 
+        // Counter 'i' will iteratively point to all operator nodes (odd-numbered) under this node.
+        for (int i=1; i<node.getChildCount(); i = i+2) {
+            ParseTree operandTree1 = node.getChild(i-1);
+            ParseTree operandTree2 = node.getChild(i+1);
+            String reltype = getNodeCat(node.getChild(i).getChild(0));
 
-	private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
-		putIntoSuperObject(object, 0);
-	}
+            LinkedHashMap<String,Object> group = null;
+            ArrayList<Object> operands = null;
+            // make sure one of the operands has already been put into a 
+            // relation (if this is not the 1st relation). If it is,
+            // queue this relation for later processing.
+            if (relationCounter != 1) {
+                if (! checkOperandsProcessedPreviously(node)) {
+                    queuedRelations.add(node);
+                    relationCounter--;
+                    if (verbose) System.out.println("Adding to queue: "+node.getText());
+                    objectsToPop.push(stackedObjects);
+                    return;
+                }
+            }
+            // Retrieve operands.
+            LinkedHashMap<String, Object> operand1 = retrieveOperand(operandTree1);
+            LinkedHashMap<String, Object> operand2 = retrieveOperand(operandTree2);
+            // 'Proper' n_ary_linguistic_operators receive a considerably different serialisation than 'commonparent' and 'commonancestor'.
+            // For the latter cases, a dummy span is introduced and declared as a span class that has a dominance relation towards
+            // the two operands, one after the other, thus resulting in two nested relations! A Poliqarp+ equivalent for A $ B would be
+            // contains(focus(1:contains({1:<>},A)), B).
+            // This is modeled here...
+            if (reltype.equals("commonparent") || reltype.equals("commonancestor")) {
+                // make an (outer) group and an inner group containing the dummy node or previous relations
+                group = KoralObjectGenerator.makeGroup("relation");
+                LinkedHashMap<String,Object> innerGroup = KoralObjectGenerator.makeGroup("relation");
+                LinkedHashMap<String,Object> relation = KoralObjectGenerator.makeRelation();
+                LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
+                term.put("layer", "c");
+                relation.put("wrap", term);
+                // commonancestor is an indirect commonparent relation
+                if (reltype.equals("commonancestor")) relation.put("boundary", KoralObjectGenerator.makeBoundary(1, null));
+                group.put("relation", relation);
+                innerGroup.put("relation", relation);
+                // Get operands list before possible re-assignment of 'group' (see following 'if')
+                ArrayList<Object> outerOperands  = (ArrayList<Object>) group.get("operands");
+                ArrayList<Object> innerOperands  = (ArrayList<Object>) innerGroup.get("operands");
+                // for lowest level, add the underspecified node as first operand and wrap it in a class group
+                if (i == 1) {
+                    innerOperands.add(KoralObjectGenerator.wrapInClass(KoralObjectGenerator.makeSpan(), classCounter));
+                    // add the first operand and wrap the whole group in a focusing reference 
+                    innerOperands.add(operand1);
+                    innerGroup = KoralObjectGenerator.wrapInReference(innerGroup, classCounter, true);
+                    outerOperands.add(innerGroup);
+                } else {
+                    outerOperands.add(operandStack.pop());
+                }
+                // Lookahead: if next operator is not commonparent or commonancestor, wrap in class for accessibility
+                if (i < node.getChildCount()-2 && !getNodeCat(node.getChild(i+2).getChild(0)).startsWith("common")) {
+                    operand2 = KoralObjectGenerator.wrapInClass(operand2, ++classCounter);
+                }
+                outerOperands.add(operand2);
 
-	@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);
-			}
-		} else {
-			requestMap.put("query", object);
-		}
-	}
+                // Wrap in another reference object in case other relations are following
+                if (i < node.getChildCount()-2) {
+                    group = KoralObjectGenerator.wrapInReference(group, classCounter, true);
+                }
+                // All other n-ary linguistic relations have special 'relation' attributes defined in CQLF and can be
+                // handled more easily...
+            } else {
+                LinkedHashMap<String, Object> operatorGroup = parseOperatorNode(node.getChild(i).getChild(0));
+                String groupType;
+                try {
+                    groupType = (String) operatorGroup.get("groupType");
+                } catch (ClassCastException | NullPointerException n) {
+                    groupType = "relation";
+                }
+                if (groupType.equals("relation") || groupType.equals("treeRelation")) {
+                    group = KoralObjectGenerator.makeGroup(groupType);
+                    LinkedHashMap<String, Object> relation = new LinkedHashMap<String, Object>();
+                    putAllButGroupType(relation, operatorGroup);
+                    group.put("relation", relation);
+                } else if (groupType.equals("sequence")) {
+                    group = KoralObjectGenerator.makeGroup(groupType);
+                    putAllButGroupType(group, operatorGroup);
+                } else if (groupType.equals("position")) {
+                    group = new LinkedHashMap<String,Object>();
+                    putAllButGroupType(group, operatorGroup);
+                }
 
-	private void putAllButGroupType(Map<String, Object> container, Map<String, Object> input) {
-		for (String key : input.keySet()) {
-			if (!key.equals("groupType")) {
-				container.put(key, input.get(key));
-			}
-		}
-	}
+                // Get operands list before possible re-assignment of 'group' (see following 'if')
+                operands  = (ArrayList<Object>) group.get("operands");
 
-	private ParserRuleContext parseAnnisQuery (String query) {
-		Lexer lexer = new AqlLexer((CharStream)null);
-		ParserRuleContext tree = null;
-		Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
-		// Like p. 111
-		try {
-			// Tokenize input data
-			ANTLRInputStream input = new ANTLRInputStream(query);
-			lexer.setInputStream(input);
-			CommonTokenStream tokens = new CommonTokenStream(lexer);
-			parser = new AqlParser(tokens);
-			// Don't throw out erroneous stuff
-			parser.setErrorHandler(new BailErrorStrategy());
-			lexer.removeErrorListeners();
+                ParseTree leftChildSpec = getFirstChildWithCat(node.getChild(i).getChild(0), "@l");
+                ParseTree rightChildSpec = getFirstChildWithCat(node.getChild(i).getChild(0), "@r");
+                if (leftChildSpec != null || rightChildSpec != null) {
+                    String frame = (leftChildSpec!=null) ? "frames:startswith" : "frames:endswith";
+                    LinkedHashMap<String,Object> positionGroup = KoralObjectGenerator.makePosition(new String[]{frame}, null);
+                    operand2 = KoralObjectGenerator.wrapInClass(operand2, ++classCounter);
+                    ((ArrayList<Object>) positionGroup.get("operands")).add(group);
+                    ((ArrayList<Object>) positionGroup.get("operands")).add(KoralObjectGenerator.makeReference(classCounter,true));
+                    group = positionGroup;
+                }
+
+                // Wrap in reference object in case other relations are following
+                if (i < node.getChildCount()-2) {
+                    group = KoralObjectGenerator.wrapInReference(group, classCounter, true);
+                }
+
+                // Inject operands.
+                // -> Case distinction:
+                if (node.getChildCount()==3) {
+                    // Things are easy when there's just one operator (thus 3 children incl. operands)...
+                    if (operand1 != null) operands.add(operand1);
+                    if (operand2 != null) operands.add(operand2);
+                } else {
+                    // ... but things get a little more complicated here. The AST is of this form: (operand1 operator1 operand2 operator2 operand3 operator3 ...)
+                    // but we'll have to serialize it in a nested, binary way: (((operand1 operator1 operand2) operator2 operand3) operator3 ...)
+                    // the following code will do just that:
+                    if (i == 1) {
+                        // for the first operator, include both operands
+                        if (operand1 != null) operands.add(operand1);
+                        if (operand2 != null) operands.add(KoralObjectGenerator.wrapInClass(operand2, classCounter++));
+                        // Don't put this into the super object directly but store on operandStack 
+                        // (because this group will have to be an operand of a subsequent operator)
+                        operandStack.push(group);
+                        // for all subsequent operators, only take the 2nd operand (first was already added by previous operator)
+                    } else if (i < node.getChildCount()-2) {
+                        // for all intermediate operators, include other previous groups and 2nd operand. Store this on the operandStack, too.
+                        if (operand2 != null) operands.add(KoralObjectGenerator.wrapInClass(operand2, classCounter++));
+                        operands.add(0, operandStack.pop());
+                        operandStack.push(group);
+                    } else if (i == node.getChildCount()-2) {
+                        // This is the last operator. Include 2nd operand only
+                        if (operand2 != null) operands.add(operand2);
+                    }
+                }
+            }
+            // Final step: decide what to do with the 'group' object, depending on whether all relations have been processed
+            if (i == node.getChildCount()-2 && relationCounter == totalRelationCount) {
+                putIntoSuperObject(group);
+                if (!operandStack.isEmpty()) {
+                    operands.add(0, operandStack.pop());
+                }
+                objectStack.push(group);
+                stackedObjects++;
+            } else {
+                operandStack.push(group);
+            }
+        }
+    }
+
+
+
+    /**
+     * Parses a unary_linguistic_operator node. Possible operators are: root, arity, tokenarity.
+     * Operators are embedded into a korap:term, in turn wrapped by an 'attr' property in a korap:span.
+     * @param node The unary_linguistic_operator node
+     * @return A map containing the attr key, to be inserted into korap:span 
+     */
+    private LinkedHashMap<String, Object> parseUnaryOperator(ParseTree node) {
+        LinkedHashMap<String, Object> attr = new LinkedHashMap<String, Object>();
+        LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
+        String op = node.getChild(1).toStringTree(parser).substring(1);
+        if (op.equals("arity") || op.equals("tokenarity")) {
+            LinkedHashMap<String, Object> boundary = boundaryFromRangeSpec(node.getChild(3), false);
+            term.put(op, boundary);
+        } else {
+            term.put(op, true);
+        }
+        attr.put("attr", term);
+        return attr;
+    }
+
+    @SuppressWarnings("unchecked")
+    private LinkedHashMap<String, Object> parseOperatorNode(ParseTree operatorNode) {
+        LinkedHashMap<String, Object> relation = null;
+        String operator = getNodeCat(operatorNode);
+        // DOMINANCE
+        if (operator.equals("dominance")) {
+            relation = KoralObjectGenerator.makeRelation();
+            relation.put("groupType", "relation");
+            ParseTree qName = getFirstChildWithCat(operatorNode, "qName");
+            ParseTree edgeSpecNode = getFirstChildWithCat(operatorNode, "edgeSpec");
+            ParseTree star = getFirstChildWithCat(operatorNode, "*");
+            ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
+            LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
+            term.put("layer", "c");
+            if (qName != null) term = parseQNameNode(qName);
+            if (edgeSpecNode != null) {
+                LinkedHashMap<String,Object> edgeSpec = parseEdgeSpec(edgeSpecNode);
+                String edgeSpecType = (String) edgeSpec.get("@type");
+                if (edgeSpecType.equals("korap:termGroup")) {
+                    ((ArrayList<Object>) edgeSpec.get("operands")).add(term);
+                    term = edgeSpec;
+                } else {
+                    term = KoralObjectGenerator.makeTermGroup("and");
+                    ArrayList<Object> termGroupOperands = (ArrayList<Object>) term.get("operands");
+                    termGroupOperands.add(edgeSpec);
+                    LinkedHashMap<String,Object> constTerm = KoralObjectGenerator.makeTerm();
+                    constTerm.put("layer", "c");
+                    termGroupOperands.add(constTerm);
+                }
+            }
+            if (star != null) relation.put("boundary", KoralObjectGenerator.makeBoundary(0, null));
+            if (rangeSpec != null) relation.put("boundary", boundaryFromRangeSpec(rangeSpec));
+            relation.put("wrap", term);
+        }
+        else if (operator.equals("pointing")) {
+            //			String reltype = operatorNode.getChild(1).toStringTree(parser);
+            relation = KoralObjectGenerator.makeRelation();
+            relation.put("groupType", "relation");
+            ParseTree qName = getFirstChildWithCat(operatorNode, "qName");
+            ParseTree edgeSpec = getFirstChildWithCat(operatorNode, "edgeSpec");
+            ParseTree star = getFirstChildWithCat(operatorNode, "*");
+            ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
+            //			if (qName != null) relation.putAll(parseQNameNode(qName));
+            LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
+            if (qName != null) term.putAll(parseQNameNode(qName));
+            if (edgeSpec != null) term.putAll(parseEdgeSpec(edgeSpec));
+            if (star != null) relation.put("boundary", KoralObjectGenerator.makeBoundary(0, null));
+            if (rangeSpec != null) relation.put("boundary", boundaryFromRangeSpec(rangeSpec));
+            relation.put("wrap", term);
+        }
+        else if (operator.equals("precedence")) {
+            relation = new LinkedHashMap<String, Object>();
+            relation.put("groupType", "sequence");
+            ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
+            ParseTree star = getFirstChildWithCat(operatorNode, "*");
+            ArrayList<Object> distances = new ArrayList<Object>();
+            if (star != null) {
+                distances.add(KoralObjectGenerator.makeDistance("w", 0, null));
+                relation.put("distances", distances);
+            }
+            if (rangeSpec != null) {
+                distances.add(parseDistance(rangeSpec));
+                relation.put("distances", distances);
+            }
+            relation.put("inOrder", true);
+        }
+        else if (operator.equals("spanrelation")) {
+            //			relation = makeGroup("position");
+            //			relation.put("groupType", "position");
+            String reltype = operatorNode.getChild(0).toStringTree(parser);
+            String[] frames = new String[]{};
+            switch (reltype) {
+                case "_=_":
+                    frames = new String[]{"frames:matches"}; 
+                    break;
+                case "_l_":
+                    frames = new String[]{"frames:startswith"};
+                    break;
+                case "_r_":
+                    frames = new String[]{"frames:endswith"};
+                    break;
+                case "_i_":
+                    frames = new String[]{"frames:contains"};break;
+                case "_o_":
+                    frames = new String[]{"frames:overlapsLeft", "frames:overlapsRight"};
+                    break;
+                case "_ol_":
+                    frames = new String[]{"frames:overlapsLeft"};
+                    break;
+                case "_or_":
+                    frames = new String[]{"frames:overlapsRight"};
+                    break;
+            }
+            //			relation.put("frames", frames);
+            //			relation.put("sharedClasses", sharedClasses);
+            relation = KoralObjectGenerator.makePosition(frames, new String[]{});
+            relation.put("groupType", "position");
+        }
+        else if (operator.equals("identity")) {
+            //TODO since ANNIS v. 3.1.6
+        }
+        else if (operator.equals("equalvalue")) {
+            //TODO since ANNIS v. 3.1.6
+        }
+        else if (operator.equals("notequalvalue")) {
+            //TODO since ANNIS v. 3.1.6
+        }
+        return relation;
+    }
+
+    @SuppressWarnings("unchecked")
+    private LinkedHashMap<String,Object> parseEdgeSpec(ParseTree edgeSpec) {
+        List<ParseTree> annos = getChildrenWithCat(edgeSpec, "edgeAnno");
+        if (annos.size() == 1) return parseEdgeAnno(annos.get(0));
+        else {
+            LinkedHashMap<String,Object> termGroup = KoralObjectGenerator.makeTermGroup("and");
+            ArrayList<Object> operands = (ArrayList<Object>) termGroup.get("operands");
+            for (ParseTree anno : annos) {
+                operands.add(parseEdgeAnno(anno));
+            }
+            return termGroup;
+        }
+    }
+
+    private LinkedHashMap<String, Object> parseEdgeAnno(ParseTree edgeAnnoSpec) {
+        LinkedHashMap<String, Object> edgeAnno = new LinkedHashMap<String, Object>();
+        edgeAnno.put("@type", "korap:term");
+        ParseTree textSpecNode = getFirstChildWithCat(edgeAnnoSpec, "textSpec");
+        ParseTree layerNode = getFirstChildWithCat(edgeAnnoSpec, "layer");
+        ParseTree foundryNode = getFirstChildWithCat(edgeAnnoSpec, "foundry");
+        ParseTree matchOperatorNode = getFirstChildWithCat(edgeAnnoSpec, "eqOperator");
+        if (foundryNode!=null) edgeAnno.put("foundry", foundryNode.getChild(0).toStringTree(parser));
+        if (layerNode!=null) edgeAnno.put("layer", layerNode.getChild(0).toStringTree(parser));
+        edgeAnno.putAll(parseTextSpec(textSpecNode));
+        edgeAnno.put("match", parseMatchOperator(matchOperatorNode));
+        return edgeAnno;
+    }
+
+    private LinkedHashMap<String, Object> boundaryFromRangeSpec(ParseTree rangeSpec) {
+        return boundaryFromRangeSpec(rangeSpec, true); 
+    }
+
+    private LinkedHashMap<String, Object> boundaryFromRangeSpec(ParseTree rangeSpec, boolean expandToMax) {
+        Integer min = Integer.parseInt(rangeSpec.getChild(0).toStringTree(parser));
+        Integer max = min;
+        if (expandToMax) max = null;
+        if (rangeSpec.getChildCount()==3) 
+            max = Integer.parseInt(rangeSpec.getChild(2).toStringTree(parser));
+        return KoralObjectGenerator.makeBoundary(min, max);
+    }
+
+    private LinkedHashMap<String, Object> parseDistance(ParseTree rangeSpec) {
+        Integer min = Integer.parseInt(rangeSpec.getChild(0).toStringTree(parser));
+        Integer max = null;
+        if (rangeSpec.getChildCount()==3) 
+            max = Integer.parseInt(rangeSpec.getChild(2).toStringTree(parser));
+        return KoralObjectGenerator.makeDistance("w", min, max);
+    }
+
+    private LinkedHashMap<String, Object> parseTextSpec(ParseTree node) {
+        LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
+        if (hasChild(node, "regex")) {
+            term.put("type", "type:regex");
+            term.put("key", node.getChild(0).getChild(0).toStringTree(parser).replaceAll("/", ""));
+        } else {
+            term.put("key", node.getChild(1).toStringTree(parser));
+        }
+        term.put("match", "match:eq");
+        return term;
+    }
+
+    /**
+     * Parses the match operator (= or !=)
+     * @param node
+     * @return
+     */
+    private String parseMatchOperator(ParseTree node) {
+        if (node.getChildCount()>0) {
+            return node.getChild(0).toStringTree(parser).equals("=") ? "match:eq" : "match:ne";
+        }
+        return null;
+    }
+
+    private LinkedHashMap<String, Object> parseQNameNode(ParseTree node) {
+        LinkedHashMap<String, Object> fields = new LinkedHashMap<String, Object>();
+        ParseTree layerNode = getFirstChildWithCat(node, "layer");
+        ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
+        if (foundryNode != null) fields.put("foundry", foundryNode.getChild(0).toStringTree(parser));
+        String layer = layerNode.getChild(0).toStringTree(parser);
+        if (layer.equals("pos")) layer = "p";
+        if (layer.equals("cat")) layer = "c";
+        fields.put("layer", layer);
+        return fields;
+    }
+
+    private void putIntoSuperObject(LinkedHashMap<String, Object> object) {
+        putIntoSuperObject(object, 0);
+    }
+
+    @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);
+            }
+        } else {
+            requestMap.put("query", object);
+        }
+    }
+
+    private void putAllButGroupType(Map<String, Object> container, Map<String, Object> input) {
+        for (String key : input.keySet()) {
+            if (!key.equals("groupType")) {
+                container.put(key, input.get(key));
+            }
+        }
+    }
+
+    private ParserRuleContext parseAnnisQuery (String query) {
+        Lexer lexer = new AqlLexer((CharStream)null);
+        ParserRuleContext tree = null;
+        Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
+        // Like p. 111
+        try {
+            // Tokenize input data
+            ANTLRInputStream input = new ANTLRInputStream(query);
+            lexer.setInputStream(input);
+            CommonTokenStream tokens = new CommonTokenStream(lexer);
+            parser = new AqlParser(tokens);
+            // Don't throw out erroneous stuff
+            parser.setErrorHandler(new BailErrorStrategy());
+            lexer.removeErrorListeners();
             lexer.addErrorListener(errorListener);
             parser.removeErrorListeners();
             parser.addErrorListener(errorListener);
-			// Get starting rule from parser
-			Method startRule = AqlParser.class.getMethod("start"); 
-			tree = (ParserRuleContext) startRule.invoke(parser, (Object[])null);
-		}
-		// Some things went wrong ...
-		catch (Exception e) {
-			log.error("Could not parse query. Please make sure it is well-formed.");
-			log.error(errorListener.generateFullErrorMsg().toString());
-			addError(errorListener.generateFullErrorMsg());
-		}
-		return tree;
-	}
+            // Get starting rule from parser
+            Method startRule = AqlParser.class.getMethod("start"); 
+            tree = (ParserRuleContext) startRule.invoke(parser, (Object[])null);
+        }
+        // Some things went wrong ...
+        catch (Exception e) {
+            log.error("Could not parse query. Please make sure it is well-formed.");
+            log.error(errorListener.generateFullErrorMsg().toString());
+            addError(errorListener.generateFullErrorMsg());
+        }
+        return tree;
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java
index ffdedf0..6416b0e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/StatusCodes.java
@@ -7,6 +7,7 @@
 	public final static int UNDEFINED_CLASS_REFERENCE = 304;
 	public final static int INCOMPATIBLE_OPERATOR_AND_OPERAND = 305;
 	public final static int UNKNOWN_QUERY_ELEMENT = 306;
-	public static final int UNKNOWN_QL = 307;
+	public final static int UNKNOWN_QL = 307;
+	public final static int UNBOUND_ANNIS_RELATION = 308;
 	public final static int UNKNOWN_QUERY_ERROR = 399;
 }
diff --git a/src/test/java/AnnisQueryProcessorTest.java b/src/test/java/AnnisQueryProcessorTest.java
index 2788dad..eb5a738 100644
--- a/src/test/java/AnnisQueryProcessorTest.java
+++ b/src/test/java/AnnisQueryProcessorTest.java
@@ -523,6 +523,58 @@
 //		assertEquals(seq6.replaceAll(" ", ""), map.replaceAll(" ", ""));
 //	}
 //	
+	/**
+	 * Tests the (rather difficult) serialization of queries where two subsequent relations
+	 * do not share any common operand. Makes it impossible to wrap 2nd relation around 1st. 
+	 * Must therefore re-order relations (or postpone processing of 2nd).
+	 * @throws JsonProcessingException
+	 * @throws IOException
+	 */
+	@Test
+    public void testNoSharedOperand() throws JsonProcessingException, IOException {
+	    query = "cat=\"A\" & cat=\"B\" & cat=\"C\" & cat=\"D\" & #1 . #2 & #3 . #4 & #1 > #3";  
+	    // the resulting query should be equivalent to PQ+:  focus(2:dominates(focus(1:{1:<A>}<B>),{2:<C>}))<D> 
+        qs.setQuery(query, "annis");
+        res = mapper.readTree(qs.toJSON());
+        assertEquals("korap:group",         res.at("/query/@type").asText());
+        assertEquals("operation:sequence",  res.at("/query/operation").asText());
+        assertEquals("korap:reference",     res.at("/query/operands/0/@type").asText());
+        assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
+        assertEquals("korap:group",         res.at("/query/operands/0/operands/0/@type").asText());
+        assertEquals("operation:relation",  res.at("/query/operands/0/operands/0/operation").asText());
+        assertEquals("korap:reference",     res.at("/query/operands/0/operands/0/operands/0/@type").asText());
+        assertEquals("operation:focus",     res.at("/query/operands/0/operands/0/operands/0/operation").asText());
+        assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/0/operands/0/@type").asText());
+        assertEquals("operation:sequence",  res.at("/query/operands/0/operands/0/operands/0/operands/0/operation").asText());
+        assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operation").asText());
+        assertEquals("A",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/key").asText());
+        assertEquals("B",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/1/key").asText());
+        assertEquals("C",                   res.at("/query/operands/0/operands/0/operands/1/operands/0/key").asText());
+        assertEquals("D",                   res.at("/query/operands/1/key").asText());
+        
+        query = "cat=\"A\" & cat=\"B\" & cat=\"C\" & cat=\"D\" & cat=\"E\" & cat=\"F\" & #1 . #2 & #3 . #4 & #5 . #6 & #1 > #3 & #3 > #5";  
+        // the resulting query should be equivalent to PQ+:   focus(3:dominates(focus(2:dominates(focus(1:{1:<A>}<B>),{2:<C>}))<D>,{3:<E>}))<F> 
+        qs.setQuery(query, "annis");
+        res = mapper.readTree(qs.toJSON());
+        assertEquals("korap:group",         res.at("/query/@type").asText());
+        assertEquals("operation:sequence",  res.at("/query/operation").asText());
+        assertEquals("korap:reference",     res.at("/query/operands/0/@type").asText());
+        assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
+        assertEquals("korap:group",         res.at("/query/operands/0/operands/0/@type").asText());
+        assertEquals("operation:relation",  res.at("/query/operands/0/operands/0/operation").asText());
+        assertEquals("korap:reference",     res.at("/query/operands/0/operands/0/operands/0/@type").asText());
+        assertEquals("operation:focus",     res.at("/query/operands/0/operands/0/operands/0/operation").asText());
+        assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/0/operands/0/@type").asText());
+        assertEquals("operation:sequence",  res.at("/query/operands/0/operands/0/operands/0/operands/0/operation").asText());
+        assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operation").asText());
+        assertEquals("A",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/key").asText());
+        assertEquals("B",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/1/key").asText());
+        assertEquals("C",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/operands/1/operands/0/key").asText());
+        assertEquals("D",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/1/key").asText());
+        assertEquals("E",                   res.at("/query/operands/0/operands/0/operands/1/operands/0/key").asText());
+        assertEquals("F",                   res.at("/query/operands/1/key").asText());
+    }
+	
 //	@Test
 //	public void testMultipleMixedOperators() throws Exception {
 //		query = "tok=\"Sonne\" & tok=\"Mond\" & tok=\"Sterne\" & #1 > #2 .0,4 #3";
