diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
index bb56d65..57c958f 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
@@ -103,14 +103,13 @@
 		} else {
 			throw new NullPointerException("Parser has not been instantiated!"); 
 		}
-		log.info("Processing Annis query.");
+		log.info("Processing Annis query: "+query);
 		if (tree != null) {
 			log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
 			processNode(tree);
 		}
 	}
 
-	@SuppressWarnings("unchecked")
 	private void processNode(ParseTree node) {
 		// Top-down processing
 		if (visited.contains(node)) return;
@@ -134,57 +133,15 @@
 		 ****************************************************************
 		 */
 		if (nodeCat.equals("exprTop")) {
-			List<ParseTree> andTopExprs = getChildrenWithCat(node, "andTopExpr");
-			if (andTopExprs.size() > 1) {
-				LinkedHashMap<String, Object> topOr = makeGroup("or");
-				requestMap.put("query", topOr);
-				objectStack.push(topOr);
-			}
+			processExprTop(node);
 		}
 
 		if (nodeCat.equals("andTopExpr")) {
-			// 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);
-							}
-						}
-					}
-				}
-			}
-			System.err.println(nodeVariables);
+			processAndTopExpr(node);
 		}
 
 		if (nodeCat.equals("unary_linguistic_term")) {
-			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);
+			processUnary_linguistic_term(node);
 		}
 
 		if (nodeCat.equals("n_ary_linguistic_term")) {
@@ -222,7 +179,59 @@
 		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);
+						}
+					}
+				}
+			}
+		}
+		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 = makeGroup("or");
+			requestMap.put("query", topOr);
+			objectStack.push(topOr);
+		}
+	}
 
 	private LinkedHashMap<String, Object> processVariableExpr(ParseTree node) {
 		// simplex word or complex assignment (like qname = textSpec)?
@@ -260,6 +269,7 @@
 
 		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")));
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 9803cf0..c83dff7 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
@@ -106,14 +106,13 @@
 	public void process(String query) throws QueryException {
 		Tree tree = null;
 		tree = parseCosmasQuery(query);
-		log.info("Processing CosmasII query");
+		log.info("Processing CosmasII query: "+query);
 		if (tree != null) {
 			log.debug("ANTLR parse tree: "+tree.toStringTree());
 			processNode(tree);
 		}
 	}
 
-	@SuppressWarnings("unchecked")
 	private void processNode(Tree node) throws QueryException {
 
 		// Top-down processing
@@ -172,384 +171,43 @@
 			}
 		}
 
