Javadoc, code cleanup
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java
index 501c190..0240a15 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractQueryProcessor.java
@@ -10,31 +10,46 @@
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.slf4j.Logger;
 
+/**
+ * This is an abstract class which provides fields and methods for concrete
+ * query processor implementations. All of those must implement 
+ * {@link #process(String)}, which is expected to process the query
+ * and store a {@link #java.util.Map} representation of the KoralQuery
+ * JSON-LD tree for that query. 
+ * 
+ * @author Joachim Bingel (bingel@ids-mannheim.de)
+ * @version 0.1.0
+ * @since 0.1.0
+ */
 public abstract class AbstractQueryProcessor {
 
     Logger log;
     /**
-     *  The query
+     *  The query string.
      */
     String query;
     /**
      * Top-level map representing the whole request.
      */
-    LinkedHashMap<String, Object> requestMap = new LinkedHashMap<String, Object>();
+    LinkedHashMap<String, Object> requestMap = 
+            new LinkedHashMap<String, Object>();
     /**
-     * Keeps track of open node categories
+     * Keeps track of open node categories.
      */
     LinkedList<String> openNodeCats = new LinkedList<String>();
     /**
-     * Keeps track of all visited nodes in a tree
+     * Keeps track of all visited nodes in a tree.
      */
     List<ParseTree> visited = new ArrayList<ParseTree>();
     /**
-     * Keeps track of active object.
+     * Keeps track of active object, used for inserting new KoralQuery objects
+     * into last created objects.
      */
-    LinkedList<LinkedHashMap<String, Object>> objectStack = new LinkedList<LinkedHashMap<String, Object>>();
+    LinkedList<LinkedHashMap<String, Object>> objectStack = 
+            new LinkedList<LinkedHashMap<String, Object>>();
     /**
-     * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
+     * Keeps track of how many objects there are to pop after every recursion
+     * of {@link #processNode(ParseTree)}
      */
     LinkedList<Integer> objectsToPop = new LinkedList<Integer>();
     /**
@@ -42,15 +57,37 @@
      */
     public static boolean verbose = false;
     protected Integer stackedObjects = 0;
+    /**
+     * Contains error arrays, consisting of an error code and a message.
+     */
     private ArrayList<List<Object>> errors = new ArrayList<List<Object>>();
+    /**
+     * Contains warning arrays, consisting of a warning code (optional) and a
+     * message.
+     */
     private ArrayList<List<Object>> warnings = new ArrayList<List<Object>>();
+    /**
+     * Contains other messages.
+     */
     private ArrayList<List<Object>> messages = new ArrayList<List<Object>>();
-    private LinkedHashMap<String, Object> collection = new LinkedHashMap<String,Object>();
-    private LinkedHashMap<String, Object> meta = new LinkedHashMap<String,Object>();
+    /**
+     * Virtual collection queries.
+     */
+    private LinkedHashMap<String, Object> collection = 
+            new LinkedHashMap<String,Object>();
+    /**
+     * Holds information on displaying directives.
+     */
+    private LinkedHashMap<String, Object> meta = 
+            new LinkedHashMap<String,Object>();
+    /**
+     * Indicates which classes are to be highlighted in KWIC view.
+     */
     private ArrayList<Integer> highlightClasses = new ArrayList<Integer>();
 
     AbstractQueryProcessor() {
-        requestMap.put("@context", "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld");
+        requestMap.put("@context", "http://ids-mannheim.de/ns/KorAP/json-ld/"
+                + "v0.2/context.jsonld");
         requestMap.put("errors", errors);
         requestMap.put("warnings", warnings);
         requestMap.put("messages", messages);
@@ -59,42 +96,85 @@
         requestMap.put("meta", meta);
     }
 
+    /**
+     * Called to process the query, is expected to generate a Map-based 
+     * KoralQuery representation in {@link #requestMap}. 
+     * @param query The query string.
+     */
     public abstract void process(String query);
 
+    /**
+     * Adds a warning to {@link #warnings}.
+     * @param code The warning code.
+     * @param msg The warning message.
+     */
     public void addWarning(int code, String msg) {
         List<Object> warning = Arrays.asList(new Object[]{code, msg}); 
         warnings.add(warning);
     }
 
+    /**
+     * Adds a warning to {@link #warnings}.
+     * @param msg The warning message.
+     */
     public void addWarning(String msg) {
         List<Object> warning = Arrays.asList(new Object[]{msg}); 
         warnings.add(warning);
     }
 
+    /**
+     * Adds a generic message to {@link #messages}.
+     * @param code The message code.
+     * @param msg The message string.
+     */
     public void addMessage(int code, String msg) {
         List<Object> message = Arrays.asList(new Object[]{code, msg}); 
         messages.add(message);
     }
 
+    /**
+     * Adds a generic message to {@link #messages}.
+     * @param msg The message string.
+     */
     public void addMessage(String msg) {
         List<Object> message = Arrays.asList(new Object[]{msg}); 
         messages.add(message);
     }
 
+    /**
+     * Adds an error to {@link #errors}.
+     * @param code The error code.
+     * @param msg The error message.
+     */
     public void addError(int code, String msg) {
         List<Object> error = Arrays.asList(new Object[]{code, msg}); 
         errors.add(error);
     }
 
+    /**
+     * Adds an error to {@link #errors}.
+     * @param fullErrorMsg First object is expected to be an integer
+     * error code, second a message.
+     */
     public void addError(List<Object> fullErrorMsg) {
         errors.add(fullErrorMsg);
     }
 
+    /**
+     * Add a class to the list of classes highlighted in KWIC view.
+     * @param classId The class ID.
+     */
     public void addHighlightClass(int classId) {
         highlightClasses.add(classId);
         meta.put("highlight", highlightClasses);
     }
 
+    /**
+     * Getter method for the {@link #requestMap}, which represents the
+     * entire KoralQuery request (query, displaying directives, virtual 
+     * collections, messages etc.) based on a Java Map.
+     * @return
+     */
     public Map<String, Object> getRequestMap() {
         return requestMap;
     }
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 6f95189..298d45d 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
@@ -27,26 +27,39 @@
 import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
 
 /**
- * Map representation of ANNIS QL syntax tree as returned by ANTLR
+ * Processor class for ANNIS QL queries. This class uses an ANTLR v4 grammar
+ * for query parsing, it therefore extends {@link Antlr4AbstractQueryProcessor}.
+ * The parser object is inherited from the parent class and instantiated in
+ * {@link #parseAnnisQuery(String)} as an {@link AqlParser}.
+ * 
+ * @see http://annis-tools.org/aql.html
+ * 
  * @author Joachim Bingel (bingel@ids-mannheim.de)
- *
+ * @version 0.1.0
+ * @since 0.1.0
  */
 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
+     * 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.
+     * Keeps track of operands that are to be integrated into yet uncreated 
+     * objects.
      */
-    LinkedList<LinkedHashMap<String,Object>> operandStack = new LinkedList<LinkedHashMap<String,Object>>();
+    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)
+     * 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>>();
+    Map<String, LinkedHashMap<String,Object>> nodeVariables = 
+            new LinkedHashMap<String, LinkedHashMap<String,Object>>();
     /**
-     * Keeps track of explicitly (by #-var definition) or implicitly (number as reference) introduced entities (for later reference by #-operator)
+     * Keeps track of explicitly (by #-var definition) or implicitly (number 
+     * as reference) introduced entities (for later reference by #-operator)
      */
     Map<ParseTree, String> nodes2refs= new LinkedHashMap<ParseTree, String>(); 
     /**
@@ -54,58 +67,76 @@
      */
     Integer variableCount = 1;
     /**
-     * Marks the currently active token in order to know where to add flags (might already have been taken away from token stack).
+     * 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>>();
+    private LinkedList<ArrayList<Object>> invertedOperandsLists = 
+            new LinkedList<ArrayList<Object>>();
     /**
      * Keeps track of operation:class numbers.
      */
     int classCounter = 1;
     /**
-     * Keeps track of numers of relations processed (important when dealing with multiple predications).
+     * 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.   
+     * 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 int totalRelationCount = 0;
     /**
-     * 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.
+     * 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>();
+    private LinkedHashMap<String, Integer> refClassMapping = 
+            new LinkedHashMap<String, Integer>();
     /**
      * Keeps a record of unary relations on spans/tokens.
      */