-		// 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);
-
-			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("key", value);
-			fieldMap.put("layer", attr);
-
-			// 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
-			}
+			processOPWF_OPLEM(node);
 		}
 
 		if (nodeCat.equals("OPMORPH")) {
-			//Step I: get info
-			String[] morphterms = node.getChild(0).toStringTree().replace(" ", "").split("&");
-			LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
-			token.put("@type", "korap:token");
-			ArrayList<Object> terms = new ArrayList<Object>();
-			LinkedHashMap<String, Object> fieldMap = null;
-			for (String morphterm : morphterms) {
-				// regex group #2 is foundry, #4 layer, #5 operator #6 key, #8 value
-				Pattern p = Pattern.compile("((\\w+)/)?((\\w*)(!?=))?(\\w+)(:(\\w+))?");    
-				Matcher m = p.matcher(morphterm);										  
-				if (! m.matches()) {
-					throw new QueryException();
-				}
-				
-				fieldMap = new LinkedHashMap<String, Object>();
-				fieldMap.put("@type", "korap:term");
-				
-				if (m.group(2) != null) fieldMap.put("foundry", m.group(2));
-				if (m.group(4) != null) fieldMap.put("layer", m.group(4));
-				if (m.group(5) != null) {
-					if ("!=".equals(m.group(5))) negate = !negate; 
-				}
-				if (m.group(6) != null) fieldMap.put("key", m.group(6));
-				if (m.group(8) != null) fieldMap.put("value", m.group(8));
-
-				// 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", fieldMap);
-			} 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));
+			processOPMORPH(node);
 		}
 
 		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) {
-					/*
-					 * 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
-					 * term group, but only if there are other attributes in that group. If
-					 * not, put the several values as distinct attr-val-pairs into the
-					 * 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;
-					}
-					// possibly only one term was present throughout all nodes: extract it from the group
-					if (termGroupOperands.size()==1) {
-						termGroup = (LinkedHashMap<String, Object>) termGroupOperands.get(0);
-					}
-					span.put("attr", termGroup);
-				}
-			}
-
-			//Step II: decide where to put
-			putIntoSuperObject(span);
+			processOPELEM(node);
 		}
 
 		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);
+			processOPLABEL(node);
 		}
 
 		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);
+			processOPAND_OPNOT(node);
 		}
 
 		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);
+			processOPOR(node);
 		}
 
 		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");
-
-			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, 128+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));
+			processOPPROX(node);
 		}
 
 		// 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[]{128+classCounter-2,128+classCounter-1};
-			LinkedHashMap<String, Object> classRefCheck = makeClassRefCheck(check, classIn, 128+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, 128+classCounter-1);
-			}
-			putIntoSuperObject(focusGroup, 1);
+			processOPIN_OPOV(node);
 		}
 
 		// 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);
-				}
-			}
-			//        	}
+			processARG1_ARG2(node);
 		}
 
 		if (nodeCat.equals("OPALL")) {
@@ -557,100 +215,15 @@
 		}
 
 		if (nodeCat.equals("OPNHIT")) {
-			Integer[] classRef = new Integer[]{128+classCounter+1, 128+classCounter+2}; 
-			//            classRef.add(classCounter + 1);  // yes, do this twice (two classes)!
-			LinkedHashMap<String, Object> group = makeReference(128+classCounter);
-			LinkedHashMap<String, Object> classRefCheck = makeClassRefOp("classRefOp:inversion", classRef, classCounter+128);
-			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);
+			processOPNHIT(node);
 		}
 
 		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++;
-
-			// Step II: decide where to put
-			putIntoSuperObject(beggroup, 1);
+			processOPEND_OPBEG(node);
 		}
 
 		if (nodeCat.equals("OPBED")) { 
-			// Node structure is (OPBED X+ (OPTS (TPBEG tpos*) (TPEND tpos*)))   
-			// X is some segment, TPBEG or TPEND must be present (inclusive OR)
-			// tpos is a three-char string of the form "[+-]?[spt][ae]". s/p/t indicates span, a/e beginning/end, - means negation
-			// See C-II QL documentation for more detail: 
-			// http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/textpositionen.html
-			
-			// Step I: create group
-			int optsChild = node.getChildCount() - 1;
-			Tree begConditions = getFirstChildWithCat(node.getChild(optsChild), "TPBEG");
-			Tree endConditions = getFirstChildWithCat(node.getChild(optsChild), "TPEND");
-
-			LinkedHashMap<String, Object> submatchgroup = makeReference(128+classCounter);
-			ArrayList<Object> submatchOperands = new ArrayList<Object>();
-			submatchgroup.put("operands", submatchOperands);
-			putIntoSuperObject(submatchgroup);
-
-			// Step II: collect all conditions, create groups for them in processPositionCondition()
-			ArrayList<Object> distributedOperands = new ArrayList<Object>();
-			ArrayList<LinkedHashMap<String, Object>> conditionGroups = new ArrayList<LinkedHashMap<String, Object>>(); 
-			if (begConditions != null) {
-				for (Tree condition : getChildren(begConditions)) {
-					conditionGroups.add(processPositionCondition(condition, distributedOperands, "beg"));
-				}
-			}
-			if (endConditions != null) {
-				for (Tree condition : getChildren(endConditions)) {
-					conditionGroups.add(processPositionCondition(condition, distributedOperands, "end"));
-				}
-			}
-			// Step III: insert conditions. need to stack matches-groups because position groups may only have two operands
-			ArrayList<Object> currentLowestOperands = submatchOperands; // indicates where to insert next condition group
-			int conditionCount = 0;
-			for (LinkedHashMap<String,Object> conditionGroup : conditionGroups) {
-				conditionCount++;
-				if (conditionGroups.size()==1) {
-					submatchOperands.add(conditionGroup);
-				} else if (conditionCount < conditionGroups.size()) {
-					LinkedHashMap<String,Object> matchesGroup = makePosition(new String[]{"frames:matches"}, new String[0]);
-					ArrayList<Object> matchesOperands = (ArrayList<Object>) matchesGroup.get("operands");
-					matchesOperands.add(conditionGroup);
-					// matches groups that are embedded at the second or lower level receive an additional
-					// focus to grep out only the query term to which the constraint applies
-					if (conditionCount > 1) {
-						LinkedHashMap<String,Object> focus = makeReference(128+classCounter-conditionGroups.size()+conditionCount-1);
-						ArrayList<Object> focusOperands = new ArrayList<Object>();
-						focus.put("operands", focusOperands);
-						focusOperands.add(matchesGroup);
-						currentLowestOperands.add(focus);
-					} else {
-						currentLowestOperands.add(matchesGroup);
-					}
-					currentLowestOperands = matchesOperands;
-				} else {
-					currentLowestOperands.add(conditionGroup);
-				}
-			}
+			processOPBED(node);
 		}
 		objectsToPop.push(stackedObjects);
 		toWrapsToPop.push(stackedToWrap);
@@ -704,6 +277,490 @@
 		openNodeCats.pop();
 	}
 
+	private void processOPEND_OPBEG(Tree node) {
+		// Step I: create group
+		String nodeCat = getNodeCat(node);
+		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++;
+
+		// Step II: decide where to put
+		putIntoSuperObject(beggroup, 1);
+	}
+
+	private void processOPBED(Tree node) {
+		// Node structure is (OPBED X+ (OPTS (TPBEG tpos*) (TPEND tpos*)))   
+		// X is some segment, TPBEG or TPEND must be present (inclusive OR)
+		// tpos is a three-char string of the form "[+-]?[spt][ae]". s/p/t indicates span, a/e beginning/end, - means negation
+		// See C-II QL documentation for more detail: 
+		// http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/textpositionen.html
+		
+		// Step I: create group
+		int optsChild = node.getChildCount() - 1;
+		Tree begConditions = getFirstChildWithCat(node.getChild(optsChild), "TPBEG");
+		Tree endConditions = getFirstChildWithCat(node.getChild(optsChild), "TPEND");
+
+		LinkedHashMap<String, Object> submatchgroup = makeReference(128+classCounter);
+		ArrayList<Object> submatchOperands = new ArrayList<Object>();
+		submatchgroup.put("operands", submatchOperands);
+		putIntoSuperObject(submatchgroup);
+
+		// Step II: collect all conditions, create groups for them in processPositionCondition()
+		ArrayList<Object> distributedOperands = new ArrayList<Object>();
+		ArrayList<LinkedHashMap<String, Object>> conditionGroups = new ArrayList<LinkedHashMap<String, Object>>(); 
+		if (begConditions != null) {
+			for (Tree condition : getChildren(begConditions)) {
+				conditionGroups.add(processPositionCondition(condition, distributedOperands, "beg"));
+			}
+		}
+		if (endConditions != null) {
+			for (Tree condition : getChildren(endConditions)) {
+				conditionGroups.add(processPositionCondition(condition, distributedOperands, "end"));
+			}
+		}
+		// Step III: insert conditions. need to stack matches-groups because position groups may only have two operands
+		ArrayList<Object> currentLowestOperands = submatchOperands; // indicates where to insert next condition group
+		int conditionCount = 0;
+		for (LinkedHashMap<String,Object> conditionGroup : conditionGroups) {
+			conditionCount++;
+			if (conditionGroups.size()==1) {
+				submatchOperands.add(conditionGroup);
+			} else if (conditionCount < conditionGroups.size()) {
+				LinkedHashMap<String,Object> matchesGroup = makePosition(new String[]{"frames:matches"}, new String[0]);
+				@SuppressWarnings("unchecked")
+				ArrayList<Object> matchesOperands = (ArrayList<Object>) matchesGroup.get("operands");
+				matchesOperands.add(conditionGroup);
+				// matches groups that are embedded at the second or lower level receive an additional
+				// focus to grep out only the query term to which the constraint applies
+				if (conditionCount > 1) {
+					LinkedHashMap<String,Object> focus = makeReference(128+classCounter-conditionGroups.size()+conditionCount-1);
+					ArrayList<Object> focusOperands = new ArrayList<Object>();
+					focus.put("operands", focusOperands);
+					focusOperands.add(matchesGroup);
+					currentLowestOperands.add(focus);
+				} else {
+					currentLowestOperands.add(matchesGroup);
+				}
+				currentLowestOperands = matchesOperands;
+			} else {
+				currentLowestOperands.add(conditionGroup);
+			}
+		}
+	}
+
+	private void processOPNHIT(Tree node) {
+		Integer[] classRef = new Integer[]{128+classCounter+1, 128+classCounter+2}; 
+		//            classRef.add(classCounter + 1);  // yes, do this twice (two classes)!
+		LinkedHashMap<String, Object> group = makeReference(128+classCounter);
+		LinkedHashMap<String, Object> classRefCheck = makeClassRefOp("classRefOp:inversion", classRef, classCounter+128);
+		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);
+	}
+
+	private void processARG1_ARG2(Tree node) {
+		String nodeCat = getNodeCat(node);
+		Tree parent = node.getParent();
+		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);
+			}
+		}
+	}
+	
+
+	@SuppressWarnings("unchecked")
+	private void processOPIN_OPOV(Tree node) {
+		// Step I: create group
+		String nodeCat = getNodeCat(node);
+		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[]{128+classCounter-2,128+classCounter-1};
+		LinkedHashMap<String, Object> classRefCheck = makeClassRefCheck(check, classIn, 128+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, 128+classCounter-1);
+		}
+		putIntoSuperObject(focusGroup, 1);
+	}
+
+	@SuppressWarnings("unchecked")
+	private void processOPPROX(Tree node) {
+		// 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");
+
+		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, 128+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));
+	}
+
+	private void processOPOR(Tree node) {
+		// 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);
+	}
+
+	private void processOPAND_OPNOT(Tree node) {
+		// Step I: create group
+		String nodeCat = getNodeCat(node);
+		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);
+	}
+
+	private void processOPLABEL(Tree node) {
+		// 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);
+	}
+
+	@SuppressWarnings("unchecked")
+	private void processOPELEM(Tree node) {
+		// 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) {
+				/*
+				 * 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
+				 * term group, but only if there are other attributes in that group. If
+				 * not, put the several values as distinct attr-val-pairs into the
+				 * 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;
+				}
+				// possibly only one term was present throughout all nodes: extract it from the group
+				if (termGroupOperands.size()==1) {
+					termGroup = (LinkedHashMap<String, Object>) termGroupOperands.get(0);
+				}
+				span.put("attr", termGroup);
+			}
+		}
+		//Step II: decide where to put
+		putIntoSuperObject(span);
+	}
+
+	private void processOPMORPH(Tree node) {
+		//Step I: get info
+		String[] morphterms = node.getChild(0).toStringTree().replace(" ", "").split("&");
+		LinkedHashMap<String, Object> token = makeToken();
+		ArrayList<Object> terms = new ArrayList<Object>();
+		LinkedHashMap<String, Object> fieldMap = null;
+		for (String morphterm : morphterms) {
+			// regex group #2 is foundry, #4 layer, #5 operator #6 key, #8 value
+			Pattern p = Pattern.compile("((\\w+)/)?((\\w*)(!?=))?(\\w+)(:(\\w+))?");    
+			Matcher m = p.matcher(morphterm);										  
+			if (! m.matches()) {
+				addError(StatusCodes.UNKNOWN_QUERY_ERROR, "Something went wrong parsing the argument in MORPH().");
+				requestMap.put("query", new LinkedHashMap<String, Object>());
+				return;
+			}
+			
+			fieldMap = new LinkedHashMap<String, Object>();
+			fieldMap.put("@type", "korap:term");
+			
+			if (m.group(2) != null) fieldMap.put("foundry", m.group(2));
+			if (m.group(4) != null) fieldMap.put("layer", m.group(4));
+			if (m.group(5) != null) {
+				if ("!=".equals(m.group(5))) negate = !negate; 
+			}
+			if (m.group(6) != null) fieldMap.put("key", m.group(6));
+			if (m.group(8) != null) fieldMap.put("value", m.group(8));
+
+			// 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", fieldMap);
+		} 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));
+	}
+
+	/**
+	 * Nodes introducing tokens. Process all in the same manner, except for the fieldMap entry
+	 * @param node
+	 */
+	private void processOPWF_OPLEM(Tree node) {
+		String nodeCat = getNodeCat(node);
+		//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("key", value);
+		fieldMap.put("layer", attr);
+
+		// 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
+		}
+	}
+
 	private void processSpanDistance(String meas, int min, int max) {
 		// Do stuff here in case we'll decide one day to treat span distances in a special way.
 		// (see GDoc Special Distances Serialization)
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 ff525a0..1429d9b 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
@@ -60,7 +60,6 @@
 	 * @param node The currently processed node. The process(String query) method calls this method with the root.
 	 * @throws QueryException
 	 */
-	@SuppressWarnings("unchecked")
 	private void processNode(ParseTree node) throws QueryException {
 		// Top-down processing
 		if (visited.contains(node)) return;
@@ -85,330 +84,65 @@
 		 ****************************************************************
 		 ****************************************************************
 		 */
-
+				
 		if (nodeCat.equals("segment")) {
-			// Cover possible quantification (i.e. repetition) of segment
-			ParseTree quantification = getFirstChildWithCat(node, "repetition");
-			if (quantification != null) {
-				LinkedHashMap<String,Object> quantGroup = makeGroup("repetition");
-				Integer[] minmax = parseRepetition(quantification);
-				quantGroup.put("boundary", makeBoundary(minmax[0], minmax[1]));
-				if (minmax[0] != null) quantGroup.put("min", minmax[0]);
-				if (minmax[1] != null) quantGroup.put("max", minmax[1]);
-				addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-07-24: 'min' and 'max' to be " +
-						"supported until 3 months from deprecation date.");
-				putIntoSuperObject(quantGroup);
-				objectStack.push(quantGroup);
-				stackedObjects++;
-			}
+			processSegment(node);
 		}
-
+		
 		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]);