-    private LinkedHashMap<String, ArrayList<ParseTree>> unaryRelations = new LinkedHashMap<String, ArrayList<ParseTree>>();
+    private LinkedHashMap<String, ArrayList<ParseTree>> unaryRelations = 
+            new LinkedHashMap<String, ArrayList<ParseTree>>();
     /**
-     * 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.
+     * 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>();
+    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.
+     * 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 LinkedHashMap<String, Integer> nodeReferencesProcessed = 
+            new LinkedHashMap<String, Integer>();
     /**
-     * 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.
+     * 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>();
     /**
-     * For some objects, it may be decided in the initial scan (processAndTopExpr()) that they
-     * need to be wrapped in a class operation when retrieved later. This map stores this information.
-     * More precisely, it stores for every node in the tree which class ID its derived Koral
-     * object will receive.
+     * For some objects, it may be decided in the initial scan 
+     * ({@link #processAndTopExpr(ParseTree)} that they need to be wrapped in a
+     * class operation when retrieved later. This map stores this information.
+     * More precisely, it stores for every node in the tree which class ID its 
+     * derived KoralQuery object will receive.
      */
-    private LinkedHashMap<ParseTree, Integer> objectsToWrapInClass = new LinkedHashMap<ParseTree, Integer>();
+    private LinkedHashMap<ParseTree, Integer> objectsToWrapInClass = 
+            new LinkedHashMap<ParseTree, Integer>();
 
     public AnnisQueryProcessor(String query) {
         KoralObjectGenerator.setQueryProcessor(this);
@@ -127,26 +158,35 @@
             // Last check to see if all relations have left the queue
             if (!queuedRelations.isEmpty()) {
                 ParseTree queued = queuedRelations.pop();
-                if (verbose) System.out.println("Taking off queue (last rel): "+ queued.getText());
+                if (verbose) System.out.println("Taking off queue (last rel): "
+                        + queued.getText());
                 if (checkOperandsProcessedPreviously(queued)) {
                     processNode(queued);
                 } else {
-                    addError(StatusCodes.UNBOUND_ANNIS_RELATION, "The relation "+queued.getText()
-                            +" is not bound to any other relations.");
-                    requestMap.put("query", new LinkedHashMap<String, Object>());
+                    addError(StatusCodes.UNBOUND_ANNIS_RELATION, 
+                            "The relation " +queued.getText()+ 
+                            " is not bound to any other relations.");
+                    requestMap.put("query", 
+                            new LinkedHashMap<String, Object>());
                 }
             }
         }
     }
 
+    /**
+     * Traverses the parse tree by recursively calling itself, starting with
+     * the root node of the tree and calling itself with the children of its
+     * current node in a depth-first, left-to-right fashion. In each call,
+     * depending on the category of the current node, special processor
+     * methods for the respective node category are called to process the node.
+     * @param node The node currently visited in the parse tree traversal.
+     */
     private void processNode(ParseTree node) {
         String nodeCat = getNodeCat(node);
-
         // Top-down processing
         if (visited.contains(node)) return;
         openNodeCats.push(nodeCat);
         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")) {
@@ -160,7 +200,6 @@
                 }
             }  
         }