-				sequence.put("inOrder", true);
-				ArrayList<Object> distances = new ArrayList<Object>();
-				distances.add(distance);
-				sequence.put("distances", distances);
-				visited.add(distanceNode.getChild(0)); // don't re-visit the emptyTokenSequence node
-			}
-			putIntoSuperObject(sequence);
-			objectStack.push(sequence);
-			stackedObjects++;
+			processSequence(node);
 		}
 
-		/*
-		 * empty tokens at beginning/end of sequence
-		 */
 		if (nodeCat.equals("emptyTokenSequence")) {
-			Integer[] minmax = parseEmptySegments(node);
-			// object will be either a repetition group or a single empty token
-			LinkedHashMap<String,Object> object; 
-			LinkedHashMap<String,Object> emptyToken = makeToken();
-			if (minmax[0] != 1 || minmax[1] == null || minmax[1] != 1) {
-				object = makeRepetition(minmax[0], minmax[1]);
-				((ArrayList<Object>) object.get("operands")).add(emptyToken);
-			} else {
-				object = emptyToken;
-			}
-			putIntoSuperObject(object);
-			objectStack.push(object);
-			stackedObjects++;
+			processEmptyTokenSequence(node);
 		}
 
 		if (nodeCat.equals("emptyTokenSequenceClass")) {
-			int classId = 1;
-			if (hasChild(node, "spanclass_id")) {
-				classId = Integer.parseInt(node.getChild(1).getChild(0).toStringTree(parser));
-			}
-			LinkedHashMap<String,Object> classGroup = makeSpanClass(classId, false);
-			putIntoSuperObject(classGroup);
-			objectStack.push(classGroup);
-			stackedObjects++;
+			processEmptyTokenSequenceClass(node);
 		}
 
-
 		if (nodeCat.equals("token")) {
-			LinkedHashMap<String,Object> token = makeToken();
-			// handle negation
-			List<ParseTree> negations = getChildrenWithCat(node, "!");
-			boolean negated = false;
-			boolean isRegex = false;
-			if (negations.size() % 2 == 1) negated = true;
-			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;
-					term.put("type", "type:regex");
-					key = key.substring(1,key.length()-1);
-				}
-				term.put("layer", "orth");
-				term.put("key", key);
-				String matches = negated ? "ne" : "eq";
-				term.put("match", "match:"+matches);
-				ParseTree flagNode = getFirstChildWithCat(node, "flag");
-				if (flagNode != null) {
-					// substring removes leading slash '/'
-					String flag = getNodeCat(flagNode.getChild(0)).substring(1);
-					if (flag.contains("i")) term.put("caseInsensitive", true);
-					else if (flag.contains("I")) term.put("caseInsensitive", false);
-					if (flag.contains("x")) {
-						term.put("type", "type:regex");
-						if (!isRegex) {
-							key = QueryUtils.escapeRegexSpecialChars(key); 
-						}
-						term.put("key", ".*?"+key+".*?"); // overwrite key
-					}
-				}
-				token.put("wrap", term);
-			} else {
-				// child is 'term' or 'termGroup' -> process in extra method 
-				LinkedHashMap<String,Object> termOrTermGroup = 
-						parseTermOrTermGroup(node.getChild(1), negated);
-				token.put("wrap", termOrTermGroup);
-			}
-			putIntoSuperObject(token);
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(2));
+			processToken(node);
 		}
 
 		if (nodeCat.equals("alignment")) {
-			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++;
+			processAlignment(node);
 		}
 
 		if (nodeCat.equals("span")) {
-			List<ParseTree> negations = getChildrenWithCat(node, "!");
-			boolean negated = false;
-			if (negations.size() % 2 == 1) negated = true;
-			LinkedHashMap<String,Object> span = makeSpan();
-			ParseTree keyNode = getFirstChildWithCat(node, "key");
-			ParseTree layerNode = getFirstChildWithCat(node, "layer");
-			ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
-			ParseTree termOpNode = getFirstChildWithCat(node, "termOp");
-			ParseTree termNode = getFirstChildWithCat(node, "term");
-			ParseTree termGroupNode = getFirstChildWithCat(node, "termGroup");
-			if (foundryNode != null) span.put("foundry", foundryNode.getText());
-			if (layerNode != null) {
-				String layer = layerNode.getText();
-				if (layer.equals("base")) layer="lemma";
-				span.put("layer", layer);
-			}
-			span.put("key", keyNode.getText());
-			if (termOpNode != null) {
-				String termOp = termOpNode.getText();
-				if (termOp.equals("==")) span.put("match", "match:eq");
-				else if (termOp.equals("!=")) span.put("match", "match:ne");
-			}
-			if (termNode != null) {
-				LinkedHashMap<String,Object> termOrTermGroup = 
-						parseTermOrTermGroup(termNode, negated, "span");
-				span.put("attr", termOrTermGroup);
-			}
-			if (termGroupNode != null) {
-				LinkedHashMap<String,Object> termOrTermGroup = 
-						parseTermOrTermGroup(termGroupNode, negated, "span");
-				span.put("attr", termOrTermGroup);
-			}
-			putIntoSuperObject(span);
-			objectStack.push(span);
-			stackedObjects++;
+			processSpan(node);
 		}
 
 		if (nodeCat.equals("disjunction")) {
-			LinkedHashMap<String,Object> disjunction = makeGroup("or");
-			putIntoSuperObject(disjunction);
-			objectStack.push(disjunction);
-			stackedObjects++;
+			processDisjunction(node);
 		}
 
 		if (nodeCat.equals("position")) {
-			LinkedHashMap<String,Object> position = parseFrame(node.getChild(0));
-			putIntoSuperObject(position);
-			objectStack.push(position);
-			stackedObjects++;
+			processPosition(node);
 		}
 
 		if (nodeCat.equals("relation")) {
-			LinkedHashMap<String, Object> relationGroup = makeGroup("relation");
-			LinkedHashMap<String, Object> relation = makeRelation();
-			relationGroup.put("relation", relation);
-			if (node.getChild(0).getText().equals("dominates")) {
-				relation.put("layer", "c");
-			}
-			ParseTree relSpec = getFirstChildWithCat(node, "relSpec");
-			ParseTree repetition = getFirstChildWithCat(node, "repetition");
-			if (relSpec != null) {
-				ParseTree foundry = getFirstChildWithCat(relSpec, "foundry");
-				ParseTree layer = getFirstChildWithCat(relSpec, "layer");
-				ParseTree key = getFirstChildWithCat(relSpec, "key");
-				if (foundry != null) relation.put("foundry", foundry.getText());
-				if (layer != null) relation.put("layer", layer.getText());
-				if (key != null) relation.put("key", key.getText());
-			}
-			if (repetition != null) {
-				Integer[] minmax =  parseRepetition(repetition);
-				relation.put("boundary", makeBoundary(minmax[0], minmax[1]));
-			}
-			putIntoSuperObject(relationGroup);
-			objectStack.push(relationGroup);
-			stackedObjects++;
+			processRelation(node);
 		}
 
 		if (nodeCat.equals("spanclass")) {
-			// Step I: get info
-			int classId = 1;
-			if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
-				String ref = node.getChild(1).getChild(0).toStringTree(parser);
-				try {
-					classId = Integer.parseInt(ref);
-				} catch (NumberFormatException e) {
-					String msg = "The specified class reference in the " +
-							"focus/split-Operator is not a number: " + ref;
-					log.error(msg);
-					throw new QueryException(msg);
-				}
-				// only allow class id up to 127
-				if (classId > 127) {
-					addWarning("Only class IDs up to 127 are allowed. Your class "+classId+" has been set back to 127. "
-							+ "Check for possible conflict with other classes.");
-					classId = 127;
-				}
-			}
-			LinkedHashMap<String, Object> classGroup = makeSpanClass(classId, false);
-			putIntoSuperObject(classGroup);
-			objectStack.push(classGroup);
-			stackedObjects++;
+			processSpanclass(node);
 		}
 
 		if (nodeCat.equals("matching")) {
-			// Step I: get info
-			ArrayList<Integer> classRefs = new ArrayList<Integer>();
-			String classRefOp = null;
-			if (getNodeCat(node.getChild(2)).equals("spanclass_id")) {
-				ParseTree spanNode = node.getChild(2);
-				for (int i = 0; i < spanNode.getChildCount() - 1; i++) {
-					String ref = spanNode.getChild(i).getText();
-					if (ref.equals("|") || ref.equals("&")) {
-						classRefOp = ref.equals("|") ? "intersection" : "union";
-					} else {
-						try {
-							int classRef = Integer.parseInt(ref);
-							// only allow class id up to 127
-							if (classRef > 127) {
-								addWarning("Only class references up to 127 are allowed. Your reference to class "+classRef+" has been set back to 127. "
-										+ "Check for possible conflict with other classes.");
-								classRef = 127;
-							}
-							classRefs.add(classRef);
-						} catch (NumberFormatException e) {
-							String err = "The specified class reference in the " +
-									"shrink/split-Operator is not a number.";
-							addError(StatusCodes.UNDEFINED_CLASS_REFERENCE, err);
-						}
-					}
-				}
-			} else {
-				classRefs.add(1);
-			}
-			LinkedHashMap<String, Object> referenceGroup = makeReference(classRefs);
-
-			String type = node.getChild(0).toStringTree(parser);
-			// Default is focus(), if deviating catch here
-			if (type.equals("split")) referenceGroup.put("operation", "operation:split");
-			if (type.equals("submatch") || type.equals("shrink")) {
-				String warning = "Deprecated 2014-07-24: "+type + "() as a match reducer " +
-						"to a specific class is deprecated in favor of focus() and will " +
-						"only be supported for 3 months after deprecation date.";
-				addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, warning);
-			}
-			if (classRefOp != null) {
-				referenceGroup.put("classRefOp", "classRefOp:" + classRefOp);
-			}
-			ArrayList<Object> referenceOperands = new ArrayList<Object>();
-			referenceGroup.put("operands", referenceOperands);
-			// Step II: decide where to put the group
-			putIntoSuperObject(referenceGroup);
-			objectStack.push(referenceGroup);
-			stackedObjects++;
-			visited.add(node.getChild(0));
+			processMatching(node);
 		}
 
 		if (nodeCat.equals("submatch")) {
-			LinkedHashMap<String,Object> submatch = makeReference(null);
-			submatch.put("operands", new ArrayList<Object>());
-			ParseTree startpos = getFirstChildWithCat(node,"startpos");
-			ParseTree length = getFirstChildWithCat(node,"length");
-			ArrayList<Integer> spanRef = new ArrayList<Integer>();
-			spanRef.add(Integer.parseInt(startpos.getText()));
-			if (length != null) {
-				spanRef.add(Integer.parseInt(length.getText()));
-			}
-			submatch.put("spanRef", spanRef);
-			putIntoSuperObject(submatch);
-			objectStack.push(submatch);
-			stackedObjects++;
-			visited.add(node.getChild(0));
+			processSubmatch(node);
 		}
 
 		if (nodeCat.equals("meta")) {
-			LinkedHashMap<String, Object> metaFilter = new LinkedHashMap<String, Object>();
-			requestMap.put("meta", metaFilter);
-			metaFilter.put("@type", "korap:meta");
+			processMeta(node);
 		}
 
 		if (nodeCat.equals("within") && !getNodeCat(node.getParent()).equals("position")) {
-			ParseTree domainNode = node.getChild(2);
-			String domain = getNodeCat(domainNode);
-			LinkedHashMap<String, Object> curObject = 
-					(LinkedHashMap<String, Object>) objectStack.getFirst();
-			curObject.put("within", domain);
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(1));
-			visited.add(domainNode);
+			processWithin(node);
 		}
 
 		objectsToPop.push(stackedObjects);