-
         if (verbose) {
             System.err.println(" "+objectStack);
             System.out.println(openNodeCats);
@@ -181,17 +220,9 @@
             processAndTopExpr(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("variableExpr")) {
-//            processVariableExpr(node);
-//        }
 
         objectsToPop.push(stackedObjects);
 
@@ -220,29 +251,42 @@
         openNodeCats.pop();
     }
 
-
-
+    /**
+     * Processes an <tt>andTopExpr</tt> node. This is a child of the root
+     * and contains a set of expressions connected by logical conjunction.
+     * Several of these nodes are possibly connected via disjunction.
+     * @param node The current parse tree node (must be of category 
+     * <tt>andTopExpr</tt>). 
+     */
     private void processAndTopExpr(ParseTree node) {
-        // Before processing any child expr node, check if it has one or more "*ary_linguistic_term" nodes.
+        // 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 unaryTermNode : getDescendantsWithCat(node, "unary_linguistic_term")) {
+        // 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 unaryTermNode : 
+                getDescendantsWithCat(node, "unary_linguistic_term")) {
             String ref = getNodeCat(unaryTermNode.getChild(0)).substring(1);
             ArrayList<ParseTree> unaryTermsForRef = unaryRelations.get(ref);
-            if (unaryTermsForRef == null) unaryTermsForRef = new ArrayList<ParseTree>();
+            if (unaryTermsForRef == null) unaryTermsForRef = 
+                    new ArrayList<ParseTree>();
             unaryTermsForRef.add(unaryTermNode);
             unaryRelations.put(ref, unaryTermsForRef);
         }
-        for (ParseTree lingTermNode : getDescendantsWithCat(node, "n_ary_linguistic_term")) {
-            for (ParseTree refOrNode : getChildrenWithCat(lingTermNode, "refOrNode")) {
-                String refOrNodeString = refOrNode.getChild(0).toStringTree(parser);
+        for (ParseTree lingTermNode : 
+                getDescendantsWithCat(node, "n_ary_linguistic_term")) {
+            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);
+                    String ref = refOrNode.getChild(0).toStringTree(parser).
+                            substring(1);
                     if (nodeReferencesTotal.containsKey(ref)) {
-                        nodeReferencesTotal.put(ref, nodeReferencesTotal.get(ref)+1);
+                        nodeReferencesTotal.put(ref, 
+                                nodeReferencesTotal.get(ref)+1);
                     } else {
                         nodeReferencesTotal.put(ref, 1);
                         nodeReferencesProcessed.put(ref, 0);   
@@ -252,54 +296,54 @@
             totalRelationCount++;
         }
         // Then, mine all object definitions. 
-        for (ParseTree variableExprNode : getDescendantsWithCat(node, "variableExpr")) {
+        for (ParseTree variableExprNode : 
+                getDescendantsWithCat(node, "variableExpr")) {
             String ref;
             // might be a ref label rather than a counting number
-            ParseTree varDef = getFirstChildWithCat(variableExprNode.getParent(), "varDef");
+            ParseTree varDef = 
+                    getFirstChildWithCat(variableExprNode.getParent(),"varDef");
             if (varDef != null) {
-                ref = varDef.getText().replaceFirst("#", ""); // remove trailing #
+                // remove trailing #
+                ref = varDef.getText().replaceFirst("#", ""); 
             } else {
                 ref = variableCount.toString();
             }
             nodes2refs.put(variableExprNode, ref);
-            LinkedHashMap<String,Object> object = processVariableExpr(variableExprNode);
+            LinkedHashMap<String,Object> object = 
+                    processVariableExpr(variableExprNode);
             nodeVariables.put(ref, object);            
             variableCount++;
-            // Check if this object definition is part of a "direct declaration relation", 
-            // i.e. a relation which declares its operands directly rather than using
-            // references to earlier declared objects. These objects must still be
-            // available for later reference, handle this here. 
-            // Direct declaration relation is present when grandparent is n_ary_linguistic_term node.
-            if (getNodeCat(variableExprNode.getParent().getParent()).equals("n_ary_linguistic_term")) {
+            // Check if this object definition is part of a "direct declaration
+            // relation", i.e. a relation which declares its operands directly
+            // rather than using references to earlier declared objects. These 
+            // objects must still be available for later reference, handle this 
+            // here. Direct declaration relation is present when grandparent is
+            // n_ary_linguistic_term node.
+            if (getNodeCat(variableExprNode.getParent().getParent()).
+                    equals("n_ary_linguistic_term")) {
                 if (nodeReferencesTotal.containsKey(ref)) {
-                    nodeReferencesTotal.put(ref, nodeReferencesTotal.get(ref)+1);
+                    nodeReferencesTotal.put(ref,nodeReferencesTotal.get(ref)+1);
                 } else {
                     nodeReferencesTotal.put(ref, 1);
                 }
-                // This is important for later relations wrapping the present relation.
-                // If the object isn't registered as processed, it won't be available
-                // for referencing.
+                // This is important for later relations wrapping the present 
+                // relation. If the object isn't registered as processed, it 
+                // won't be available  for referencing.
                 nodeReferencesProcessed.put(ref, 1);  
                 // Register this node for latter wrapping in class.
                 if (nodeReferencesTotal.get(ref) > 1) {
-                    refClassMapping.put(ref, classCounter);
-                    objectsToWrapInClass.put(variableExprNode, classCounter++);    
+                    refClassMapping.put(ref, classCounter+128);
+                    objectsToWrapInClass.put(variableExprNode, 128+classCounter++);    
                 }
             }
         }
     }
-//
-//    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("disjunction");
+            LinkedHashMap<String, Object> topOr = 
+                    KoralObjectGenerator.makeGroup("disjunction");
             requestMap.put("query", topOr);
             objectStack.push(topOr);
         }
@@ -315,17 +359,24 @@
         } 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();
+                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"))) { 
+        } 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();
+                LinkedHashMap<String, Object> term = 
+                        KoralObjectGenerator.makeTerm();
                 object.put("wrap", term);
                 term.putAll(qNameParse);
             } else {
@@ -334,20 +385,24 @@
             }
         } else if (firstChildNodeCat.equals("textSpec")) {
             object = KoralObjectGenerator.makeToken();
-            LinkedHashMap<String, Object> term = KoralObjectGenerator.makeTerm();
+            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 (node.getChildCount() == 3) {  			
+            // (foundry/)?layer=key specification
             if (object.get("@type").equals("korap:token")) {
-                HashMap<String, Object> term = (HashMap<String, Object>) object.get("wrap");
+                HashMap<String, Object> term = (HashMap<String, Object>) 
+                        object.get("wrap");
                 term.putAll(parseTextSpec(node.getChild(2)));
-                term.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
+                term.put("match", parseMatchOperator(
+                        getFirstChildWithCat(node, "eqOperator")));
             } else {
                 object.putAll(parseTextSpec(node.getChild(2)));
-                object.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
+                object.put("match", parseMatchOperator(
+                        getFirstChildWithCat(node, "eqOperator")));
             }
         }
 
@@ -360,8 +415,10 @@
                 object.put("attr", 
                         parseUnaryOperator(unaryTermsForRef.get(0)));   
             } else {
-                LinkedHashMap<String, Object> termGroup = KoralObjectGenerator.makeTermGroup("and");
-                ArrayList<Object> operands = (ArrayList<Object>) termGroup.get("operands");
+                LinkedHashMap<String, Object> termGroup = 
+                        KoralObjectGenerator.makeTermGroup("and");
+                ArrayList<Object> operands = (ArrayList<Object>) 
+                        termGroup.get("operands");
                 for (ParseTree unaryTerm : unaryTermsForRef) {
                     operands.add(parseUnaryOperator(unaryTerm));
                 }
@@ -375,7 +432,8 @@
             }
             ParseTree parentsFirstChild = node.getParent().getChild(0);
             if (getNodeCat(parentsFirstChild).endsWith("#")) {
-                nodeVariables.put(getNodeCat(parentsFirstChild).replaceAll("#", ""), object);
+                nodeVariables.put(getNodeCat(parentsFirstChild).
+                        replaceAll("#", ""), object);
             }
             if (objectsToWrapInClass.containsKey(node)) {
                 int classId = objectsToWrapInClass.get(node);
@@ -386,30 +444,38 @@
     }
 
     /**
-     * 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 Koral representation of the operand 
+     * 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 The operand node of a relation, e.g. '#1'
+     * @return A map object with the appropriate KoralQuery 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);
+            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) {
+                    refClassMapping.put(ref, classCounter+128);
+                    operand = KoralObjectGenerator.
+                            wrapInClass(operand, 128+classCounter++);
+                } else if (nodeReferencesProcessed.get(ref)>0 && 
+                        nodeReferencesTotal.get(ref)>1) {
                     try {
-                        operand = KoralObjectGenerator.wrapInReference(operandStack.pop(), refClassMapping.get(ref), true);
+                        operand = KoralObjectGenerator.wrapInReference(
+                                operandStack.pop(), refClassMapping.get(ref));
                     } catch (NoSuchElementException e) {
-                        operand = KoralObjectGenerator.makeReference(refClassMapping.get(ref));
+                        operand = KoralObjectGenerator.makeReference(
+                                refClassMapping.get(ref));
                     }
                 }
-                nodeReferencesProcessed.put(ref, nodeReferencesProcessed.get(ref)+1);
+                nodeReferencesProcessed.put(ref, 
+                        nodeReferencesProcessed.get(ref)+1);
             }
         } else {
             operand = processVariableExpr(operandNode.getChild(0));
@@ -425,7 +491,8 @@
         // We can assume two operands.
         ParseTree operand1 = node.getChild(0);
         ParseTree operand2 = node.getChild(2);
-        if (checkOperandProcessedPreviously(operand1) || checkOperandProcessedPreviously(operand2)) {
+        if (checkOperandProcessedPreviously(operand1) || 
+                checkOperandProcessedPreviously(operand2)) {
             return true;
         }
         return false;
@@ -449,9 +516,11 @@
     @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.
+        // Get operator and determine type of group (sequence/treeRelation/
+        // relation/...). It's possible in Annis QL to concatenate operatiors,
+        // so there may be several operators under one n_ary_linguistic_term 
+        // node. Counter 'i' will iteratively point to all operator nodes 
+        // (odd-numbered children) 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);
@@ -476,61 +545,86 @@
                 }
             }
             // 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
+            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
+            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();
+                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));
+                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
+                // 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(KoralObjectGenerator.wrapInClass(
+                            KoralObjectGenerator.makeSpan(), classCounter+128));
+                    // add the first operand and wrap the whole group in a 
+                    // focusing reference 
                     innerOperands.add(operand1);
-                    innerGroup = KoralObjectGenerator.wrapInReference(innerGroup, classCounter, true);
+                    innerGroup = KoralObjectGenerator.
+                            wrapInReference(innerGroup, classCounter+128);
                     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);
+                // 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+128);
                 }
                 outerOperands.add(operand2);
-
-                // Wrap in another reference object in case other relations are following
+                // Wrap in another reference object in case other relations
+                // are following
                 if (i < node.getChildCount()-2) {
-                    group = KoralObjectGenerator.wrapInReference(group, classCounter, true);
+                    group = KoralObjectGenerator.wrapInReference(
+                            group, classCounter+128);
                 }
-                // All other n-ary linguistic relations have special 'relation' attributes defined in CQLF and can be
-                // handled more easily...
+                // All other n-ary linguistic relations have special 'relation' 
+                // attributes defined in KoralQ. and can be handled more easily
             } else {
-                LinkedHashMap<String, Object> operatorGroup = parseOperatorNode(node.getChild(i).getChild(0));
+                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")) {
+                if (groupType.equals("relation") || 
+                        groupType.equals("treeRelation")) {
                     group = KoralObjectGenerator.makeGroup(groupType);
-                    LinkedHashMap<String, Object> relation = new LinkedHashMap<String, Object>();
+                    LinkedHashMap<String, Object> relation = 
+                            new LinkedHashMap<String, Object>();
                     putAllButGroupType(relation, operatorGroup);
                     group.put("relation", relation);
                 } else if (groupType.equals("sequence")) {
@@ -541,46 +635,67 @@
                     putAllButGroupType(group, operatorGroup);
                 }
 
-                // Get operands list before possible re-assignment of 'group' (see following 'if')
+                // 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");
+                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});
-                    operand2 = KoralObjectGenerator.wrapInClass(operand2, ++classCounter);
-                    ((ArrayList<Object>) positionGroup.get("operands")).add(group);
-                    ((ArrayList<Object>) positionGroup.get("operands")).add(KoralObjectGenerator.makeReference(classCounter));
+                    String frame = (leftChildSpec!=null) ? 
+                            "frames:startsWith" : "frames:endsWith";
+                    LinkedHashMap<String,Object> positionGroup = 
+                            KoralObjectGenerator.
+                            makePosition(new String[]{frame});
+                    operand2 = KoralObjectGenerator.wrapInClass(
+                            operand2, ++classCounter+128);
+                    ((ArrayList<Object>) positionGroup.get("operands")).
+                            add(group);
+                    ((ArrayList<Object>) positionGroup.get("operands")).
+                            add(KoralObjectGenerator.
+                                    makeReference(classCounter+128));
                     group = positionGroup;
                 }
 
-                // Wrap in reference object in case other relations are following
+                // Wrap in reference object in case other relations follow
                 if (i < node.getChildCount()-2) {
-                    group = KoralObjectGenerator.wrapInReference(group, classCounter, true);
+                    group = KoralObjectGenerator.wrapInReference(
+                            group, classCounter+128);
                 }
 
                 // Inject operands.
                 // -> Case distinction:
                 if (node.getChildCount()==3) {
-                    // Things are easy when there's just one operator (thus 3 children incl. operands)...
+                    // 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:
+                    // ... 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)
+                        if (operand2 != null) operands.add(KoralObjectGenerator.
+                                wrapInClass(operand2, 128+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)
+                        // for all subsequent operators, only take 2nd operand
+                        // (1st 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++));
+                        // 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, 128+classCounter++));
                         operands.add(0, operandStack.pop());
                         operandStack.push(group);
                     } else if (i == node.getChildCount()-2) {
@@ -589,8 +704,10 @@
                     }
                 }
             }
-            // 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) {
+            // 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());
@@ -603,11 +720,10 @@
         }
     }
 
-
-
     /**
-     * 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.
+     * 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 
      */
@@ -615,7 +731,8 @@
         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);