@@ -433,6 +167,343 @@
 		openNodeCats.pop();
 	}
 
+	private void processSegment(ParseTree node) {
+		// Cover possible quantification (i.e. repetition) of segment
+		ParseTree quantification = getFirstChildWithCat(node, "repetition");
+		if (quantification != null) {
+			LinkedHashMap<String,Object> quantGroup = makeGroup("repetition");
+			Integer[] minmax = parseRepetition(quantification);
+			quantGroup.put("boundary", makeBoundary(minmax[0], minmax[1]));
+			if (minmax[0] != null) quantGroup.put("min", minmax[0]);
+			if (minmax[1] != null) quantGroup.put("max", minmax[1]);
+			addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, "Deprecated 2014-07-24: 'min' and 'max' to be " +
+					"supported until 3 months from deprecation date.");
+			putIntoSuperObject(quantGroup);
+			objectStack.push(quantGroup);
+			stackedObjects++;
+		}
+	}
+
+	private void processSequence(ParseTree node) {
+		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]);
+			sequence.put("inOrder", true);
+			ArrayList<Object> distances = new ArrayList<Object>();
+			distances.add(distance);
+			sequence.put("distances", distances);
+			visited.add(distanceNode.getChild(0)); // don't re-visit the emptyTokenSequence node
+		}
+		putIntoSuperObject(sequence);
+		objectStack.push(sequence);
+		stackedObjects++;
+	}
+
+	@SuppressWarnings("unchecked")
+	/**
+	 * empty tokens at beginning/end of sequence
+	 * @param node
+	 */
+	private void processEmptyTokenSequence(ParseTree node) {
+		Integer[] minmax = parseEmptySegments(node);
+		// object will be either a repetition group or a single empty token
+		LinkedHashMap<String,Object> object; 
+		LinkedHashMap<String,Object> emptyToken = makeToken();
+		if (minmax[0] != 1 || minmax[1] == null || minmax[1] != 1) {
+			object = makeRepetition(minmax[0], minmax[1]);
+			((ArrayList<Object>) object.get("operands")).add(emptyToken);
+		} else {
+			object = emptyToken;
+		}
+		putIntoSuperObject(object);
+		objectStack.push(object);
+		stackedObjects++;
+	}
+
+	private void processEmptyTokenSequenceClass(ParseTree node) {
+		int classId = 1;
+		if (hasChild(node, "spanclass_id")) {
+			classId = Integer.parseInt(node.getChild(1).getChild(0).toStringTree(parser));
+		}
+		LinkedHashMap<String,Object> classGroup = makeSpanClass(classId, false);
+		putIntoSuperObject(classGroup);
+		objectStack.push(classGroup);
+		stackedObjects++;
+	}
+
+	private void processToken(ParseTree node) {
+		LinkedHashMap<String,Object> token = makeToken();
+		// handle negation
+		List<ParseTree> negations = getChildrenWithCat(node, "!");
+		boolean negated = false;
+		boolean isRegex = false;
+		if (negations.size() % 2 == 1) negated = true;
+		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;
+				term.put("type", "type:regex");
+				key = key.substring(1,key.length()-1);
+			}
+			term.put("layer", "orth");
+			term.put("key", key);
+			String matches = negated ? "ne" : "eq";
+			term.put("match", "match:"+matches);
+			ParseTree flagNode = getFirstChildWithCat(node, "flag");
+			if (flagNode != null) {
+				// substring removes leading slash '/'
+				String flag = getNodeCat(flagNode.getChild(0)).substring(1);
+				if (flag.contains("i")) term.put("caseInsensitive", true);
+				else if (flag.contains("I")) term.put("caseInsensitive", false);
+				if (flag.contains("x")) {
+					term.put("type", "type:regex");
+					if (!isRegex) {
+						key = QueryUtils.escapeRegexSpecialChars(key); 
+					}
+					term.put("key", ".*?"+key+".*?"); // overwrite key
+				}
+			}
+			token.put("wrap", term);
+		} else {
+			// child is 'term' or 'termGroup' -> process in extra method 
+			LinkedHashMap<String,Object> termOrTermGroup = 
+					parseTermOrTermGroup(node.getChild(1), negated);
+			token.put("wrap", termOrTermGroup);
+		}
+		putIntoSuperObject(token);
+		visited.add(node.getChild(0));
+		visited.add(node.getChild(2));
+	}
+	
+
+	@SuppressWarnings("unchecked")
+	private void processAlignment(ParseTree node) {
+		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++;
+	}
+
+	private void processSpan(ParseTree node) {
+		List<ParseTree> negations = getChildrenWithCat(node, "!");
+		boolean negated = false;
+		if (negations.size() % 2 == 1) negated = true;
+		LinkedHashMap<String,Object> span = makeSpan();
+		ParseTree keyNode = getFirstChildWithCat(node, "key");
+		ParseTree layerNode = getFirstChildWithCat(node, "layer");
+		ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
+		ParseTree termOpNode = getFirstChildWithCat(node, "termOp");
+		ParseTree termNode = getFirstChildWithCat(node, "term");
+		ParseTree termGroupNode = getFirstChildWithCat(node, "termGroup");
+		if (foundryNode != null) span.put("foundry", foundryNode.getText());
+		if (layerNode != null) {
+			String layer = layerNode.getText();
+			if (layer.equals("base")) layer="lemma";
+			span.put("layer", layer);
+		}
+		span.put("key", keyNode.getText());
+		if (termOpNode != null) {
+			String termOp = termOpNode.getText();
+			if (termOp.equals("==")) span.put("match", "match:eq");
+			else if (termOp.equals("!=")) span.put("match", "match:ne");
+		}
+		if (termNode != null) {
+			LinkedHashMap<String,Object> termOrTermGroup = 
+					parseTermOrTermGroup(termNode, negated, "span");
+			span.put("attr", termOrTermGroup);
+		}
+		if (termGroupNode != null) {
+			LinkedHashMap<String,Object> termOrTermGroup = 
+					parseTermOrTermGroup(termGroupNode, negated, "span");
+			span.put("attr", termOrTermGroup);
+		}
+		putIntoSuperObject(span);
+		objectStack.push(span);
+		stackedObjects++;
+	}
+
+	private void processDisjunction(ParseTree node) {
+		LinkedHashMap<String,Object> disjunction = makeGroup("or");
+		putIntoSuperObject(disjunction);
+		objectStack.push(disjunction);
+		stackedObjects++;
+	}
+
+	private void processPosition(ParseTree node) {
+		LinkedHashMap<String,Object> position = parseFrame(node.getChild(0));
+		putIntoSuperObject(position);
+		objectStack.push(position);
+		stackedObjects++;
+	}
+
+	private void processRelation(ParseTree node) {
+		LinkedHashMap<String, Object> relationGroup = makeGroup("relation");
+		LinkedHashMap<String, Object> relation = makeRelation();
+		relationGroup.put("relation", relation);
+		if (node.getChild(0).getText().equals("dominates")) {
+			relation.put("layer", "c");
+		}
+		ParseTree relSpec = getFirstChildWithCat(node, "relSpec");
+		ParseTree repetition = getFirstChildWithCat(node, "repetition");
+		if (relSpec != null) {
+			ParseTree foundry = getFirstChildWithCat(relSpec, "foundry");
+			ParseTree layer = getFirstChildWithCat(relSpec, "layer");
+			ParseTree key = getFirstChildWithCat(relSpec, "key");
+			if (foundry != null) relation.put("foundry", foundry.getText());
+			if (layer != null) relation.put("layer", layer.getText());
+			if (key != null) relation.put("key", key.getText());
+		}
+		if (repetition != null) {
+			Integer[] minmax =  parseRepetition(repetition);
+			relation.put("boundary", makeBoundary(minmax[0], minmax[1]));
+		}
+		putIntoSuperObject(relationGroup);
+		objectStack.push(relationGroup);
+		stackedObjects++;
+	}
+
+	private void processSpanclass(ParseTree node) {
+		// Step I: get info
+		int classId = 1;
+		if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
+			String ref = node.getChild(1).getChild(0).toStringTree(parser);
+			try {
+				classId = Integer.parseInt(ref);
+			} catch (NumberFormatException e) {
+				String msg = "The specified class reference in the " +
+						"focus/split-Operator is not a number: " + ref;
+				log.error(msg);
+				addError(StatusCodes.UNDEFINED_CLASS_REFERENCE, msg);
+			}
+			// only allow class id up to 127
+			if (classId > 127) {
+				addWarning("Only class IDs up to 127 are allowed. Your class "+classId+" has been set back to 127. "
+						+ "Check for possible conflict with other classes.");
+				classId = 127;
+			}
+		}
+		LinkedHashMap<String, Object> classGroup = makeSpanClass(classId, false);
+		putIntoSuperObject(classGroup);
+		objectStack.push(classGroup);
+		stackedObjects++;
+		
+	}
+
+	private void processMatching(ParseTree node) {
+		// Step I: get info
+		ArrayList<Integer> classRefs = new ArrayList<Integer>();
+		String classRefOp = null;
+		if (getNodeCat(node.getChild(2)).equals("spanclass_id")) {
+			ParseTree spanNode = node.getChild(2);
+			for (int i = 0; i < spanNode.getChildCount() - 1; i++) {
+				String ref = spanNode.getChild(i).getText();
+				if (ref.equals("|") || ref.equals("&")) {
+					classRefOp = ref.equals("|") ? "intersection" : "union";
+				} else {
+					try {
+						int classRef = Integer.parseInt(ref);
+						// only allow class id up to 127
+						if (classRef > 127) {
+							addWarning("Only class references up to 127 are allowed. Your reference to class "+classRef+" has been set back to 127. "
+									+ "Check for possible conflict with other classes.");
+							classRef = 127;
+						}
+						classRefs.add(classRef);
+					} catch (NumberFormatException e) {
+						String err = "The specified class reference in the " +
+								"shrink/split-Operator is not a number.";
+						addError(StatusCodes.UNDEFINED_CLASS_REFERENCE, err);
+					}
+				}
+			}
+		} else {
+			classRefs.add(1);
+		}
+		LinkedHashMap<String, Object> referenceGroup = makeReference(classRefs);
+
+		String type = node.getChild(0).toStringTree(parser);
+		// Default is focus(), if deviating catch here
+		if (type.equals("split")) referenceGroup.put("operation", "operation:split");
+		if (type.equals("submatch") || type.equals("shrink")) {
+			String warning = "Deprecated 2014-07-24: "+type + "() as a match reducer " +
+					"to a specific class is deprecated in favor of focus() and will " +
+					"only be supported for 3 months after deprecation date.";
+			addMessage(StatusCodes.DEPRECATED_QUERY_ELEMENT, warning);
+		}
+		if (classRefOp != null) {
+			referenceGroup.put("classRefOp", "classRefOp:" + classRefOp);
+		}
+		ArrayList<Object> referenceOperands = new ArrayList<Object>();
+		referenceGroup.put("operands", referenceOperands);
+		// Step II: decide where to put the group
+		putIntoSuperObject(referenceGroup);
+		objectStack.push(referenceGroup);
+		stackedObjects++;
+		visited.add(node.getChild(0));
+	}
+
+	private void processSubmatch(ParseTree node) {
+		LinkedHashMap<String,Object> submatch = makeReference(null);
+		submatch.put("operands", new ArrayList<Object>());
+		ParseTree startpos = getFirstChildWithCat(node,"startpos");
+		ParseTree length = getFirstChildWithCat(node,"length");
+		ArrayList<Integer> spanRef = new ArrayList<Integer>();
+		spanRef.add(Integer.parseInt(startpos.getText()));
+		if (length != null) {
+			spanRef.add(Integer.parseInt(length.getText()));
+		}
+		submatch.put("spanRef", spanRef);
+		putIntoSuperObject(submatch);
+		objectStack.push(submatch);
+		stackedObjects++;
+		visited.add(node.getChild(0));
+	}
+
+	/**
+	 * Creates meta field in requestMap, later filled by terms
+	 * @param node
+	 */
+	private void processMeta(ParseTree node) {
+		LinkedHashMap<String, Object> metaFilter = new LinkedHashMap<String, Object>();
+		requestMap.put("meta", metaFilter);
+		metaFilter.put("@type", "korap:meta");
+	}
+
+	/**
+	 * NB: requires that parent is not 'position'!
+	 * @param node
+	 */
+	private void processWithin(ParseTree node) {
+		ParseTree domainNode = node.getChild(2);
+		String domain = getNodeCat(domainNode);
+		LinkedHashMap<String, Object> curObject = 
+				(LinkedHashMap<String, Object>) objectStack.getFirst();
+		curObject.put("within", domain);
+		visited.add(node.getChild(0));
+		visited.add(node.getChild(1));
+		visited.add(domainNode);
+	}
+
 	/**
 	 * Parses a repetition node
 	 * @param node
@@ -521,7 +592,8 @@
 	 */
 	@SuppressWarnings("unchecked")
 	private LinkedHashMap<String, Object> parseTermOrTermGroup(ParseTree node, boolean negatedGlobal, String mode) {
-		if (getNodeCat(node).equals("term")) {
+		String nodeCat = getNodeCat(node);
+		if (nodeCat.equals("term")) {
 			String key = null;
 			LinkedHashMap<String,Object> term = makeTerm();
 			// handle negation
@@ -577,7 +649,7 @@
 				}
 			}
 			return term;
-		} else {
+		} else if (nodeCat.equals("termGroup")) {
 			// For termGroups, establish a boolean relation between operands and recursively call this function with
 			// the term or termGroup operands
 			LinkedHashMap<String,Object> termGroup = null;
@@ -598,6 +670,7 @@
 			operands.add(parseTermOrTermGroup(rightOp, negatedGlobal, mode));
 			return termGroup;
 		}
+		return null;
 	}
 
 	/**
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 6bcf7e9..6fe6afd 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,4 +7,5 @@
 	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 final static int UNKNOWN_QUERY_ERROR = 399;
 }