+            LinkedHashMap<String, Object> boundary = 
+                    boundaryFromRangeSpec(node.getChild(3), false);
             term.put(op, boundary);
         } else {
             term.put(op, true);
@@ -624,63 +741,76 @@
     }
 
     @SuppressWarnings("unchecked")
-    private LinkedHashMap<String, Object> parseOperatorNode(ParseTree operatorNode) {
+    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 qName = getFirstChildWithCat(
+                    operatorNode, "qName");
+            ParseTree edgeSpecNode = getFirstChildWithCat(
+                    operatorNode, "edgeSpec");
             ParseTree star = getFirstChildWithCat(operatorNode, "*");
-            ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
-            LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
+            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);
+                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");
+                    ArrayList<Object> termGroupOperands = 
+                            (ArrayList<Object>) term.get("operands");
                     termGroupOperands.add(edgeSpec);
-                    LinkedHashMap<String,Object> constTerm = KoralObjectGenerator.makeTerm();
+                    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));
+            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 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();
+            ParseTree rangeSpec = 
+                    getFirstChildWithCat(operatorNode, "rangeSpec");
+            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));
+            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 rangeSpec = 
+                    getFirstChildWithCat(operatorNode, "rangeSpec");
             ParseTree star = getFirstChildWithCat(operatorNode, "*");
             ArrayList<Object> distances = new ArrayList<Object>();
             if (star != null) {
-                distances.add(KoralObjectGenerator.makeDistance("w", 0, null));
+                distances.add(KoralObjectGenerator.
+                        makeDistance("w", 0, null));
                 relation.put("distances", distances);
             }
             if (rangeSpec != null) {
@@ -690,8 +820,6 @@
             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) {
@@ -699,16 +827,19 @@
                     frames = new String[]{"frames:matches"}; 
                     break;
                 case "_l_":
-                    frames = new String[]{"frames:startsWith", "frames:matches"};
+                    frames = new String[]{"frames:startsWith", 
+                            "frames:matches"};
                     break;
                 case "_r_":
-                    frames = new String[]{"frames:endsWith", "frames:matches"};
+                    frames = new String[]{"frames:endsWith", 
+                            "frames:matches"};
                     break;
                 case "_i_":
                     frames = new String[]{"frames:isAround"};
                     break;
                 case "_o_":
-                    frames = new String[]{"frames:overlapsLeft", "frames:overlapsRight"};
+                    frames = new String[]{"frames:overlapsLeft", 
+                            "frames:overlapsRight"};
                     break;
                 case "_ol_":
                     frames = new String[]{"frames:overlapsLeft"};
@@ -717,19 +848,19 @@
                     frames = new String[]{"frames:overlapsRight"};
                     break;
             }
-            //			relation.put("frames", frames);
-            //			relation.put("sharedClasses", sharedClasses);
             relation = KoralObjectGenerator.makePosition(frames);
             relation.put("groupType", "position");
         } 
         else if (operator.equals("near")) {
             relation = new LinkedHashMap<String, Object>();
             relation.put("groupType", "sequence");
-            ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
+            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));
+                distances.add(KoralObjectGenerator.
+                        makeDistance("w", 0, null));
                 relation.put("distances", distances);
             }
             if (rangeSpec != null) {
@@ -755,8 +886,10 @@
         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");
+            LinkedHashMap<String,Object> termGroup = 
+                    KoralObjectGenerator.makeTermGroup("and");
+            ArrayList<Object> operands = 
+                    (ArrayList<Object>) termGroup.get("operands");
             for (ParseTree anno : annos) {
                 operands.add(parseEdgeAnno(anno));
             }
@@ -764,35 +897,45 @@
         }
     }
 
-    private LinkedHashMap<String, Object> parseEdgeAnno(ParseTree edgeAnnoSpec) {
-        LinkedHashMap<String, Object> edgeAnno = new LinkedHashMap<String, Object>();
+    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 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));
+        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) {
+    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));
+    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));
+            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 min = 
+                Integer.parseInt(rangeSpec.getChild(0).toStringTree(parser));
         Integer max = null;
         if (rangeSpec.getChildCount()==3) 
             max = Integer.parseInt(rangeSpec.getChild(2).toStringTree(parser));
@@ -803,7 +946,8 @@
         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("/", ""));
+            term.put("key", node.getChild(0).getChild(0).toStringTree(parser).
+                    replaceAll("/", ""));
         } else {
             term.put("key", node.getChild(1).toStringTree(parser));
         }
@@ -818,16 +962,19 @@
      */
     private String parseMatchOperator(ParseTree node) {
         if (node.getChildCount()>0) {
-            return node.getChild(0).getText().equals("=") ? "match:eq" : "match:ne";
+            return node.getChild(0).getText().equals("=") ? 
+                    "match:eq" : "match:ne";
         }
         return "match:eq";
     }
 
     private LinkedHashMap<String, Object> parseQNameNode(ParseTree node) {
-        LinkedHashMap<String, Object> fields = new LinkedHashMap<String, Object>();
+        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));
+        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";
@@ -840,9 +987,11 @@
     }
 
     @SuppressWarnings({ "unchecked" })
-    private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
+    private void putIntoSuperObject(
+            LinkedHashMap<String, Object> object, int objStackPosition) {
         if (objectStack.size()>objStackPosition) {
-            ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
+            ArrayList<Object> topObjectOperands = (ArrayList<Object>) 
+                    objectStack.get(objStackPosition).get("operands");
             if (!invertedOperandsLists.contains(topObjectOperands)) {
                 topObjectOperands.add(object);
             } else {
@@ -853,7 +1002,8 @@
         }
     }
 
-    private void putAllButGroupType(Map<String, Object> container, Map<String, Object> input) {
+    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));
@@ -864,7 +1014,8 @@
     private ParserRuleContext parseAnnisQuery (String query) {
         Lexer lexer = new AqlLexer((CharStream)null);
         ParserRuleContext tree = null;
-        Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
+        Antlr4DescriptiveErrorListener errorListener = 
+                new Antlr4DescriptiveErrorListener(query);
         // Like p. 111
         try {
             // Tokenize input data
@@ -880,11 +1031,12 @@
             parser.addErrorListener(errorListener);
             // Get starting rule from parser
             Method startRule = AqlParser.class.getMethod("start"); 
-            tree = (ParserRuleContext) startRule.invoke(parser, (Object[])null);
+            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("Could not parse query. "
+                    + "Please make sure it is well-formed.");
             log.error(errorListener.generateFullErrorMsg().toString());
             addError(errorListener.generateFullErrorMsg());
         }
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
index 822d022..3750220 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr3AbstractQueryProcessor.java
@@ -8,17 +8,31 @@
 import org.antlr.runtime.Parser;
 import org.antlr.runtime.tree.Tree;
 
+/**
+ * This class is provides methods for navigation and search in Abstract Syntax
+ * Trees returned by ANTLR v3 parsers, using ANTLR v3 libraries. Any class that
+ * extends this abstract class will thus be equipped with such methods,
+ * which makes it easier to, e.g., retrieve children of a specific category
+ * for some node. 
+ * 
+ * @author Joachim Bingel (bingel@ids-mannheim.de)
+ * @version 0.1.0
+ * @since 0.1.0
+ */
 public abstract class Antlr3AbstractQueryProcessor extends
         AbstractQueryProcessor {
 
+    /**
+     * The ANTLR parser. Subclasses need to instantiate this field.
+     */
     protected Parser parser;
 
     /**
      * Returns the category (or 'label') of the root of a (sub-)
      * ParseTree (ANTLR 3).
      *
-     * @param node
-     * @return
+     * @param node The tree node. 
+     * @return The category of the node.
      */
     protected static String getNodeCat(Tree node) {
         String nodeCat = node.toStringTree();
@@ -32,14 +46,14 @@
     }
 
     /**
-     * Tests whether a certain node has a child by a certain name
+     * Tests whether a certain node has a child of a certain category.
      *
      * @param node
      *            The parent node.
      * @param childCat
      *            The category of the potential child.
      * @return true iff one or more children belong to the specified
-     *         category
+     *         category.
      */
     protected static boolean hasChild(Tree node, String childCat) {
         for (int i = 0; i < node.getChildCount(); i++) {
@@ -50,6 +64,17 @@
         return false;
     }
 
+    /**
+     * Tests whether a certain node has a descendant (direct or indirect child)
+     * of a certain category.
+     *
+     * @param node
+     *            The parent node.
+     * @param childCat
+     *            The category of the potential descendant.
+     * @return true iff one or more descendants belong to the specified
+     *         category.
+     */
     protected static boolean hasDescendantWithCat(Tree node, String childCat) {
         for (int i = 0; i < node.getChildCount(); i++) {
             Tree child = node.getChild(i);
@@ -63,6 +88,11 @@
         return false;
     }
 
+    /**
+     * Returns all children of a node.
+     * @param node The node.
+     * @return A list containing all children. 
+     */
     protected static List<Tree> getChildren(Tree node) {
         ArrayList<Tree> children = new ArrayList<Tree>();
         for (int i = 0; i < node.getChildCount(); i++) {
@@ -71,6 +101,13 @@
         return children;
     }
 
+    /**
+     * Returns all children of a node which are of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned children. 
+     * @return A (possibly empty) list containing all children of the given
+     *      category. 
+     */
     protected static List<Tree> getChildrenWithCat(Tree node, String nodeCat) {
         ArrayList<Tree> children = new ArrayList<Tree>();
         for (int i = 0; i < node.getChildCount(); i++) {
@@ -81,11 +118,47 @@
         return children;
     }
 
+    /**
+     * Returns all descendants (direct or indirect children) of a node which
+     * are of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned descendants. 
+     * @return A (possibly empty) list containing all descendants of the given
+     *      category. 
+     */
+    protected List<Tree> getDescendantsWithCat(Tree node, String nodeCat) {
+        ArrayList<Tree> descendants = new ArrayList<Tree>();
+        for (Tree child : getChildren(node)) {
+            if (getNodeCat(child).equals(nodeCat)) {
+                descendants.add(child);
+            }
+            descendants.addAll(getDescendantsWithCat(child, nodeCat));
+        }
+        return descendants;
+    }
+    
+    /**
+     * Returns the first child of a node which is of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned child. 
+     * @return The first child with the given category, <tt>null</tt> if no
+     *      such child exists. 
+     */
     protected static Tree getFirstChildWithCat(Tree node, String nodeCat) {
         return getNthChildWithCat(node, nodeCat, 1);
     }
 
-    protected static Tree getNthChildWithCat(Tree node, String nodeCat, int n) {
+    /**
+     * Returns the nth child of a node which is of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned child. 
+     * @param n The index of the child to return, among all children with the
+     *      given category.
+     * @return The nth child with the given category, <tt>null</tt> if no
+     *      such child exists (i.e., if n is larger than the number of children
+     *      with the given category). 
+     */
+    protected static Tree getNthChildWithCat(Tree node,String nodeCat, int n) {
         int counter = 0;
         for (int i = 0; i < node.getChildCount(); i++) {
             if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java
index 517338e..324d25e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/Antlr4AbstractQueryProcessor.java
@@ -8,22 +8,37 @@
 import org.antlr.v4.runtime.Parser;
 import org.antlr.v4.runtime.tree.ParseTree;
 
-public abstract class Antlr4AbstractQueryProcessor extends AbstractQueryProcessor {
+/**
+ * This class is provides methods for navigation and search in Abstract Syntax
+ * Trees returned by ANTLR v4 parsers, using ANTLR v4 libraries. Any class that
+ * extends this abstract class will thus be equipped with such methods,
+ * which makes it easier to, e.g., retrieve children of a specific category
+ * for some node. 
+ * 
+ * @author Joachim Bingel (bingel@ids-mannheim.de)
+ * @version 0.1.0
+ * @since 0.1.0
+ */
+public abstract class Antlr4AbstractQueryProcessor extends  
+        AbstractQueryProcessor {
 
-	/**
-	 * Parser object deriving the ANTLR parse tree.
-	 */
+    /**
+     * The ANTLR parser. Subclasses need to instantiate this field such that it
+     * can be used in the methods of this class.
+     */
 	protected Parser parser;
 
 	 /**
-     * Returns the category (or 'label') of the root of a (sub-) ParseTree (ANTLR 4).
+     * Returns the category (or 'label') of the root of a (sub-) 
+     * ParseTree (ANTLR 4).
      *
-     * @param node
-     * @return
+     * @param node The tree node. 
+     * @return The category of the node.
      */
 	protected String getNodeCat(ParseTree node) {
         String nodeCat = node.toStringTree(parser);
-        Pattern p = Pattern.compile("\\((.*?)\\s"); // from opening parenthesis to 1st whitespace
+        // pattern: from opening parenthesis to 1st whitespace
+        Pattern p = Pattern.compile("\\((.*?)\\s"); 
         Matcher m = p.matcher(node.toStringTree(parser));
         if (m.find()) {
             nodeCat = m.group(1);
@@ -31,12 +46,15 @@
         return nodeCat;
     }
     
-    /**
-     * Tests whether a certain node has a child by a certain name
+	/**
+     * Tests whether a certain node has a child of a certain category.
      *
-     * @param node     The parent node.
-     * @param childCat The category of the potential child.
-     * @return true iff one or more children belong to the specified category
+     * @param node
+     *            The parent node.
+     * @param childCat
+     *            The category of the potential child.
+     * @return true iff one or more children belong to the specified
+     *         category.
      */
     protected boolean hasChild(ParseTree node, String childCat) {
         for (int i = 0; i < node.getChildCount(); i++) {
@@ -47,6 +65,17 @@
         return false;
     }
 
+    /**
+     * Tests whether a certain node has a descendant (direct or indirect child)
+     * of a certain category.
+     *
+     * @param node
+     *            The parent node.
+     * @param childCat
+     *            The category of the potential descendant.
+     * @return true iff one or more descendants belong to the specified
+     *         category.
+     */
     protected boolean hasDescendantWithCat(ParseTree node, String childCat) {
         for (int i = 0; i < node.getChildCount(); i++) {
             ParseTree child = node.getChild(i);
@@ -60,7 +89,11 @@
         return false;
     }
     
-
+    /**
+     * Returns all children of a node.
+     * @param node The node.
+     * @return A list containing all children. 
+     */
     protected List<ParseTree> getChildren(ParseTree node) {
         ArrayList<ParseTree> children = new ArrayList<ParseTree>();
         for (int i = 0; i < node.getChildCount(); i++) {
@@ -69,7 +102,15 @@
         return children;
     }
     
-    protected List<ParseTree> getChildrenWithCat(ParseTree node, String nodeCat) {
+    /**
+     * Returns all children of a node which are of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned children. 
+     * @return A (possibly empty) list containing all children of the given
+     *      category. 
+     */
+    protected List<ParseTree> getChildrenWithCat(ParseTree node, 
+            String nodeCat) {
         ArrayList<ParseTree> children = new ArrayList<ParseTree>();
         for (int i = 0; i < node.getChildCount(); i++) {
             if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
@@ -79,7 +120,16 @@
         return children;
     }
     
-    protected List<ParseTree> getDescendantsWithCat(ParseTree node, String nodeCat) {
+    /**
+     * Returns all descendants (direct or indirect children) of a node which
+     * are of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned descendants. 
+     * @return A (possibly empty) list containing all descendants of the given
+     *      category. 
+     */
+    protected List<ParseTree> getDescendantsWithCat(ParseTree node, 
+            String nodeCat) {
         ArrayList<ParseTree> descendants = new ArrayList<ParseTree>();
         for (ParseTree child : getChildren(node)) {
             if (getNodeCat(child).equals(nodeCat)) {
@@ -90,11 +140,29 @@
         return descendants;
     }
 
+    /**
+     * Returns the first child of a node which is of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned child. 
+     * @return The first child with the given category, <tt>null</tt> if no
+     *      such child exists. 
+     */
     protected ParseTree getFirstChildWithCat(ParseTree node, String nodeCat) {
         return getNthChildWithCat(node, nodeCat, 1);
     }
     
-    protected ParseTree getNthChildWithCat(ParseTree node, String nodeCat, int n) {
+    /**
+     * Returns the nth child of a node which is of a given category.
+     * @param node The node.
+     * @param nodeCat The node category constraining the returned child. 
+     * @param n The index of the child to return, among all children with the
+     *      given category.
+     * @return The nth child with the given category, <tt>null</tt> if no
+     *      such child exists (i.e., if n is larger than the number of children
+     *      with the given category). 
+     */
+    protected ParseTree getNthChildWithCat(ParseTree node, String nodeCat, 
+            int n) {
     	int counter = 0;
     	for (int i = 0; i < node.getChildCount(); i++) {
     		if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
index acad4d6..a884171 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
@@ -17,30 +17,21 @@
 import java.util.regex.Pattern;
 
 /**
- * @author hanl, bingel
- * @date 06/12/2013
+ * This class processes queries that define virtual collections and create
+ * an KoralQuery representation of these in the <tt>collection</tt> attribute
+ * of the KoralQuery tree. See the official documentation for VC query syntax
+ * and functionality.
+ * 
+ * @author Michael Hanl (hanl@ids-mannheim.de)
+ * @author Joachim Bingel (bingel@ids-mannheim.de)
+ * @version 0.1.0
+ * @since 0.1.0
  */
 public class CollectionQueryProcessor extends Antlr4AbstractQueryProcessor {
 
-	private static Logger log = LoggerFactory.getLogger(CollectionQueryProcessor.class);
-    private Parser parser;
-    private static boolean verbose;
-    private List<ParseTree> visited = new ArrayList<ParseTree>();
+	private static Logger log = 
+	        LoggerFactory.getLogger(CollectionQueryProcessor.class);
 
-    /**
-     * Keeps track of active object.
-     */
-    LinkedList<LinkedHashMap<String, Object>> objectStack = new LinkedList<LinkedHashMap<String, Object>>();
-    /**
-     * Keeps track of open node categories
-     */
-    LinkedList<String> openNodeCats = new LinkedList<String>();
-    /**
-     * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
-     */
-    LinkedList<Integer> objectsToPop = new LinkedList<Integer>();
-    Integer stackedObjects = 0;
-    
     public CollectionQueryProcessor() {
     	KoralObjectGenerator.setQueryProcessor(this);
 	}
@@ -61,15 +52,17 @@
         if (this.parser != null) {
             super.parser = this.parser;
         } else {
-            throw new NullPointerException("Parser has not been instantiated!");
+            throw new NullPointerException(
+                    "Parser has not been instantiated!");
         }
-        log.info("Processing collection query: "+query);
+        log.info("Processing virtual collection query: "+query);
         if (verbose) System.out.println(tree.toStringTree(parser));
         if (tree != null) {
 			log.debug("ANTLR parse tree: "+tree.toStringTree(parser));
 			processNode(tree);
 		} else {
-			addError(StatusCodes.MALFORMED_QUERY, "Could not parse query >>> "+query+" <<<.");
+			addError(StatusCodes.MALFORMED_QUERY, 
+			        "Could not parse query >>> "+query+" <<<.");
 		}
     }
 
@@ -93,8 +86,10 @@
 		 */
 
         if (nodeCat.equals("relation")) {
-        	String operator = node.getChild(1).getChild(0).toStringTree(parser).equals("&") ? "and" : "or"; 
-            LinkedHashMap<String, Object> relationGroup = KoralObjectGenerator.makeDocGroup(operator);
+        	String operator = getNodeCat(node.getChild(1).getChild(0))
+        	        .equals("&") ? "and" : "or";
+            LinkedHashMap<String, Object> relationGroup = 
+                    KoralObjectGenerator.makeDocGroup(operator);
             putIntoSuperObject(relationGroup);
             objectStack.push(relationGroup);
             stackedObjects++;
@@ -105,7 +100,8 @@
             String field = fieldNode.getChild(0).toStringTree(parser);
             ParseTree operatorNode = getFirstChildWithCat(node, "operator");
             ParseTree valueNode = getFirstChildWithCat(node, "value");
-            LinkedHashMap<String, Object> term = KoralObjectGenerator.makeDoc();
+            LinkedHashMap<String, Object> term = 
+                    KoralObjectGenerator.makeDoc();
             term.put("key", field);
             term.putAll(parseValue(valueNode));
             String match = operatorNode.getText();
@@ -115,9 +111,12 @@
             	return;
             }
             if (checkDateValidity(valueNode)) {
-        		addWarning("The collection query contains a value that looks like a date ('"+valueNode.getText()+"')"
-        				+ " and an operator that is only defined for strings ('"+match+"'). The value is interpreted as "
-        						+ "a string. Use a date operator to ensure the value is treated as a date");            	
+        		addWarning("The collection query contains a value that looks"
+        		        + " like a date ('"+valueNode.getText()+"') and an"
+        				+ " operator that is only defined for strings"
+        				+ " ('"+match+"'). The value is interpreted as"
+        				+ " a string. Use a date operator to ensure the value"
+        				+ " is treated as a date");            	
             }
             putIntoSuperObject(term);
         }
@@ -128,7 +127,8 @@
             ParseTree dateOpNode = getFirstChildWithCat(node, "dateOp");
             ParseTree dateNode = getFirstChildWithCat(node, "date");
 
-            LinkedHashMap<String, Object> term = KoralObjectGenerator.makeDoc();
+            LinkedHashMap<String, Object> term = 
+                    KoralObjectGenerator.makeDoc();
             term.put("key", field);
             term.putAll(parseValue(dateNode));
             String match = dateOpNode.getText();
@@ -141,7 +141,8 @@
         }
         
         if (nodeCat.equals("token")) {
-			LinkedHashMap<String,Object> token = KoralObjectGenerator.makeToken();
+			LinkedHashMap<String,Object> token = 
+			        KoralObjectGenerator.makeToken();
 			// handle negation
 			List<ParseTree> negations = getChildrenWithCat(node, "!");
 			boolean negated = false;
@@ -149,7 +150,8 @@
 			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 = KoralObjectGenerator.makeTerm();
+				LinkedHashMap<String,Object> term = 
+				        KoralObjectGenerator.makeTerm();
 				String key = node.getChild(0).getText();
 				if (getNodeCat(node.getChild(0).getChild(0)).equals("regex")) {
 					isRegex = true;
@@ -162,9 +164,12 @@
 				term.put("match", "match:"+matches);
 				ParseTree flagNode = getFirstChildWithCat(node, "flag");
 				if (flagNode != null) {
-					String flag = getNodeCat(flagNode.getChild(0)).substring(1); //substring removes leading slash '/'
-					if (flag.contains("i")) term.put("caseInsensitive", true);
-					else if (flag.contains("I")) term.put("caseInsensitive", false);
+				    // 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) {
@@ -176,14 +181,14 @@
 				token.put("wrap", term);
 			} else {
 				// child is 'term' or 'termGroup' -> process in extra method 
-				LinkedHashMap<String,Object> termOrTermGroup = parseTermOrTermGroup(node.getChild(1), negated);
+				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));
 		}
-
         objectsToPop.push(stackedObjects);
 
 		/*
@@ -215,14 +220,20 @@
     }
 
 	/**
-	 * Checks whether the combination of operator and value is legal (inequation operators <,>,<=,>= may only be used with dates).
+	 * Checks whether the combination of operator and value is legal 
+	 * (inequation operators <,>,<=,>= may only be used with dates).
 	 */
-    private boolean checkOperatorValueConformance(LinkedHashMap<String, Object> term) {
+    private boolean checkOperatorValueConformance(
+            LinkedHashMap<String, Object> term) {
 		String match = (String) term.get("match");
 		String type = (String) term.get("type");
 		if (type == null || type.equals("type:regex")) {
-			if (!(match.equals("match:eq") || match.equals("match:ne") || match.equals("match:contains") || match.equals("match:containsnot"))) {
-				addError(StatusCodes.INCOMPATIBLE_OPERATOR_AND_OPERAND, "You used an inequation operator with a string value.");
+			if (!(match.equals("match:eq") 
+			        || match.equals("match:ne") 
+			        || match.equals("match:contains") 
+			        || match.equals("match:containsnot"))) {
+				addError(StatusCodes.INCOMPATIBLE_OPERATOR_AND_OPERAND, 
+				       "You used an inequation operator with a string value.");
 				return false;
 			}
 		}
@@ -230,13 +241,15 @@
 	}
 
 	private LinkedHashMap<String, Object> parseValue(ParseTree valueNode) {
-    	LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
+    	LinkedHashMap<String, Object> map = 
+    	        new LinkedHashMap<String, Object>();
     	if (getNodeCat(valueNode).equals("date")) {
     		map.put("type", "type:date");
     		checkDateValidity(valueNode);
     	}
     	if (getNodeCat(valueNode.getChild(0)).equals("regex")) {
-    		String regex = valueNode.getChild(0).getChild(0).toStringTree(parser);
+    		String regex = 
+    		        valueNode.getChild(0).getChild(0).toStringTree(parser);
     		map.put("value", regex.substring(1, regex.length()-1));
     		map.put("type", "type:regex");
     	} else if (getNodeCat(valueNode.getChild(0)).equals("multiword")) {
@@ -316,7 +329,8 @@
                 break;
             default:
             	out = match;
-            	addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, "Unknown operator '"+match+"'.");
+            	addError(StatusCodes.UNKNOWN_QUERY_ELEMENT, 
+            	        "Unknown operator '"+match+"'.");
             	break;
         }
         return out;
@@ -347,9 +361,11 @@
     }
 
     @SuppressWarnings({"unchecked"})
-    private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
+    private void putIntoSuperObject(LinkedHashMap<String, Object> object, 
+            int objStackPosition) {
         if (objectStack.size() > objStackPosition) {
-            ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
+            ArrayList<Object> topObjectOperands = (ArrayList<Object>) 
+                    objectStack.get(objStackPosition).get("operands");
             topObjectOperands.add(object);
         } else {
 //        	requestMap = object;
@@ -365,15 +381,18 @@
     /**
 	 * Parses a (term) or (termGroup) node
 	 * @param node
-	 * @param negatedGlobal Indicates whether the term/termGroup is globally negated, e.g. through a negation 
-	 * operator preceding the related token like "![base=foo]". Global negation affects the term's "match" parameter.
+	 * @param negatedGlobal Indicates whether the term/termGroup is globally 
+	 * negated, e.g. through a negation operator preceding the related token  
+	 * like "![base=foo]". Global negation affects the "match" parameter.
 	 * @return A term or termGroup object, depending on input
 	 */
 	@SuppressWarnings("unchecked")
-	private LinkedHashMap<String, Object> parseTermOrTermGroup(ParseTree node, boolean negatedGlobal, String mode) {
+	private LinkedHashMap<String, Object> parseTermOrTermGroup(
+	        ParseTree node, boolean negatedGlobal, String mode) {
 		if (getNodeCat(node).equals("term")) {
 			String key = null;
-			LinkedHashMap<String,Object> term = KoralObjectGenerator.makeTerm();
+			LinkedHashMap<String,Object> term = 
+			        KoralObjectGenerator.makeTerm();
 			// handle negation
 			boolean negated = negatedGlobal;
 			boolean isRegex = false;
@@ -387,7 +406,8 @@
 			ParseTree termOpNode = getFirstChildWithCat(node, "termOp");
 			ParseTree flagNode = getFirstChildWithCat(node, "flag");
 			// process foundry
-			if (foundryNode != null) term.put("foundry", foundryNode.getText());
+			if (foundryNode != null) 
+			    term.put("foundry", foundryNode.getText());
 			// process layer: map "base" -> "lemma"
 			if (layerNode != null) {
 				String layer = layerNode.getText();
@@ -400,7 +420,8 @@
 			if (getNodeCat(keyNode.getChild(0)).equals("regex")) {
 				isRegex = true;
 				term.put("type", "type:regex");
-				key = key.substring(1, key.length()-1); // remove leading and trailing slashes
+				// remove leading and trailing slashes
+				key = key.substring(1, key.length()-1); 
 			}
 			if (mode.equals("span")) term.put("value", key);
 			else term.put("key", key);
@@ -415,34 +436,40 @@
 			}
 			// process possible flags
 			if (flagNode != null) {
-				String flag = getNodeCat(flagNode.getChild(0)).substring(1); //substring removes leading slash '/'
+			    // 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")) {
 					if (!isRegex) {
 						key = QueryUtils.escapeRegexSpecialChars(key); 
 					}
-					term.put("key", ".*?"+key+".*?");  // flag 'x' allows submatches: overwrite key with appended .*? 
+					// flag 'x' allows submatches: append .*? to key
+					term.put("key", ".*?"+key+".*?");   
 					term.put("type", "type:regex");
 				}
 			}
 			return term;
 		} else {
-			// For termGroups, establish a boolean relation between operands and recursively call this function with
-			// the term or termGroup operands
+			// For termGroups, establish a boolean relation between operands 
+		    // and recursively call this function with the term or termGroup 
+			// operands.
 			LinkedHashMap<String,Object> termGroup = null;
 			ParseTree leftOp = null;
 			ParseTree rightOp = null;
 			// check for leading/trailing parantheses
-			if (!getNodeCat(node.getChild(0)).equals("(")) leftOp = node.getChild(0);
+			if (!getNodeCat(node.getChild(0)).equals("(")) 
+			    leftOp = node.getChild(0);
 			else leftOp = node.getChild(1);
-			if (!getNodeCat(node.getChild(node.getChildCount()-1)).equals(")")) rightOp = node.getChild(node.getChildCount()-1);
+			if (!getNodeCat(node.getChild(node.getChildCount()-1)).equals(")")) 
+			    rightOp = node.getChild(node.getChildCount()-1);
 			else rightOp = node.getChild(node.getChildCount()-2);
 			// establish boolean relation
 			ParseTree boolOp = getFirstChildWithCat(node, "booleanOp"); 
 			String operator = boolOp.getText().equals("&") ? "and" : "or";
 			termGroup = KoralObjectGenerator.makeTermGroup(operator);
-			ArrayList<Object> operands = (ArrayList<Object>) termGroup.get("operands");
+			ArrayList<Object> operands = 
+			        (ArrayList<Object>) termGroup.get("operands");
 			// recursion with left/right operands
 			operands.add(parseTermOrTermGroup(leftOp, negatedGlobal, mode));
 			operands.add(parseTermOrTermGroup(rightOp, negatedGlobal, mode));
@@ -453,7 +480,8 @@
     private ParserRuleContext parseCollectionQuery(String query) {
         Lexer lexer = new CollectionQueryLexer((CharStream) null);
         ParserRuleContext tree = null;
-        Antlr4DescriptiveErrorListener errorListener = new Antlr4DescriptiveErrorListener(query);
+        Antlr4DescriptiveErrorListener errorListener = 
+                new Antlr4DescriptiveErrorListener(query);
         // Like p. 111
         try {
 
@@ -471,7 +499,8 @@
             parser.addErrorListener(errorListener);
             // Get starting rule from parser
             Method startRule = CollectionQueryParser.class.getMethod("start");
-            tree = (ParserRuleContext) startRule.invoke(parser, (Object[]) null);
+            tree = (ParserRuleContext) 
+                    startRule.invoke(parser, (Object[]) null);
         }
         // Some things went wrong ...
         catch (Exception e) {
diff --git a/src/test/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessorTest.java
index d8b0196..add2e16 100644
--- a/src/test/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/AnnisQueryProcessorTest.java
@@ -262,12 +262,12 @@
         assertEquals("S",					res.at("/query/operands/0/operands/0/key").asText());
         assertEquals("korap:group",			res.at("/query/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",		res.at("/query/operands/0/operands/1/operation").asText());
-        assertEquals(2,					    res.at("/query/operands/0/operands/1/classOut").asInt());
+        assertEquals(130,				    res.at("/query/operands/0/operands/1/classOut").asInt());
         assertEquals("korap:span",			res.at("/query/operands/0/operands/1/operands/0/@type").asText());
         assertEquals("NP",					res.at("/query/operands/0/operands/1/operands/0/key").asText());
         assertEquals("korap:reference",		res.at("/query/operands/1/@type").asText());
         assertEquals("operation:focus",		res.at("/query/operands/1/operation").asText());
-        assertEquals(2,					    res.at("/query/operands/1/classRef/0").asInt());
+        assertEquals(130,				    res.at("/query/operands/1/classRef/0").asInt());
 
         query = "cat=\"S\" & cat=\"NP\" & #1 >@r #2";  
         qs.setQuery(query, "annis");
@@ -279,12 +279,12 @@
         assertEquals("S",					res.at("/query/operands/0/operands/0/key").asText());
         assertEquals("korap:group",			res.at("/query/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",		res.at("/query/operands/0/operands/1/operation").asText());
-        assertEquals(2,					    res.at("/query/operands/0/operands/1/classOut").asInt());
+        assertEquals(130,					res.at("/query/operands/0/operands/1/classOut").asInt());
         assertEquals("korap:span",			res.at("/query/operands/0/operands/1/operands/0/@type").asText());
         assertEquals("NP",					res.at("/query/operands/0/operands/1/operands/0/key").asText());
         assertEquals("korap:reference",		res.at("/query/operands/1/@type").asText());
         assertEquals("operation:focus",		res.at("/query/operands/1/operation").asText());
-        assertEquals(2,					    res.at("/query/operands/1/classRef/0").asInt());
+        assertEquals(130,					res.at("/query/operands/1/classRef/0").asInt());
     }
 
     @Test
@@ -319,7 +319,7 @@
         assertEquals("operation:relation",	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(1,					    res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,   			    res.at("/query/operands/0/classRef/0").asInt());
         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:relation",		res.at("/query/operands/0/operands/0/relation/@type").asText());
@@ -329,7 +329,7 @@
         assertEquals("CP",					res.at("/query/operands/0/operands/0/operands/0/key").asText());
         assertEquals("korap:group",			res.at("/query/operands/0/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",		res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(1,					    res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(129,   			    res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("VP",					res.at("/query/operands/0/operands/0/operands/1/operands/0/key").asText());
     }
     //		query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";
@@ -479,7 +479,7 @@
         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(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/classRef/0").asInt());
         assertEquals(res.at("/query/operands/0/classRef/0").asInt(), 
                 res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
     }
@@ -603,14 +603,14 @@
         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(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/classRef/0").asInt());
         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:token",         res.at("/query/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("Sonne",               res.at("/query/operands/0/operands/0/operands/0/wrap/key").asText());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("Mond",                res.at("/query/operands/0/operands/0/operands/1/operands/0/wrap/key").asText());
         assertEquals("Sterne",              res.at("/query/operands/1/wrap/key").asText());
         assertEquals("w",                   res.at("/query/distances/0/key").asText());
@@ -624,14 +624,14 @@
         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(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/classRef/0").asInt());
         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:token",         res.at("/query/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("Sonne",               res.at("/query/operands/0/operands/0/operands/0/wrap/key").asText());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("Mond",                res.at("/query/operands/0/operands/0/operands/1/operands/0/wrap/key").asText());
         assertEquals("Sterne",              res.at("/query/operands/1/wrap/key").asText());
         assertEquals("w",                   res.at("/query/distances/0/key").asText());
@@ -645,21 +645,21 @@
         assertEquals("operation:relation",  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(2,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(130,                   res.at("/query/operands/0/classRef/0").asInt());
         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(1,                     res.at("/query/operands/0/operands/0/operands/0/classRef/0").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/operands/0/operands/0/classRef/0").asInt());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("operation:relation",  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(1,                     res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/classOut").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/classOut").asInt());
         assertEquals("korap:span",          res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("NP",                  res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/1/key").asText());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(2,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(130,                   res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("VP",                  res.at("/query/operands/0/operands/0/operands/1/operands/0/key").asText());
         assertEquals("PP",                  res.at("/query/operands/1/key").asText());
 
@@ -674,19 +674,19 @@
         assertEquals("frames:startsWith",   res.at("/query/frames/0").asText());
         assertEquals("korap:reference",     res.at("/query/operands/0/@type").asText());
         assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/classRef/0").asInt());
         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("operation:class",     res.at("/query/operands/0/operands/0/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/0/classOut").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/operands/0/operands/0/classOut").asInt());
         assertEquals("korap:span",          res.at("/query/operands/0/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("NP",                  res.at("/query/operands/0/operands/0/operands/0/operands/0/key").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(2,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(130,                   res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("VP",                  res.at("/query/operands/0/operands/0/operands/1/operands/0/key").asText());
         assertEquals("korap:reference",     res.at("/query/operands/1/@type").asText());
         assertEquals("operation:focus",     res.at("/query/operands/1/operation").asText());
-        assertEquals(2,  res.at("/query/operands/1/classRef/0").asInt());
+        assertEquals(130,                   res.at("/query/operands/1/classRef/0").asInt());
 
     }
     @Test
@@ -744,12 +744,12 @@
         res = mapper.readTree(qs.toJSON());
         assertEquals("frames:startsWith",   res.at("/query/frames/0").asText());
         assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/classRef/0").asInt());
         assertEquals("frames:endsWith",     res.at("/query/operands/0/operands/0/frames/0").asText());
         assertEquals("korap:span",          res.at("/query/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("VP",                  res.at("/query/operands/0/operands/0/operands/1/operands/0/key").asText());
         assertEquals("NP",                  res.at("/query/operands/1/key").asText());
 
@@ -787,14 +787,14 @@
         res = mapper.readTree(qs.toJSON());
         assertEquals("operation:sequence",  res.at("/query/operation").asText());
         assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/classRef/0").asInt());
         assertEquals("operation:sequence",  res.at("/query/operands/0/operands/0/operation").asText());
         assertEquals("korap:token",         res.at("/query/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("p",                   res.at("/query/operands/0/operands/0/operands/0/wrap/layer").asText());
         assertEquals("N",                   res.at("/query/operands/0/operands/0/operands/0/wrap/key").asText());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(129,                   res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("V",                   res.at("/query/operands/0/operands/0/operands/1/operands/0/wrap/key").asText());
         assertEquals("P",                   res.at("/query/operands/1/wrap/key").asText());
 
@@ -803,14 +803,14 @@
         res = mapper.readTree(qs.toJSON());
         assertEquals("operation:sequence",  res.at("/query/operation").asText());
         assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/classRef/0").asInt());
         assertEquals("operation:sequence",  res.at("/query/operands/0/operands/0/operation").asText());
         assertEquals("korap:token",         res.at("/query/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("p",                   res.at("/query/operands/0/operands/0/operands/0/wrap/layer").asText());
         assertEquals("N",                   res.at("/query/operands/0/operands/0/operands/0/wrap/key").asText());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/operands/1/@type").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/1/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("V",                   res.at("/query/operands/0/operands/0/operands/1/operands/0/wrap/key").asText());
         assertEquals("P",                   res.at("/query/operands/1/wrap/key").asText());
 
@@ -819,10 +819,10 @@
         res = mapper.readTree(qs.toJSON());
         assertEquals("operation:relation",  res.at("/query/operation").asText());
         assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/classRef/0").asInt());
         assertEquals("operation:relation",  res.at("/query/operands/0/operands/0/operation").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/0/classOut").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/operands/0/operands/0/classOut").asInt());
         assertEquals("N",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/wrap/key").asText());
         assertEquals("V",                   res.at("/query/operands/0/operands/0/operands/1/wrap/key").asText());
         assertEquals("P",                   res.at("/query/operands/1/wrap/key").asText());
@@ -832,20 +832,20 @@
         res = mapper.readTree(qs.toJSON());
         assertEquals("operation:sequence",  res.at("/query/operation").asText());
         assertEquals("operation:focus",     res.at("/query/operands/0/operation").asText());
-        assertEquals(2,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(130,                     res.at("/query/operands/0/classRef/0").asInt());
         assertEquals("operation:relation",  res.at("/query/operands/0/operands/0/operation").asText());
         assertEquals("operation:focus",     res.at("/query/operands/0/operands/0/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/0/classRef/0").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/operands/0/operands/0/classRef/0").asInt());
         assertEquals("operation:relation",  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(1,                     res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/classOut").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/classOut").asInt());
         assertEquals("NP",                  res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/0/operands/0/key").asText());
-        assertEquals(2,                     res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(130,                     res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("V",                   res.at("/query/operands/0/operands/0/operands/0/operands/0/operands/1/operands/0/wrap/key").asText());
-        assertEquals(3,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
+        assertEquals(131,                     res.at("/query/operands/0/operands/0/operands/1/classOut").asInt());
         assertEquals("P",                   res.at("/query/operands/0/operands/0/operands/1/operands/0/wrap/key").asText());
         assertEquals("operation:focus",     res.at("/query/operands/1/operation").asText());
-        assertEquals(3,                     res.at("/query/operands/1/classRef/0").asInt());
+        assertEquals(131,                     res.at("/query/operands/1/classRef/0").asInt());
         assertEquals(true,                  res.at("/query/operands/1/operands").isMissingNode());
     }
 
@@ -930,12 +930,12 @@
         assertEquals("operation:relation",  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(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/classRef/0").asInt());
         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:group",         res.at("/query/operands/0/operands/0/operands/0/@type").asText());
         assertEquals("operation:class",     res.at("/query/operands/0/operands/0/operands/0/operation").asText());
-        assertEquals(1,                     res.at("/query/operands/0/operands/0/operands/0/classOut").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/operands/0/operands/0/classOut").asInt());
         assertEquals("korap:span",          res.at("/query/operands/0/operands/0/operands/0/operands/0/@type").asText());
         assertEquals(true,                  res.at("/query/operands/0/operands/0/operands/0/operands/0/key").isMissingNode());
         assertEquals("korap:span",          res.at("/query/operands/0/operands/0/operands/1/@type").asText());
@@ -952,7 +952,7 @@
         assertEquals("operation:relation",  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(1,                     res.at("/query/operands/0/classRef/0").asInt());
+        assertEquals(129,                     res.at("/query/operands/0/classRef/0").asInt());
         assertEquals("korap:group",         res.at("/query/operands/0/operands/0/@type").asText());
         assertEquals("operation:relation",  res.at("/query/operands/0/operands/0/operation").asText());
     }
diff --git a/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java
index 04bd48c..8efd140 100644
--- a/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java
@@ -246,6 +246,13 @@
         res = mapper.readTree(qs.toJSON());
         assertEquals("korap:span", 			res.at("/query/@type").asText());
         assertEquals("s",					res.at("/query/key").asText());
+        
+        query = "<\".*\">";
+        qs.setQuery(query, "poliqarpplus");
+        res = mapper.readTree(qs.toJSON());
+        assertEquals("korap:span",          res.at("/query/@type").asText());
+        assertEquals(".*",                  res.at("/query/key").asText());
+        assertEquals("type:regex",          res.at("/query/type").asText());
 
         query = "<vp>";
         qs.setQuery(query, "poliqarpplus");