diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQuery.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQuery.java
index 63ae367..a54cd46 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQuery.java
@@ -1,15 +1,17 @@
 package de.ids_mannheim.korap.query.serialize;
 
-import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multiset;
+import lombok.Data;
 
 import java.io.IOException;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * @author hanl
@@ -19,7 +21,6 @@
 
 
     private static ObjectMapper serialzer = new ObjectMapper();
-    private JsonFactory factory;
     private CollectionTypes types;
     private List<Map> rq;
     private Multimap<String, String> mfilter;
@@ -34,7 +35,6 @@
         this.rq = new ArrayList<>();
         this.mfilter = ArrayListMultimap.create();
         this.mextension = ArrayListMultimap.create();
-        this.factory = serialzer.getFactory();
         this.types = new CollectionTypes();
     }
 
@@ -255,27 +255,82 @@
 
 
     /**
-     * resolves all queries as equal (hierarchy) AND relations
+     * resolves all queries as equal (hierarchy) AND/OR relations
+     * grouping is not supported!
      *
      * @param queries
      * @return
      */
     private Multimap<String, String> resRel(String queries, RELATION rel) {
         Multimap<String, String> qmap = ArrayListMultimap.create();
-        String[] spl = queries.split(rel.toString());
+        String[] spl = queries.trim().split(rel.toString());
         for (String query : spl) {
-            String[] q = query.split(":");
-            String attr = q[0];
-            String val = q[1];
-            qmap.put(attr, val);
+            String[] q = query.split("=");
+            if (q.length > 1) {
+                String attr = q[0].trim();
+                String val = q[1].trim();
+                qmap.put(attr, val);
+            }
+            //return error when query not well formed
         }
         return qmap;
     }
 
+    /**
+     * resolve relations and allow grouping of attributes: (tc1 and tc1) or (tc3)
+     *
+     * @param queries
+     * @param filter  flag if either filter or extend collection
+     * @return
+     */
+    private void resRelation(String queries, boolean filter) {
+        Pattern p = Pattern.compile("\\(([\\w\\s:]+)\\)");
+        List _fill = new ArrayList();
+        Matcher m = p.matcher(queries);
+        while (m.find()) {
+            String gr = m.group(1);
+            _fill.add(gr);
+            String whole = "(" + gr + ")";
+            int fin = queries.lastIndexOf(whole);
+            String sub = queries.substring(queries.indexOf(whole), queries.lastIndexOf(whole));
+            queries.replace(whole, "");
+        }
+
+    }
+
+    private void v(String queries, boolean filter) {
+        // and exclude sub-groups?? : ((tc=121))
+        Pattern p = Pattern.compile("\\(([\\w\\s=]+)\\)");
+        List _fill = new ArrayList();
+        Matcher m = p.matcher(queries);
+        while (m.find()) {
+            String gr = m.group(1);
+
+        }
+
+    }
+
 
     public void clear() {
         this.rq.clear();
         this.mfilter.clear();
         this.mextension.clear();
     }
+
+
+    private static interface Value {
+    }
+
+    @Data
+    private static class Group implements Value {
+        private RELATION relation;
+        private List<Term> _terms;
+
+    }
+
+    @Data
+    private static class Term implements Value {
+
+        private String _value;
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java
index 403619d..40bd9d7 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusTree.java
@@ -1,388 +1,372 @@
 package de.ids_mannheim.korap.query.serialize;
 
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.antlr.v4.runtime.ANTLRInputStream;
-import org.antlr.v4.runtime.BailErrorStrategy;
-import org.antlr.v4.runtime.CharStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.Lexer;
-import org.antlr.v4.runtime.Parser;
-import org.antlr.v4.runtime.ParserRuleContext;
-import org.antlr.v4.runtime.tree.ParseTree;
-
 import de.ids_mannheim.korap.query.PoliqarpPlusLexer;
 import de.ids_mannheim.korap.query.PoliqarpPlusParser;
 import de.ids_mannheim.korap.util.QueryException;
-
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.tree.ParseTree;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.reflect.Method;
+import java.util.*;
+
 /**
  * Map representation of Poliqarp syntax tree as returned by ANTLR
- * @author joachim
  *
+ * @author joachim
  */
 public class PoliqarpPlusTree extends Antlr4AbstractSyntaxTree {
 
     Logger log = LoggerFactory.getLogger(PoliqarpPlusTree.class);
-	/**
-	 * Top-level map representing the whole request.
-	 */
-	LinkedHashMap<String,Object> requestMap = new LinkedHashMap<String,Object>();
-	/**
-	 * Keeps track of open node categories
-	 */
-	LinkedList<String> openNodeCats = new LinkedList<String>();
-	/**
-	 * Flag that indicates whether token fields or meta fields are currently being processed
-	 */
-	boolean inMeta = false;
-	/**
-	 * Flag that indicates whether a cq_segment is to be ignored (e.g. when it is empty, is followed directly by only a spanclass and has no other children etc...). 
-	 */
-	boolean ignoreCq_segment = false;
-	/**
-	 *  Flag that indicates whether a cq_segments element is quantified by an occ element.
-	 */
-	boolean cqHasOccSibling = false;
-	/**
-	 *  Flag that indicates whether a cq_segments' children are quantified by an occ element.
-	 */
-	boolean cqHasOccChild = false;
-	/**
-	 * Flag for negation of complete field
-	 */
-	boolean negField = false;
-	/**
-	 * Flag that indicates whether subsequent element is to be aligned.
-	 */
-	boolean alignNext = false;
-	/**
-	 * Flag that indicates whether current element has been aligned.
-	 */
-	boolean isAligned = false;
-	/**
-	 * Indicates a sequence which has an align operator as its child. Needed for deciding
-	 * when to close the align group object.
-	 */
+    /**
+     * Top-level map representing the whole request.
+     */
+    LinkedHashMap<String, Object> requestMap = new LinkedHashMap<String, Object>();
+    /**
+     * Keeps track of open node categories
+     */
+    LinkedList<String> openNodeCats = new LinkedList<String>();
+    /**
+     * Flag that indicates whether token fields or meta fields are currently being processed
+     */
+    boolean inMeta = false;
+    /**
+     * Flag that indicates whether a cq_segment is to be ignored (e.g. when it is empty, is followed directly by only a spanclass and has no other children etc...).
+     */
+    boolean ignoreCq_segment = false;
+    /**
+     * Flag that indicates whether a cq_segments element is quantified by an occ element.
+     */
+    boolean cqHasOccSibling = false;
+    /**
+     * Flag that indicates whether a cq_segments' children are quantified by an occ element.
+     */
+    boolean cqHasOccChild = false;
+    /**
+     * Flag for negation of complete field
+     */
+    boolean negField = false;
+    /**
+     * Flag that indicates whether subsequent element is to be aligned.
+     */
+    boolean alignNext = false;
+    /**
+     * Flag that indicates whether current element has been aligned.
+     */
+    boolean isAligned = false;
+    /**
+     * Indicates a sequence which has an align operator as its child. Needed for deciding
+     * when to close the align group object.
+     */
 //	ParseTree alignedSequence = null;
-	/**
-	 * Parser object deriving the ANTLR parse tree.
-	 */
-	Parser parser;
-	/**
-	 * Keeps track of all visited nodes in a tree
-	 */
-	List<ParseTree> visited = new ArrayList<ParseTree>();
+    /**
+     * Parser object deriving the ANTLR parse tree.
+     */
+    Parser parser;
+    /**
+     * Keeps track of all visited nodes in a tree
+     */
+    List<ParseTree> visited = new ArrayList<ParseTree>();
 
-	/**
-	 * Keeps track of active fields (like 'base=foo').
-	 */
-	LinkedList<ArrayList<Object>> fieldStack = new LinkedList<ArrayList<Object>>();
-	/**
-	 * Keeps track of active tokens.
-	 */
-	LinkedList<LinkedHashMap<String,Object>> tokenStack = new LinkedList<LinkedHashMap<String,Object>>();
-	/**
-	 * 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 active object.
-	 */
-	LinkedList<LinkedHashMap<String,Object>> objectStack = new LinkedList<LinkedHashMap<String,Object>>();
-	/**
-	 * Marks the object to which following occurrence information is to be added.
-	 */
-	LinkedHashMap<String,Object> curOccGroup = new LinkedHashMap<String,Object>();
-	/**
-	 * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
-	 */
-	LinkedList<Integer> objectsToPop = new LinkedList<Integer>();
-	/**
-	 * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
-	 */
-	LinkedList<Integer> tokensToPop = new LinkedList<Integer>();
-	/**
-	 * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
-	 */
-	LinkedList<Integer> fieldsToPop = new LinkedList<Integer>();
-	/**
-	 * If true, print debug statements
-	 */
-	public static boolean verbose = false;
-	/**
-	 * Index of the current child of its parent (needed for relating occ elements to their operands).
-	 */
-	int curChildIndex = 0;
-	/**
-	 * 
-	 */
-	Integer stackedObjects = 0;
-	Integer stackedTokens= 0;
-	Integer stackedFields = 0;
-	
-	
-	/**
-	 * Most centrally, this class maintains a set of nested maps and lists which represent the JSON tree, which is built by the JSON serialiser
-	 * on basis of the {@link #requestMap} at the root of the tree. 
-	 * <br/>
-	 * The class further maintains a set of stacks which effectively keep track of which objects to embed in which containing objects. 
-	 * 
-	 * @param query The syntax tree as returned by ANTLR
-	 * @throws QueryException 
-	 */
-	public PoliqarpPlusTree(String query) throws QueryException {
-		try {
-			process(query); 
-		} catch (NullPointerException e) {
-			if (query.contains(" ")) {
-				System.err.println("Warning: It seems like your query contains illegal whitespace characters. Trying again with whitespaces removed...");
-				query = query.replaceAll(" ", "");
-				process(query);
-			} else {
-				throw new QueryException("Error handling query.");
-			}
-		}
-		System.out.println(">>> "+requestMap.get("query")+" <<<");
+    /**
+     * Keeps track of active fields (like 'base=foo').
+     */
+    LinkedList<ArrayList<Object>> fieldStack = new LinkedList<ArrayList<Object>>();
+    /**
+     * Keeps track of active tokens.
+     */
+    LinkedList<LinkedHashMap<String, Object>> tokenStack = new LinkedList<LinkedHashMap<String, Object>>();
+    /**
+     * 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 active object.
+     */
+    LinkedList<LinkedHashMap<String, Object>> objectStack = new LinkedList<LinkedHashMap<String, Object>>();
+    /**
+     * Marks the object to which following occurrence information is to be added.
+     */
+    LinkedHashMap<String, Object> curOccGroup = new LinkedHashMap<String, Object>();
+    /**
+     * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
+     */
+    LinkedList<Integer> objectsToPop = new LinkedList<Integer>();
+    /**
+     * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
+     */
+    LinkedList<Integer> tokensToPop = new LinkedList<Integer>();
+    /**
+     * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)}
+     */
+    LinkedList<Integer> fieldsToPop = new LinkedList<Integer>();
+    /**
+     * If true, print debug statements
+     */
+    public static boolean verbose = false;
+    /**
+     * Index of the current child of its parent (needed for relating occ elements to their operands).
+     */
+    int curChildIndex = 0;
+    /**
+     *
+     */
+    Integer stackedObjects = 0;
+    Integer stackedTokens = 0;
+    Integer stackedFields = 0;
+
+
+    /**
+     * Most centrally, this class maintains a set of nested maps and lists which represent the JSON tree, which is built by the JSON serialiser
+     * on basis of the {@link #requestMap} at the root of the tree.
+     * <br/>
+     * The class further maintains a set of stacks which effectively keep track of which objects to embed in which containing objects.
+     *
+     * @param query The syntax tree as returned by ANTLR
+     * @throws QueryException
+     */
+    public PoliqarpPlusTree(String query) throws QueryException {
+        try {
+            process(query);
+        } catch (NullPointerException e) {
+            if (query.contains(" ")) {
+                System.err.println("Warning: It seems like your query contains illegal whitespace characters. Trying again with whitespaces removed...");
+                query = query.replaceAll(" ", "");
+                process(query);
+            } else {
+                throw new QueryException("Error handling query.");
+            }
+        }
+        System.out.println(">>> " + requestMap.get("query") + " <<<");
         log.info(">>> " + requestMap.get("query") + " <<<");
-	}
+    }
 
-	@Override
-	public Map<String, Object> getRequestMap() {
-		return requestMap;
-	}
-	
-	@Override
-	public void process(String query) throws QueryException {
-		ParseTree tree = null;
-		try {
-			tree = parsePoliqarpQuery(query);
-		} catch (QueryException e) {
-			try {
-				tree = parsePoliqarpQuery(query.replaceAll(" ", ""));
-			} catch (QueryException e1) {
-				System.exit(1);
-			}
-		}
-		super.parser = this.parser;
-		System.out.println("Processing PoliqarpPlus");
-		requestMap.put("@context", "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld");
+    @Override
+    public Map<String, Object> getRequestMap() {
+        return requestMap;
+    }
+
+    @Override
+    public void process(String query) throws QueryException {
+        ParseTree tree = null;
+        try {
+            tree = parsePoliqarpQuery(query);
+        } catch (QueryException e) {
+            // if the second time query could not be parsed, throw exception!
+            tree = parsePoliqarpQuery(query.replaceAll(" ", ""));
+        }
+        super.parser = this.parser;
+        System.out.println("Processing PoliqarpPlus");
+        requestMap.put("@context", "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld");
 //		prepareContext(requestMap);
-		processNode(tree);
-	}
-	
-	/**
-	 * Recursively calls itself with the children of the currently active node, traversing the tree nodes in a top-down, depth-first fashion. 
-	 * A list is maintained that contains all visited nodes 
-	 * in case they have been directly addressed by its (grand-/grand-grand-/...) parent node, such that some processing time is saved, as these node will
-	 * not be processed. This method is effectively a list of if-statements that are responsible for treating the different node types correctly and filling the
-	 * respective maps/lists.
-	 *
-	 * @param node The currently processed node. The process(String query) method calls this method with the root.
-	 * @throws QueryException 
-	 */
-	@SuppressWarnings("unchecked")
-	private void processNode(ParseTree node) throws QueryException {
-		// Top-down processing
-		if (visited.contains(node)) return;
-		else visited.add(node);
-		
-		if (alignNext) {
-			alignNext=false;
-			isAligned=true;
-		}
-		
-		String nodeCat = getNodeCat(node);
-		openNodeCats.push(nodeCat);
-		
-		stackedObjects = 0;
-		stackedTokens= 0;
-		stackedFields = 0;
-		
-		if (verbose) {
-			System.err.println(" "+objectStack);
+        processNode(tree);
+    }
+
+    /**
+     * Recursively calls itself with the children of the currently active node, traversing the tree nodes in a top-down, depth-first fashion.
+     * A list is maintained that contains all visited nodes
+     * in case they have been directly addressed by its (grand-/grand-grand-/...) parent node, such that some processing time is saved, as these node will
+     * not be processed. This method is effectively a list of if-statements that are responsible for treating the different node types correctly and filling the
+     * respective maps/lists.
+     *
+     * @param node The currently processed node. The process(String query) method calls this method with the root.
+     * @throws QueryException
+     */
+    @SuppressWarnings("unchecked")
+    private void processNode(ParseTree node) throws QueryException {
+        // Top-down processing
+        if (visited.contains(node)) return;
+        else visited.add(node);
+
+        if (alignNext) {
+            alignNext = false;
+            isAligned = true;
+        }
+
+        String nodeCat = getNodeCat(node);
+        openNodeCats.push(nodeCat);
+
+        stackedObjects = 0;
+        stackedTokens = 0;
+        stackedFields = 0;
+
+        if (verbose) {
+            System.err.println(" " + objectStack);
 //			System.err.println(" "+tokenStack);
-			System.out.println(openNodeCats);
-		}
-		
+            System.out.println(openNodeCats);
+        }
+
 
 		/*
-		 ****************************************************************
+         ****************************************************************
 		 **************************************************************** 
 		 * 			Processing individual node categories  				*
 		 ****************************************************************
 		 ****************************************************************
 		 */
 
-		// cq_segments/sq_segments: token group
-		if (nodeCat.equals("cq_segments") || nodeCat.equals("sq_segments")) {
-			cqHasOccSibling = false;
-			cqHasOccChild = false;
-			// disregard empty segments in simple queries (parsed by ANTLR as empty cq_segments) 
-			ignoreCq_segment = (node.getChildCount() == 1 && (node.getChild(0).toStringTree(parser).equals(" ") || getNodeCat(node.getChild(0)).equals("spanclass") || getNodeCat(node.getChild(0)).equals("position")));
-			// ignore this node if it only serves as an aligned sequence container
-			if (node.getChildCount()>1) {
-				if (getNodeCat(node.getChild(1)).equals("cq_segments") && hasChild(node.getChild(1), "alignment")) {
+        // cq_segments/sq_segments: token group
+        if (nodeCat.equals("cq_segments") || nodeCat.equals("sq_segments")) {
+            cqHasOccSibling = false;
+            cqHasOccChild = false;
+            // disregard empty segments in simple queries (parsed by ANTLR as empty cq_segments)
+            ignoreCq_segment = (node.getChildCount() == 1 && (node.getChild(0).toStringTree(parser).equals(" ") || getNodeCat(node.getChild(0)).equals("spanclass") || getNodeCat(node.getChild(0)).equals("position")));
+            // ignore this node if it only serves as an aligned sequence container
+            if (node.getChildCount() > 1) {
+                if (getNodeCat(node.getChild(1)).equals("cq_segments") && hasChild(node.getChild(1), "alignment")) {
 //				if (getNodeCat(node.getChild(0)).equals("align")) {	
-					ignoreCq_segment = true;
-				}
-			}
-			if (!ignoreCq_segment) {
-				LinkedHashMap<String,Object> sequence = new LinkedHashMap<String,Object>();
-				// Step 0:  cq_segments has 'occ' child -> introduce group as super group to the sequence/token/group
-				// this requires creating a group and inserting it at a suitable place
-				if (node.getParent().getChildCount()>curChildIndex+2 && getNodeCat(node.getParent().getChild(curChildIndex+2)).equals("occ")) {
-					cqHasOccSibling = true;
-					createOccGroup(node);
-				}
-				if (getNodeCat(node.getChild(node.getChildCount()-1)).equals("occ")) {
-					cqHasOccChild = true;
-				}
-				// Step I: decide type of element (one or more elements? -> token or sequence)
-				// take into account a possible 'occ' child with accompanying parantheses, therefore 3 extra children
-				int occExtraChildren = cqHasOccChild ? 3:0;
-				if (node.getChildCount()>1 + occExtraChildren) {
-					ParseTree emptySegments = getFirstChildWithCat(node, "empty_segments");
-					if (emptySegments != null && emptySegments != node.getChild(0)) {
-						String[] minmax = parseEmptySegments(emptySegments);
-						Integer min = Integer.parseInt(minmax[0]);
-						Integer max = Integer.parseInt(minmax[1]);
-						sequence.put("@type", "korap:group");
-						sequence.put("operation", "operation:sequence");
-						sequence.put("inOrder", true);
-						ArrayList<Object> constraint = new ArrayList<Object>(); 
-						sequence.put("distances", constraint);
-						ArrayList<Object> sequenceOperands = new ArrayList<Object>();
-						sequence.put("operands", sequenceOperands);
-						objectStack.push(sequence);
-						stackedObjects++;
-						LinkedHashMap<String, Object> distMap = new LinkedHashMap<String, Object>();
-						constraint.add(distMap);
-						distMap.put("@type", "korap:distance");
-						distMap.put("key", "w");
-						distMap.put("min", min);
-						distMap.put("max", max);
-					} else {
-						sequence.put("@type", "korap:group");
-						sequence.put("operation", "operation:"+"sequence");
-						ArrayList<Object> sequenceOperands = new ArrayList<Object>();
-						if (emptySegments != null) {
-							String[] minmax = parseEmptySegments(emptySegments);
-							Integer min = Integer.parseInt(minmax[0]);
-							Integer max = Integer.parseInt(minmax[1]);
-							sequence.put("offset-min", min-1);
-							sequence.put("offset-max", max-1);
-						}
-						sequence.put("operands", sequenceOperands);
-						objectStack.push(sequence);
-						stackedObjects++;
-					}
-				} else {
-					// if only child, make the sequence a mere token...
-					// ... but only if it has a real token/element beneath it
-					if (! isContainerOnly(node)) {
-						sequence.put("@type", "korap:token");
-						tokenStack.push(sequence);
-						stackedTokens++;
-						objectStack.push(sequence);
-						stackedObjects++;
-					// else, it's a group (with shrink()/spanclass/align... as child)
-					} else {
+                    ignoreCq_segment = true;
+                }
+            }
+            if (!ignoreCq_segment) {
+                LinkedHashMap<String, Object> sequence = new LinkedHashMap<String, Object>();
+                // Step 0:  cq_segments has 'occ' child -> introduce group as super group to the sequence/token/group
+                // this requires creating a group and inserting it at a suitable place
+                if (node.getParent().getChildCount() > curChildIndex + 2 && getNodeCat(node.getParent().getChild(curChildIndex + 2)).equals("occ")) {
+                    cqHasOccSibling = true;
+                    createOccGroup(node);
+                }
+                if (getNodeCat(node.getChild(node.getChildCount() - 1)).equals("occ")) {
+                    cqHasOccChild = true;
+                }
+                // Step I: decide type of element (one or more elements? -> token or sequence)
+                // take into account a possible 'occ' child with accompanying parantheses, therefore 3 extra children
+                int occExtraChildren = cqHasOccChild ? 3 : 0;
+                if (node.getChildCount() > 1 + occExtraChildren) {
+                    ParseTree emptySegments = getFirstChildWithCat(node, "empty_segments");
+                    if (emptySegments != null && emptySegments != node.getChild(0)) {
+                        String[] minmax = parseEmptySegments(emptySegments);
+                        Integer min = Integer.parseInt(minmax[0]);
+                        Integer max = Integer.parseInt(minmax[1]);
+                        sequence.put("@type", "korap:group");
+                        sequence.put("operation", "operation:sequence");
+                        sequence.put("inOrder", true);
+                        ArrayList<Object> constraint = new ArrayList<Object>();
+                        sequence.put("distances", constraint);
+                        ArrayList<Object> sequenceOperands = new ArrayList<Object>();
+                        sequence.put("operands", sequenceOperands);
+                        objectStack.push(sequence);
+                        stackedObjects++;
+                        LinkedHashMap<String, Object> distMap = new LinkedHashMap<String, Object>();
+                        constraint.add(distMap);
+                        distMap.put("@type", "korap:distance");
+                        distMap.put("key", "w");
+                        distMap.put("min", min);
+                        distMap.put("max", max);
+                    } else {
+                        sequence.put("@type", "korap:group");
+                        sequence.put("operation", "operation:" + "sequence");
+                        ArrayList<Object> sequenceOperands = new ArrayList<Object>();
+                        if (emptySegments != null) {
+                            String[] minmax = parseEmptySegments(emptySegments);
+                            Integer min = Integer.parseInt(minmax[0]);
+                            Integer max = Integer.parseInt(minmax[1]);
+                            sequence.put("offset-min", min - 1);
+                            sequence.put("offset-max", max - 1);
+                        }
+                        sequence.put("operands", sequenceOperands);
+                        objectStack.push(sequence);
+                        stackedObjects++;
+                    }
+                } else {
+                    // if only child, make the sequence a mere token...
+                    // ... but only if it has a real token/element beneath it
+                    if (!isContainerOnly(node)) {
+                        sequence.put("@type", "korap:token");
+                        tokenStack.push(sequence);
+                        stackedTokens++;
+                        objectStack.push(sequence);
+                        stackedObjects++;
+                        // else, it's a group (with shrink()/spanclass/align... as child)
+                    } else {
 //						sequence.put("@type", "korap:group");
 //						objectStack.push(sequence);
 //						stackedObjects++;
-					}
-				}
-				// Step II: decide where to put this element 
-				// check if this is an argument for a containing occurrence group (see step 0)
-				if (cqHasOccSibling) {
-					ArrayList<Object> topGroupOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-					topGroupOperands.add(sequence);
-				// ...if not modified by occurrence, put into appropriate super object
-				} else {
-					if (openNodeCats.get(1).equals("query")) {
-						// cq_segment is top query node
-						if (node.getParent().getChildCount()==1) {
-							// only child
-							requestMap.put("query", sequence);
-						} else {
-							// not an only child, need to create containing sequence
-							if (node.getParent().getChild(0).equals(node)) {
-								// if first child, create containing sequence and embed there
-								LinkedHashMap<String,Object> superSequence = new LinkedHashMap<String,Object>();
-								superSequence.put("@type", "korap:group");
-								superSequence.put("operation", "operation:"+"sequence");
-								ArrayList<Object> operands = new ArrayList<Object>();
-								superSequence.put("operands", operands);
-								operands.add(sequence);
-								requestMap.put("query", superSequence);
-								objectStack.push(superSequence); // add at 2nd position to keep current cq_segment accessible
-								stackedObjects++;
-							} else {
-								// if not first child, add to previously created parent sequence
-								ArrayList<Object> topSequenceOperands;
-								try {
-									topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-								} catch (IndexOutOfBoundsException e) {
-									// Normally, the current element has been added to the object stack, so the try-block works fine.
-									// In some cases however, the element is not added (see ultimate else-block in Step I), and we need a 
-									// fallback to the first element in the object stack.
-									topSequenceOperands = (ArrayList<Object>) objectStack.get(0).get("operands");
-								}
-								
-								topSequenceOperands.add(sequence);
-							}
-						}
-					} else if (!objectStack.isEmpty()){
-						// embed in super sequence
-						ArrayList<Object> topSequenceOperands;
-						if (! isContainerOnly(node)) {
-							try {
-								topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-								topSequenceOperands.add(sequence);
-							} catch (IndexOutOfBoundsException e) {
+                    }
+                }
+                // Step II: decide where to put this element
+                // check if this is an argument for a containing occurrence group (see step 0)
+                if (cqHasOccSibling) {
+                    ArrayList<Object> topGroupOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                    topGroupOperands.add(sequence);
+                    // ...if not modified by occurrence, put into appropriate super object
+                } else {
+                    if (openNodeCats.get(1).equals("query")) {
+                        // cq_segment is top query node
+                        if (node.getParent().getChildCount() == 1) {
+                            // only child
+                            requestMap.put("query", sequence);
+                        } else {
+                            // not an only child, need to create containing sequence
+                            if (node.getParent().getChild(0).equals(node)) {
+                                // if first child, create containing sequence and embed there
+                                LinkedHashMap<String, Object> superSequence = new LinkedHashMap<String, Object>();
+                                superSequence.put("@type", "korap:group");
+                                superSequence.put("operation", "operation:" + "sequence");
+                                ArrayList<Object> operands = new ArrayList<Object>();
+                                superSequence.put("operands", operands);
+                                operands.add(sequence);
+                                requestMap.put("query", superSequence);
+                                objectStack.push(superSequence); // add at 2nd position to keep current cq_segment accessible
+                                stackedObjects++;
+                            } else {
+                                // if not first child, add to previously created parent sequence
+                                ArrayList<Object> topSequenceOperands;
+                                try {
+                                    topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                                } catch (IndexOutOfBoundsException e) {
+                                    // Normally, the current element has been added to the object stack, so the try-block works fine.
+                                    // In some cases however, the element is not added (see ultimate else-block in Step I), and we need a
+                                    // fallback to the first element in the object stack.
+                                    topSequenceOperands = (ArrayList<Object>) objectStack.get(0).get("operands");
+                                }
+
+                                topSequenceOperands.add(sequence);
+                            }
+                        }
+                    } else if (!objectStack.isEmpty()) {
+                        // embed in super sequence
+                        ArrayList<Object> topSequenceOperands;
+                        if (!isContainerOnly(node)) {
+                            try {
+                                topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                                topSequenceOperands.add(sequence);
+                            } catch (IndexOutOfBoundsException e) {
 //								topSequenceOperands = (ArrayList<Object>) objectStack.get(0).get("operands");
-							}
-						}
-						
-						
-					}
-				}
-			}
-		}
-		
-		// cq_segment
-		if (nodeCat.equals("cq_segment")) {
-			int onTopOfObjectStack = 0;
-			// Step I: determine whether to create new token or get token from the stack (if added by cq_segments)
-			LinkedHashMap<String, Object> token;
-			if (tokenStack.isEmpty()) {
-				token = new LinkedHashMap<String, Object>();
-				tokenStack.push(token);
-				stackedTokens++;
-				// do this only if token is newly created, otherwise it'll be in objectStack twice
-				objectStack.push(token);
-				onTopOfObjectStack = 1;
-				stackedObjects++;
-			} else {
-				// in case cq_segments has already added the token
-				token = tokenStack.getFirst();
-			}
-			curToken = token;
-			// Step II: start filling object and add to containing sequence
-			token.put("@type", "korap:token");
-			// add token to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the values from "field")
-			// take into account a possible 'occ' child
-			if (node.getParent().getChildCount()>1) {				
-				if (node.getText().equals("[]")) {
+                            }
+                        }
+
+
+                    }
+                }
+            }
+        }
+
+        // cq_segment
+        if (nodeCat.equals("cq_segment")) {
+            int onTopOfObjectStack = 0;
+            // Step I: determine whether to create new token or get token from the stack (if added by cq_segments)
+            LinkedHashMap<String, Object> token;
+            if (tokenStack.isEmpty()) {
+                token = new LinkedHashMap<String, Object>();
+                tokenStack.push(token);
+                stackedTokens++;
+                // do this only if token is newly created, otherwise it'll be in objectStack twice
+                objectStack.push(token);
+                onTopOfObjectStack = 1;
+                stackedObjects++;
+            } else {
+                // in case cq_segments has already added the token
+                token = tokenStack.getFirst();
+            }
+            curToken = token;
+            // Step II: start filling object and add to containing sequence
+            token.put("@type", "korap:token");
+            // add token to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the values from "field")
+            // take into account a possible 'occ' child
+            if (node.getParent().getChildCount() > 1) {
+                if (node.getText().equals("[]")) {
 //					LinkedHashMap<String, Object> sequence  = objectStack.get(onTopOfObjectStack);
 //					String offsetStr = (String) sequence.get("offset");
 //					if (offsetStr == null) {
@@ -392,446 +376,446 @@
 //						sequence.put("offset", offset+1);
 //					}
 //					
-				} else {
-					ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(onTopOfObjectStack).get("operands");
-					topSequenceOperands.add(token);
-				}
-			}
-		}
-		
-		// cq_segment modified by occurrence
-		if (nodeCat.equals("cq_seg_occ")) {
-			LinkedHashMap<String,Object> group = new LinkedHashMap<String,Object>();
-			curOccGroup = group;
-			group.put("@type", "korap:group");
-			group.put("operands", new ArrayList<Object>());
-			objectStack.push(group);
-			stackedObjects++;
-			// add group to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the values from "field")
-			// take into account a possible 'occ' child
-//			if (node.getParent().getChildCount()>1) {
-			if (objectStack.size()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(group);
-			} else {
-				requestMap.put("query", group);
-			}
-		}
+                } else {
+                    ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(onTopOfObjectStack).get("operands");
+                    topSequenceOperands.add(token);
+                }
+            }
+        }
 
-		// disjoint cq_segments, like ([base=foo][base=bar])|[base=foobar]
-		if (nodeCat.equals("cq_disj_segments")) {
-			LinkedHashMap<String,Object> disjunction = new LinkedHashMap<String,Object>();
-			objectStack.push(disjunction);
-			stackedObjects++;
-			ArrayList<Object> disjOperands = new ArrayList<Object>();
-			disjunction.put("@type", "korap:group");
-			disjunction.put("operation", "operation:"+"or");
-			disjunction.put("operands", disjOperands);
-			// decide where to put the disjunction
-			if (openNodeCats.get(1).equals("query")) {
-				requestMap.put("query", disjunction);	
-			} else if (openNodeCats.get(1).equals("cq_segments")) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(disjunction);
-			}
-		}
-		
-		// field element (outside meta)
-		if (nodeCat.equals("field")) {
-			LinkedHashMap<String,Object> fieldMap = new LinkedHashMap<String,Object>();
-			// Step I: extract info
-			String layer = "";
-			String foundry = null;
-			String value = null;
-			String key = null;
-			ParseTree fieldNameNode = node.getChild(0);
-			if (fieldNameNode.getChildCount() == 1) {
-				layer = fieldNameNode.getChild(0).toStringTree(parser);   //e.g. (field_name base) (field_op !=) (re_query "bar*")
-			} else if (fieldNameNode.getChildCount() == 3) {
-				// layer is indicated, merge layer and field name (0th and 2nd children, 1st is "/")
-				foundry = fieldNameNode.getChild(0).toStringTree(parser);
-				layer = fieldNameNode.getChild(2).toStringTree(parser);
+        // cq_segment modified by occurrence
+        if (nodeCat.equals("cq_seg_occ")) {
+            LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+            curOccGroup = group;
+            group.put("@type", "korap:group");
+            group.put("operands", new ArrayList<Object>());
+            objectStack.push(group);
+            stackedObjects++;
+            // add group to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the values from "field")
+            // take into account a possible 'occ' child
+//			if (node.getParent().getChildCount()>1) {
+            if (objectStack.size() > 1) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(group);
+            } else {
+                requestMap.put("query", group);
+            }
+        }
+
+        // disjoint cq_segments, like ([base=foo][base=bar])|[base=foobar]
+        if (nodeCat.equals("cq_disj_segments")) {
+            LinkedHashMap<String, Object> disjunction = new LinkedHashMap<String, Object>();
+            objectStack.push(disjunction);
+            stackedObjects++;
+            ArrayList<Object> disjOperands = new ArrayList<Object>();
+            disjunction.put("@type", "korap:group");
+            disjunction.put("operation", "operation:" + "or");
+            disjunction.put("operands", disjOperands);
+            // decide where to put the disjunction
+            if (openNodeCats.get(1).equals("query")) {
+                requestMap.put("query", disjunction);
+            } else if (openNodeCats.get(1).equals("cq_segments")) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(disjunction);
+            }
+        }
+
+        // field element (outside meta)
+        if (nodeCat.equals("field")) {
+            LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>();
+            // Step I: extract info
+            String layer = "";
+            String foundry = null;
+            String value = null;
+            String key = null;
+            ParseTree fieldNameNode = node.getChild(0);
+            if (fieldNameNode.getChildCount() == 1) {
+                layer = fieldNameNode.getChild(0).toStringTree(parser);   //e.g. (field_name base) (field_op !=) (re_query "bar*")
+            } else if (fieldNameNode.getChildCount() == 3) {
+                // layer is indicated, merge layer and field name (0th and 2nd children, 1st is "/")
+                foundry = fieldNameNode.getChild(0).toStringTree(parser);
+                layer = fieldNameNode.getChild(2).toStringTree(parser);
 //			} else if (fieldNameNode.getChildCount() == 5) {
 //				// layer and value are indicated
 //				foundry = fieldNameNode.getChild(0).toStringTree(poliqarpParser);
 //				layer = fieldNameNode.getChild(2).toStringTree(poliqarpParser);
 //				value = fieldNameNode.getChild(4).toStringTree(poliqarpParser);
-			}	
-			if (hasChild(node, "key")) {
-				ParseTree keyNode = getFirstChildWithCat(node, "key");
-				key = keyNode.getChild(0).toStringTree(parser);
-			}
-			
-			String relation = node.getChild(1).getChild(0).toStringTree(parser);
-			if (negField) {
-				if (relation.startsWith("!")) {
-					relation = relation.substring(1);
-				} else {
-					relation = "!"+relation;
-				}
-			}
-			if (relation.equals("=")) {
-				relation="eq";
-			} else 	if (relation.equals("!=")) {
-				relation="ne";
-			}
-			
-			ParseTree valNode;
-			if (hasChild(node, "key")) valNode = node.getChild(3);
-			else valNode = node.getChild(2);
-			String valType = getNodeCat(valNode);
-			fieldMap.put("@type", "korap:term");
-			if (valType.equals("simple_query")) {
-				value = valNode.getChild(0).getChild(0).toStringTree(parser);   //e.g. (simple_query (sq_segment foo))
-			} else if (valType.equals("re_query")) {
-				value = valNode.getChild(0).toStringTree(parser); 				//e.g. (re_query "bar*")
-				fieldMap.put("type", "type:regex");
-				value = value.substring(1,value.length()-1); //remove trailing quotes
-			}
-			if (key == null) {
-				fieldMap.put("key", value);
-			} else {
-				fieldMap.put("key", key);
-				fieldMap.put("value", value);
-			}
-			
-			if (layer.equals("base")) layer="lemma";
-			fieldMap.put("layer", layer);
-			if (foundry != null) fieldMap.put("foundry", foundry);
-			
-			fieldMap.put("match", "match:"+relation);
-			// Step II: decide where to put the field map (as the only value of a token or the meta filter or as a part of a group in case of coordinated fields)
-			if (fieldStack.isEmpty()) {
-				if (!inMeta) {
-					tokenStack.getFirst().put("wrap", fieldMap);
-				} else {
-					((HashMap<String, Object>) requestMap.get("meta")).put("key", fieldMap);
-				}
-			} else {
-				fieldStack.getFirst().add(fieldMap);
-			}
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(1));
-			visited.add(node.getChild(2));
-			if (key != null) visited.add(node.getChild(3));
-		}
-		
-		if (nodeCat.equals("neg_field") || nodeCat.equals("neg_field_group")) {
-			negField=!negField;
-		}
-		
-		// conj_field serves for both conjunctions and disjunctions
-		if (nodeCat.equals("conj_field")) {
-			LinkedHashMap<String,Object> group = new LinkedHashMap<String,Object>(); 
-			
-			group.put("@type", "korap:termGroup");
-			
-			// Step I: get operator (& or |)
-			ParseTree operatorNode = node.getChild(1).getChild(0);
-			String operator = getNodeCat(operatorNode);
-			String relation = operator.equals("&") ? "and" : "or";
-			if (negField) {
-				relation = relation.equals("or") ? "and": "or";
-			}
-			group.put("relation", "relation:" + relation);
-			ArrayList<Object> groupOperands = new ArrayList<Object>();
-			group.put("operands", groupOperands);
-			fieldStack.push(groupOperands);
-			stackedFields++;
-			// Step II: decide where to put the group (directly under token or in top meta filter section or embed in super group)
-			if (openNodeCats.get(1).equals("cq_segment")) {
-				tokenStack.getFirst().put("wrap", group);
-			} else if (openNodeCats.get(1).equals("meta_field_group")) {
-				((HashMap<String, Object>) requestMap.get("meta")).put("key", group);
-			} else if (openNodeCats.get(2).equals("conj_field")) {
-				fieldStack.get(1).add(group);
-			} else {
-				tokenStack.getFirst().put("wrap", group);
-			}
-			// skip the operator
-			visited.add(node.getChild(1));
-		}
-		
-		
-		if (nodeCat.equals("sq_segment")) {
-			// Step I: determine whether to create new token or get token from the stack (if added by cq_segments)
-			LinkedHashMap<String, Object> token;
-			if (tokenStack.isEmpty()) {
-				token = new LinkedHashMap<String, Object>();
-				tokenStack.push(token);
-				stackedTokens++;
-			} else {
-				// in case sq_segments has already added the token
-				token = tokenStack.getFirst();
-			}
-			curToken = token;
-			objectStack.push(token);
-			stackedObjects++;
-			// Step II: fill object (token values) and put into containing sequence
-			if (node.getText().equals("[]")) {
-				
-			} else {
-				token.put("@type", "korap:token");
-				String word = node.getChild(0).toStringTree(parser);
-				LinkedHashMap<String,Object> tokenValues = new LinkedHashMap<String,Object>();
-				token.put("wrap", tokenValues);
-				tokenValues.put("@type", "korap:term");
-				tokenValues.put("key", word);
-				tokenValues.put("layer", "orth");
-				tokenValues.put("match", "match:"+"eq");
-				// add token to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the values from "field")
-				if (node.getParent().getChildCount()>1) {
-					ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-					topSequenceOperands.add(token);
-				}
-			}
-			visited.add(node.getChild(0));
-		}
-		
-		if (nodeCat.equals("re_query")) {
-			LinkedHashMap<String,Object> reQuery = new LinkedHashMap<String,Object>();
-			reQuery.put("type", "type:regex");
-			String regex = node.getChild(0).toStringTree(parser);
-			reQuery.put("key", regex);
-			reQuery.put("match", "match:"+"eq");
-			
-			// if in field, regex was already added there
-			if (!openNodeCats.get(1).equals("field")) {
-				LinkedHashMap<String,Object> token = new LinkedHashMap<String,Object>();
-				token.put("@type", "korap:token");
-				token.put("wrap", reQuery);
-				reQuery.put("@type", "korap:term");
-				
-				if (openNodeCats.get(1).equals("query")) {
-					requestMap.put("query", token);
-				} else {
-					ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-					topSequenceOperands.add(token);
-				}
-			} 
-		}
-		
-		if (nodeCat.equals("alignment")) {
-			alignNext = true;
-			LinkedHashMap<String,Object> alignGroup = new LinkedHashMap<String,Object>();
-			// push but don't increase the stackedObjects counter in order to keep this
-			// group open until the mother cq_segments node will be closed, since the
-			// operands are siblings of this align node rather than children, i.e. the group
-			// would be removed from the stack before seeing its operands.
-			objectStack.push(alignGroup);
-			stackedObjects++;
-			// Step I: get info
-			// fill group
-			alignGroup.put("@type", "korap:group");
-			alignGroup.put("alignment", "left");
-			alignGroup.put("operands", new ArrayList<Object>());
-			// Step II: decide where to put the group
-			// add group to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the relevant info)
-			if (node.getParent().getChildCount()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(alignGroup);
-			} else if (openNodeCats.get(2).equals("query")) {
-				requestMap.put("query", alignGroup);	
-			} else {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(alignGroup); 
-			}
-			visited.add(node.getChild(0));
-		}
-		
-		if (nodeCat.equals("element")) {
-			// Step I: determine whether to create new token or get token from the stack (if added by cq_segments)
-			LinkedHashMap<String, Object> elem;
-			if (tokenStack.isEmpty()) {
-				elem = new LinkedHashMap<String, Object>();
-			} else {
-				// in case sq_segments has already added the token
-				elem = tokenStack.getFirst();
-			}
-			curToken = elem;
-			objectStack.push(elem);
-			stackedObjects++;
-			// Step II: fill object (token values) and put into containing sequence
-			elem.put("@type", "korap:span");
-			int valChildIdx = node.getChildCount()-2; // closing '>' is last child
-			String value = node.getChild(valChildIdx).toStringTree(parser);
-			ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
-			ParseTree layerNode = getFirstChildWithCat(node, "layer");
-			if (foundryNode != null) {
-				elem.put("foundry", foundryNode.getChild(0).toStringTree(parser));
-			}
-			if (layerNode != null) {
-				elem.put("layer", layerNode.getChild(0).toStringTree(parser));
-			}	
-			elem.put("key", value);
-			// add token to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the values from "field")
-			if (node.getParent().getChildCount()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(elem);
-			}
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(1));
-			visited.add(node.getChild(2));
-		}
-		
-		if (nodeCat.equals("spanclass")) {
-			LinkedHashMap<String,Object> span = new LinkedHashMap<String,Object>();
-			span.put("@type", "korap:group");
-			span.put("operation", "operation:"+"class");
-			objectStack.push(span);
-			stackedObjects++;
-			ArrayList<Object> spanOperands = new ArrayList<Object>();
-			// Step I: get info
-			int classId = 0;
-			if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
-				String ref = node.getChild(1).getChild(0).toStringTree(parser);
-				try {	
-					classId = Integer.parseInt(ref);
-				} catch (NumberFormatException e) {
-					throw new QueryException("The specified class reference in the shrink/split-Operator is not a number: "+ref);
-				}
-				// only allow class id up to 255
-				if (classId>255) {
-					classId = 0;
-				}
-			}
-			span.put("class", classId);
-			span.put("operands", spanOperands);
-			// Step II: decide where to put the span
-			// add span to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the relevant info)
-			if (openNodeCats.get(2).equals("query") && node.getParent().getChildCount() == 1) {
-				requestMap.put("query", span);	
-			} else if (objectStack.size()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(span); 
-			} 
-			// ignore leading and trailing braces
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(node.getChildCount()-1)); 
-			if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
-				visited.add(node.getChild(1));
-			}
-		}
-		
-		if (nodeCat.equals("position")) {
-			LinkedHashMap<String,Object> positionGroup = new LinkedHashMap<String,Object>();
-			objectStack.push(positionGroup);
-			stackedObjects++;
-			ArrayList<Object> posOperands = new ArrayList<Object>();
-			// Step I: get info
-			String relation = getNodeCat(node.getChild(0));
-			positionGroup.put("@type", "korap:group");
-			positionGroup.put("operation", "operation:"+"position");
-			positionGroup.put("frame", "frame:"+relation.toLowerCase());
+            }
+            if (hasChild(node, "key")) {
+                ParseTree keyNode = getFirstChildWithCat(node, "key");
+                key = keyNode.getChild(0).toStringTree(parser);
+            }
+
+            String relation = node.getChild(1).getChild(0).toStringTree(parser);
+            if (negField) {
+                if (relation.startsWith("!")) {
+                    relation = relation.substring(1);
+                } else {
+                    relation = "!" + relation;
+                }
+            }
+            if (relation.equals("=")) {
+                relation = "eq";
+            } else if (relation.equals("!=")) {
+                relation = "ne";
+            }
+
+            ParseTree valNode;
+            if (hasChild(node, "key")) valNode = node.getChild(3);
+            else valNode = node.getChild(2);
+            String valType = getNodeCat(valNode);
+            fieldMap.put("@type", "korap:term");
+            if (valType.equals("simple_query")) {
+                value = valNode.getChild(0).getChild(0).toStringTree(parser);   //e.g. (simple_query (sq_segment foo))
+            } else if (valType.equals("re_query")) {
+                value = valNode.getChild(0).toStringTree(parser);                //e.g. (re_query "bar*")
+                fieldMap.put("type", "type:regex");
+                value = value.substring(1, value.length() - 1); //remove trailing quotes
+            }
+            if (key == null) {
+                fieldMap.put("key", value);
+            } else {
+                fieldMap.put("key", key);
+                fieldMap.put("value", value);
+            }
+
+            if (layer.equals("base")) layer = "lemma";
+            fieldMap.put("layer", layer);
+            if (foundry != null) fieldMap.put("foundry", foundry);
+
+            fieldMap.put("match", "match:" + relation);
+            // Step II: decide where to put the field map (as the only value of a token or the meta filter or as a part of a group in case of coordinated fields)
+            if (fieldStack.isEmpty()) {
+                if (!inMeta) {
+                    tokenStack.getFirst().put("wrap", fieldMap);
+                } else {
+                    ((HashMap<String, Object>) requestMap.get("meta")).put("key", fieldMap);
+                }
+            } else {
+                fieldStack.getFirst().add(fieldMap);
+            }
+            visited.add(node.getChild(0));
+            visited.add(node.getChild(1));
+            visited.add(node.getChild(2));
+            if (key != null) visited.add(node.getChild(3));
+        }
+
+        if (nodeCat.equals("neg_field") || nodeCat.equals("neg_field_group")) {
+            negField = !negField;
+        }
+
+        // conj_field serves for both conjunctions and disjunctions
+        if (nodeCat.equals("conj_field")) {
+            LinkedHashMap<String, Object> group = new LinkedHashMap<String, Object>();
+
+            group.put("@type", "korap:termGroup");
+
+            // Step I: get operator (& or |)
+            ParseTree operatorNode = node.getChild(1).getChild(0);
+            String operator = getNodeCat(operatorNode);
+            String relation = operator.equals("&") ? "and" : "or";
+            if (negField) {
+                relation = relation.equals("or") ? "and" : "or";
+            }
+            group.put("relation", "relation:" + relation);
+            ArrayList<Object> groupOperands = new ArrayList<Object>();
+            group.put("operands", groupOperands);
+            fieldStack.push(groupOperands);
+            stackedFields++;
+            // Step II: decide where to put the group (directly under token or in top meta filter section or embed in super group)
+            if (openNodeCats.get(1).equals("cq_segment")) {
+                tokenStack.getFirst().put("wrap", group);
+            } else if (openNodeCats.get(1).equals("meta_field_group")) {
+                ((HashMap<String, Object>) requestMap.get("meta")).put("key", group);
+            } else if (openNodeCats.get(2).equals("conj_field")) {
+                fieldStack.get(1).add(group);
+            } else {
+                tokenStack.getFirst().put("wrap", group);
+            }
+            // skip the operator
+            visited.add(node.getChild(1));
+        }
+
+
+        if (nodeCat.equals("sq_segment")) {
+            // Step I: determine whether to create new token or get token from the stack (if added by cq_segments)
+            LinkedHashMap<String, Object> token;
+            if (tokenStack.isEmpty()) {
+                token = new LinkedHashMap<String, Object>();
+                tokenStack.push(token);
+                stackedTokens++;
+            } else {
+                // in case sq_segments has already added the token
+                token = tokenStack.getFirst();
+            }
+            curToken = token;
+            objectStack.push(token);
+            stackedObjects++;
+            // Step II: fill object (token values) and put into containing sequence
+            if (node.getText().equals("[]")) {
+
+            } else {
+                token.put("@type", "korap:token");
+                String word = node.getChild(0).toStringTree(parser);
+                LinkedHashMap<String, Object> tokenValues = new LinkedHashMap<String, Object>();
+                token.put("wrap", tokenValues);
+                tokenValues.put("@type", "korap:term");
+                tokenValues.put("key", word);
+                tokenValues.put("layer", "orth");
+                tokenValues.put("match", "match:" + "eq");
+                // add token to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the values from "field")
+                if (node.getParent().getChildCount() > 1) {
+                    ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                    topSequenceOperands.add(token);
+                }
+            }
+            visited.add(node.getChild(0));
+        }
+
+        if (nodeCat.equals("re_query")) {
+            LinkedHashMap<String, Object> reQuery = new LinkedHashMap<String, Object>();
+            reQuery.put("type", "type:regex");
+            String regex = node.getChild(0).toStringTree(parser);
+            reQuery.put("key", regex);
+            reQuery.put("match", "match:" + "eq");
+
+            // if in field, regex was already added there
+            if (!openNodeCats.get(1).equals("field")) {
+                LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>();
+                token.put("@type", "korap:token");
+                token.put("wrap", reQuery);
+                reQuery.put("@type", "korap:term");
+
+                if (openNodeCats.get(1).equals("query")) {
+                    requestMap.put("query", token);
+                } else {
+                    ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                    topSequenceOperands.add(token);
+                }
+            }
+        }
+
+        if (nodeCat.equals("alignment")) {
+            alignNext = true;
+            LinkedHashMap<String, Object> alignGroup = new LinkedHashMap<String, Object>();
+            // push but don't increase the stackedObjects counter in order to keep this
+            // group open until the mother cq_segments node will be closed, since the
+            // operands are siblings of this align node rather than children, i.e. the group
+            // would be removed from the stack before seeing its operands.
+            objectStack.push(alignGroup);
+            stackedObjects++;
+            // Step I: get info
+            // fill group
+            alignGroup.put("@type", "korap:group");
+            alignGroup.put("alignment", "left");
+            alignGroup.put("operands", new ArrayList<Object>());
+            // Step II: decide where to put the group
+            // add group to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the relevant info)
+            if (node.getParent().getChildCount() > 1) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(alignGroup);
+            } else if (openNodeCats.get(2).equals("query")) {
+                requestMap.put("query", alignGroup);
+            } else {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(alignGroup);
+            }
+            visited.add(node.getChild(0));
+        }
+
+        if (nodeCat.equals("element")) {
+            // Step I: determine whether to create new token or get token from the stack (if added by cq_segments)
+            LinkedHashMap<String, Object> elem;
+            if (tokenStack.isEmpty()) {
+                elem = new LinkedHashMap<String, Object>();
+            } else {
+                // in case sq_segments has already added the token
+                elem = tokenStack.getFirst();
+            }
+            curToken = elem;
+            objectStack.push(elem);
+            stackedObjects++;
+            // Step II: fill object (token values) and put into containing sequence
+            elem.put("@type", "korap:span");
+            int valChildIdx = node.getChildCount() - 2; // closing '>' is last child
+            String value = node.getChild(valChildIdx).toStringTree(parser);
+            ParseTree foundryNode = getFirstChildWithCat(node, "foundry");
+            ParseTree layerNode = getFirstChildWithCat(node, "layer");
+            if (foundryNode != null) {
+                elem.put("foundry", foundryNode.getChild(0).toStringTree(parser));
+            }
+            if (layerNode != null) {
+                elem.put("layer", layerNode.getChild(0).toStringTree(parser));
+            }
+            elem.put("key", value);
+            // add token to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the values from "field")
+            if (node.getParent().getChildCount() > 1) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(elem);
+            }
+            visited.add(node.getChild(0));
+            visited.add(node.getChild(1));
+            visited.add(node.getChild(2));
+        }
+
+        if (nodeCat.equals("spanclass")) {
+            LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>();
+            span.put("@type", "korap:group");
+            span.put("operation", "operation:" + "class");
+            objectStack.push(span);
+            stackedObjects++;
+            ArrayList<Object> spanOperands = new ArrayList<Object>();
+            // Step I: get info
+            int classId = 0;
+            if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
+                String ref = node.getChild(1).getChild(0).toStringTree(parser);
+                try {
+                    classId = Integer.parseInt(ref);
+                } catch (NumberFormatException e) {
+                    throw new QueryException("The specified class reference in the shrink/split-Operator is not a number: " + ref);
+                }
+                // only allow class id up to 255
+                if (classId > 255) {
+                    classId = 0;
+                }
+            }
+            span.put("class", classId);
+            span.put("operands", spanOperands);
+            // Step II: decide where to put the span
+            // add span to sequence only if it is not an only child (in that case, cq_segments has already added the info and is just waiting for the relevant info)
+            if (openNodeCats.get(2).equals("query") && node.getParent().getChildCount() == 1) {
+                requestMap.put("query", span);
+            } else if (objectStack.size() > 1) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(span);
+            }
+            // ignore leading and trailing braces
+            visited.add(node.getChild(0));
+            visited.add(node.getChild(node.getChildCount() - 1));
+            if (getNodeCat(node.getChild(1)).equals("spanclass_id")) {
+                visited.add(node.getChild(1));
+            }
+        }
+
+        if (nodeCat.equals("position")) {
+            LinkedHashMap<String, Object> positionGroup = new LinkedHashMap<String, Object>();
+            objectStack.push(positionGroup);
+            stackedObjects++;
+            ArrayList<Object> posOperands = new ArrayList<Object>();
+            // Step I: get info
+            String relation = getNodeCat(node.getChild(0));
+            positionGroup.put("@type", "korap:group");
+            positionGroup.put("operation", "operation:" + "position");
+            positionGroup.put("frame", "frame:" + relation.toLowerCase());
 //			positionGroup.put("@subtype", "incl");
-			positionGroup.put("operands", posOperands);
-			// Step II: decide where to put the group
-			// add group to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the relevant info)
-			if (node.getParent().getChildCount()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(positionGroup); 
-			} else if (openNodeCats.get(2).equals("query")) {
-				requestMap.put("query", positionGroup);	
-			} else {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-				topSequenceOperands.add(positionGroup); 
-			}
-		}
-		
-		if (nodeCat.equals("shrink")) {
-			LinkedHashMap<String,Object> shrinkGroup = new LinkedHashMap<String,Object>();
-			objectStack.push(shrinkGroup);
-			stackedObjects++;
-			ArrayList<Object> shrinkOperands = new ArrayList<Object>();
-			// Step I: get info
-			ArrayList<Integer> classRefs = new ArrayList<Integer>();
-			String classRefOp = null;
-			if (getNodeCat(node.getChild(2)).equals("spanclass_id")) {
-				ParseTree spanNode = node.getChild(2);
-				for (int i=0; i<spanNode.getChildCount()-1; i++) {
-					String ref = spanNode.getChild(i).getText();
-					if (ref.equals("|") || ref.equals("&")) {
-						classRefOp = ref.equals("|") ? "intersection" : "union";
-					} else {
-						try {
-							int classRef = Integer.parseInt(ref);
-							// only allow class id up to 255
-							if (classRef>255) {
-								classRef = 0;
-							}
-							classRefs.add(classRef);
-						} catch (NumberFormatException e) {
-							throw new QueryException("The specified class reference in the shrink/split-Operator is not a number.");
-						}
-					}
-				}
-			} else {
-				classRefs.add(0);
-			}
-			shrinkGroup.put("@type", "korap:group");
-			String type = node.getChild(0).toStringTree(parser);
-			String operation = type.equals("shrink") ? "submatch" : "split";
-			shrinkGroup.put("operation", "operation:"+operation);
-			shrinkGroup.put("classRef", classRefs);
-			if (classRefOp != null) {
-				shrinkGroup.put("classRefOp", "classRefOp:"+classRefOp);
-			}
-			shrinkGroup.put("operands", shrinkOperands);
-			int i=1;
-			// Step II: decide where to put the group
-			// add group to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the relevant info)
-			if (node.getParent().getChildCount()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(i).get("operands"); // this shrinkGroup is on top
-				topSequenceOperands.add(shrinkGroup);
-			} else if (openNodeCats.get(2).equals("query")) {
-				requestMap.put("query", shrinkGroup);	
-			} else if (objectStack.size()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(i).get("operands");
-				topSequenceOperands.add(shrinkGroup); 
-			} 
-			visited.add(node.getChild(0));
-		}
-		
-		// repetition of token group
-		if (nodeCat.equals("occ")) {
-			ParseTree occChild = node.getChild(0);
-			String repetition = occChild.toStringTree(parser);
-			int[] minmax = parseRepetition(repetition);
-			curOccGroup.put("operation", "operation:"+"repetition");
-			curOccGroup.put("min", minmax[0]);
-			curOccGroup.put("max", minmax[1]);
-			visited.add(occChild);
-		}
-				
-		// flags for case sensitivity and whole-word-matching
-		if (nodeCat.equals("flag")) {
-			String flag = getNodeCat(node.getChild(0)).substring(1); //substring removes leading slash '/'
-			// add to current token's value
-			if (flag.contains("i")) ((HashMap<String, Object>) curToken.get("wrap")).put("caseInsensitive", true);
-			else if (flag.contains("I")) ((HashMap<String, Object>) curToken.get("wrap")).put("caseInsensitive", false);
-			else ((HashMap<String, Object>) curToken.get("wrap")).put("flag", flag);
-		}
-		
-		if (nodeCat.equals("meta")) {
-			inMeta=true;
-			LinkedHashMap<String,Object> metaFilter = new LinkedHashMap<String,Object>();
-			requestMap.put("meta", metaFilter);
-			metaFilter.put("@type", "korap:meta");
-		}
-		
-		if (nodeCat.equals("within") && !getNodeCat(node.getParent()).equals("position")) {
-			ParseTree domainNode = node.getChild(2);
-			String domain = getNodeCat(domainNode);
-			LinkedHashMap<String,Object> curObject = (LinkedHashMap<String, Object>) objectStack.getFirst();
-			curObject.put("within", domain);
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(1));
-			visited.add(domainNode);
-		}
-		
-		objectsToPop.push(stackedObjects);
-		tokensToPop.push(stackedTokens);
-		fieldsToPop.push(stackedFields);
+            positionGroup.put("operands", posOperands);
+            // Step II: decide where to put the group
+            // add group to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the relevant info)
+            if (node.getParent().getChildCount() > 1) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(positionGroup);
+            } else if (openNodeCats.get(2).equals("query")) {
+                requestMap.put("query", positionGroup);
+            } else {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+                topSequenceOperands.add(positionGroup);
+            }
+        }
+
+        if (nodeCat.equals("shrink")) {
+            LinkedHashMap<String, Object> shrinkGroup = new LinkedHashMap<String, Object>();
+            objectStack.push(shrinkGroup);
+            stackedObjects++;
+            ArrayList<Object> shrinkOperands = new ArrayList<Object>();
+            // Step I: get info
+            ArrayList<Integer> classRefs = new ArrayList<Integer>();
+            String classRefOp = null;
+            if (getNodeCat(node.getChild(2)).equals("spanclass_id")) {
+                ParseTree spanNode = node.getChild(2);
+                for (int i = 0; i < spanNode.getChildCount() - 1; i++) {
+                    String ref = spanNode.getChild(i).getText();
+                    if (ref.equals("|") || ref.equals("&")) {
+                        classRefOp = ref.equals("|") ? "intersection" : "union";
+                    } else {
+                        try {
+                            int classRef = Integer.parseInt(ref);
+                            // only allow class id up to 255
+                            if (classRef > 255) {
+                                classRef = 0;
+                            }
+                            classRefs.add(classRef);
+                        } catch (NumberFormatException e) {
+                            throw new QueryException("The specified class reference in the shrink/split-Operator is not a number.");
+                        }
+                    }
+                }
+            } else {
+                classRefs.add(0);
+            }
+            shrinkGroup.put("@type", "korap:group");
+            String type = node.getChild(0).toStringTree(parser);
+            String operation = type.equals("shrink") ? "submatch" : "split";
+            shrinkGroup.put("operation", "operation:" + operation);
+            shrinkGroup.put("classRef", classRefs);
+            if (classRefOp != null) {
+                shrinkGroup.put("classRefOp", "classRefOp:" + classRefOp);
+            }
+            shrinkGroup.put("operands", shrinkOperands);
+            int i = 1;
+            // Step II: decide where to put the group
+            // add group to sequence only if it is not an only child (in that case, sq_segments has already added the info and is just waiting for the relevant info)
+            if (node.getParent().getChildCount() > 1) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(i).get("operands"); // this shrinkGroup is on top
+                topSequenceOperands.add(shrinkGroup);
+            } else if (openNodeCats.get(2).equals("query")) {
+                requestMap.put("query", shrinkGroup);
+            } else if (objectStack.size() > 1) {
+                ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(i).get("operands");
+                topSequenceOperands.add(shrinkGroup);
+            }
+            visited.add(node.getChild(0));
+        }
+
+        // repetition of token group
+        if (nodeCat.equals("occ")) {
+            ParseTree occChild = node.getChild(0);
+            String repetition = occChild.toStringTree(parser);
+            int[] minmax = parseRepetition(repetition);
+            curOccGroup.put("operation", "operation:" + "repetition");
+            curOccGroup.put("min", minmax[0]);
+            curOccGroup.put("max", minmax[1]);
+            visited.add(occChild);
+        }
+
+        // flags for case sensitivity and whole-word-matching
+        if (nodeCat.equals("flag")) {
+            String flag = getNodeCat(node.getChild(0)).substring(1); //substring removes leading slash '/'
+            // add to current token's value
+            if (flag.contains("i")) ((HashMap<String, Object>) curToken.get("wrap")).put("caseInsensitive", true);
+            else if (flag.contains("I")) ((HashMap<String, Object>) curToken.get("wrap")).put("caseInsensitive", false);
+            else ((HashMap<String, Object>) curToken.get("wrap")).put("flag", flag);
+        }
+
+        if (nodeCat.equals("meta")) {
+            inMeta = true;
+            LinkedHashMap<String, Object> metaFilter = new LinkedHashMap<String, Object>();
+            requestMap.put("meta", metaFilter);
+            metaFilter.put("@type", "korap:meta");
+        }
+
+        if (nodeCat.equals("within") && !getNodeCat(node.getParent()).equals("position")) {
+            ParseTree domainNode = node.getChild(2);
+            String domain = getNodeCat(domainNode);
+            LinkedHashMap<String, Object> curObject = (LinkedHashMap<String, Object>) objectStack.getFirst();
+            curObject.put("within", domain);
+            visited.add(node.getChild(0));
+            visited.add(node.getChild(1));
+            visited.add(domainNode);
+        }
+
+        objectsToPop.push(stackedObjects);
+        tokensToPop.push(stackedTokens);
+        fieldsToPop.push(stackedFields);
 		
 		/*
 		 ****************************************************************
@@ -840,184 +824,182 @@
 		 ****************************************************************
 		 ****************************************************************
 		 */
-		for (int i=0; i<node.getChildCount(); i++) {
-			ParseTree child = node.getChild(i);
-			curChildIndex = i;
-			processNode(child);
-		}
-				
-		// set negField back 
-		if (nodeCat.equals("neg_field") || nodeCat.equals("neg_field_group")) {
-			negField = !negField;
-		}
-		
-		// pop the align group that was introduced by previous 'align' but never closed
+        for (int i = 0; i < node.getChildCount(); i++) {
+            ParseTree child = node.getChild(i);
+            curChildIndex = i;
+            processNode(child);
+        }
+
+        // set negField back
+        if (nodeCat.equals("neg_field") || nodeCat.equals("neg_field_group")) {
+            negField = !negField;
+        }
+
+        // pop the align group that was introduced by previous 'align' but never closed
 //		if (isAligned) {
 //			isAligned=false;
 //			objectStack.pop();
 //		}
-		
-		// Stuff that happens when leaving a node (taking items off the stacks)
-		for (int i=0; i<objectsToPop.get(0); i++) {
-			objectStack.pop();
-		}
-		objectsToPop.pop();
-		for (int i=0; i<tokensToPop.get(0); i++) {
-			tokenStack.pop();
-		}
-		tokensToPop.pop();
-		for (int i=0; i<fieldsToPop.get(0); i++) {
-			fieldStack.pop();
-		}
-		fieldsToPop.pop();
-		openNodeCats.pop();
-	}
 
-	private int[] parseRepetition(String repetition) {
-		if (repetition.equals("*")) {
-			return new int[] {0, 100};
-		} else if (repetition.equals("+")) {
-			return new int[] {1, 100};
-		} else if (repetition.equals("?")) {
-			return new int[] {0, 1};
-		} else {
-			repetition = repetition.substring(1, repetition.length()-1); // remove braces
-			String[] splitted = repetition.split(",");
-			if (splitted.length==2) {
-				return new int[] {Integer.parseInt(splitted[0]), Integer.parseInt(splitted[1])};
-			} else {
-				return new int[] {Integer.parseInt(splitted[0]), Integer.parseInt(splitted[0])};
-			}
-			
-		}
-	}
+        // Stuff that happens when leaving a node (taking items off the stacks)
+        for (int i = 0; i < objectsToPop.get(0); i++) {
+            objectStack.pop();
+        }
+        objectsToPop.pop();
+        for (int i = 0; i < tokensToPop.get(0); i++) {
+            tokenStack.pop();
+        }
+        tokensToPop.pop();
+        for (int i = 0; i < fieldsToPop.get(0); i++) {
+            fieldStack.pop();
+        }
+        fieldsToPop.pop();
+        openNodeCats.pop();
+    }
 
-	private String[] parseEmptySegments(ParseTree emptySegments) {
-		String[] minmax = new String[2];
-		Integer min = 1;
-		Integer max = 1;
-		ParseTree child;
-		for (int i=0; i<emptySegments.getChildCount()-1; i++) {
-			child = emptySegments.getChild(i);
-			ParseTree nextSibling = emptySegments.getChild(i+1);
-			String nextSiblingString = nextSibling.toStringTree(); 
-			if (child.toStringTree().equals("[]")) {
-				if (nextSiblingString.equals("?")) {
-					max++;
-				} else if (nextSiblingString.startsWith("{")) {
-					String occ = nextSiblingString.substring(1,nextSiblingString.length()-1);
-					System.out.println(occ);
-					if (occ.contains(",")) {
-						String[] minmaxOcc = occ.split(",");
-						min += Integer.parseInt(minmaxOcc[0]);
-						max += Integer.parseInt(minmaxOcc[1]);
-					} else {
-						min += Integer.parseInt(occ);
-						max += Integer.parseInt(occ);
-					}
-				} else {
-					min++;
-					max++;
-				}
-			}
-		}
-		child = emptySegments.getChild(emptySegments.getChildCount()-1);
-		if (child.toStringTree().equals("[]")) {
-			min++;
-			max++;
-		}
-		minmax[0] = min.toString();
-		minmax[1] = max.toString();
-		return minmax;
-	}
+    private int[] parseRepetition(String repetition) {
+        if (repetition.equals("*")) {
+            return new int[]{0, 100};
+        } else if (repetition.equals("+")) {
+            return new int[]{1, 100};
+        } else if (repetition.equals("?")) {
+            return new int[]{0, 1};
+        } else {
+            repetition = repetition.substring(1, repetition.length() - 1); // remove braces
+            String[] splitted = repetition.split(",");
+            if (splitted.length == 2) {
+                return new int[]{Integer.parseInt(splitted[0]), Integer.parseInt(splitted[1])};
+            } else {
+                return new int[]{Integer.parseInt(splitted[0]), Integer.parseInt(splitted[0])};
+            }
 
-	@SuppressWarnings("unchecked")
-	private void createOccGroup(ParseTree node) {
-		LinkedHashMap<String,Object> occGroup = new LinkedHashMap<String,Object>();
-		occGroup.put("@type", "korap:group");
-		ArrayList<Object> groupOperands = new ArrayList<Object>();
-		occGroup.put("operands", groupOperands);
-		curOccGroup = occGroup;
-		objectStack.push(occGroup);
-		stackedObjects++;
-		// if only this group is on the object stack, add as top query element
-		if (objectStack.size()==1) {
-				requestMap.put("query", occGroup);
-		// embed in super sequence
-		} else {
-			ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
-			topSequenceOperands.add(occGroup);
-		}		
-	}
+        }
+    }
 
-	
+    private String[] parseEmptySegments(ParseTree emptySegments) {
+        String[] minmax = new String[2];
+        Integer min = 1;
+        Integer max = 1;
+        ParseTree child;
+        for (int i = 0; i < emptySegments.getChildCount() - 1; i++) {
+            child = emptySegments.getChild(i);
+            ParseTree nextSibling = emptySegments.getChild(i + 1);
+            String nextSiblingString = nextSibling.toStringTree();
+            if (child.toStringTree().equals("[]")) {
+                if (nextSiblingString.equals("?")) {
+                    max++;
+                } else if (nextSiblingString.startsWith("{")) {
+                    String occ = nextSiblingString.substring(1, nextSiblingString.length() - 1);
+                    System.out.println(occ);
+                    if (occ.contains(",")) {
+                        String[] minmaxOcc = occ.split(",");
+                        min += Integer.parseInt(minmaxOcc[0]);
+                        max += Integer.parseInt(minmaxOcc[1]);
+                    } else {
+                        min += Integer.parseInt(occ);
+                        max += Integer.parseInt(occ);
+                    }
+                } else {
+                    min++;
+                    max++;
+                }
+            }
+        }
+        child = emptySegments.getChild(emptySegments.getChildCount() - 1);
+        if (child.toStringTree().equals("[]")) {
+            min++;
+            max++;
+        }
+        minmax[0] = min.toString();
+        minmax[1] = max.toString();
+        return minmax;
+    }
 
-	
-	private ParserRuleContext parsePoliqarpQuery (String p) throws QueryException {
-		checkUnbalancedPars(p);
-		
-		Lexer poliqarpLexer = new PoliqarpPlusLexer((CharStream)null);
-	    ParserRuleContext tree = null;
-	    // Like p. 111
-	    try {
+    @SuppressWarnings("unchecked")
+    private void createOccGroup(ParseTree node) {
+        LinkedHashMap<String, Object> occGroup = new LinkedHashMap<String, Object>();
+        occGroup.put("@type", "korap:group");
+        ArrayList<Object> groupOperands = new ArrayList<Object>();
+        occGroup.put("operands", groupOperands);
+        curOccGroup = occGroup;
+        objectStack.push(occGroup);
+        stackedObjects++;
+        // if only this group is on the object stack, add as top query element
+        if (objectStack.size() == 1) {
+            requestMap.put("query", occGroup);
+            // embed in super sequence
+        } else {
+            ArrayList<Object> topSequenceOperands = (ArrayList<Object>) objectStack.get(1).get("operands");
+            topSequenceOperands.add(occGroup);
+        }
+    }
 
-	      // Tokenize input data
-	      ANTLRInputStream input = new ANTLRInputStream(p);
-	      poliqarpLexer.setInputStream(input);
-	      CommonTokenStream tokens = new CommonTokenStream(poliqarpLexer);
-	      parser = new PoliqarpPlusParser(tokens);
 
-	      // Don't throw out erroneous stuff
-	      parser.setErrorHandler(new BailErrorStrategy());
-	      parser.removeErrorListeners();
+    private ParserRuleContext parsePoliqarpQuery(String p) throws QueryException {
+        checkUnbalancedPars(p);
 
-	      // Get starting rule from parser
-	      Method startRule = PoliqarpPlusParser.class.getMethod("request");
-	      tree = (ParserRuleContext) startRule.invoke(parser, (Object[])null);
-	    }
+        Lexer poliqarpLexer = new PoliqarpPlusLexer((CharStream) null);
+        ParserRuleContext tree = null;
+        // Like p. 111
+        try {
 
-	    // Some things went wrong ...
-	    catch (Exception e) {
-	      System.err.println( e.getMessage() );
-	    }
-	    
-	    if (tree==null) throw new QueryException(
-	    		"The query you specified could not be processed. Please make sure it is well-formed.");
-	    
-	    // Return the generated tree
-	    return tree;
-	  }
-	
-	public static void main(String[] args) {
+            // Tokenize input data
+            ANTLRInputStream input = new ANTLRInputStream(p);
+            poliqarpLexer.setInputStream(input);
+            CommonTokenStream tokens = new CommonTokenStream(poliqarpLexer);
+            parser = new PoliqarpPlusParser(tokens);
+
+            // Don't throw out erroneous stuff
+            parser.setErrorHandler(new BailErrorStrategy());
+            parser.removeErrorListeners();
+
+            // Get starting rule from parser
+            Method startRule = PoliqarpPlusParser.class.getMethod("request");
+            tree = (ParserRuleContext) startRule.invoke(parser, (Object[]) null);
+        }
+
+        // Some things went wrong ...
+        catch (Exception e) {
+            System.err.println(e.getMessage());
+        }
+
+        if (tree == null) throw new QueryException(
+                "The query you specified could not be processed. Please make sure it is well-formed.");
+
+        // Return the generated tree
+        return tree;
+    }
+
+    public static void main(String[] args) {
 		/*
 		 * For testing
 		 */
-		String[] queries = new String[] {
-				"shrink(1|2:{1:[base=der]}{2:[base=Mann]})",
-				"{[base=Mann]}",
-				"shrink(1:[orth=Der]{1:[orth=Mann][orth=geht]})",
-				"[base=Mann/i]",
-				"[cnx/base=pos:n]",
-				"<cnx/c=np>",
-				"contains(<cnx/c=np>, [mate/pos=NE])",
-				"matches(<A>,[pos=N]*)",
-				"[base=Auto]matches(<A>,[][pos=N]{4})",
-				"[base=der][][base=Mann]"
-		};
+        String[] queries = new String[]{
+                "shrink(1|2:{1:[base=der]}{2:[base=Mann]})",
+                "{[base=Mann]}",
+                "shrink(1:[orth=Der]{1:[orth=Mann][orth=geht]})",
+                "[base=Mann/i]",
+                "[cnx/base=pos:n]",
+                "<cnx/c=np>",
+                "contains(<cnx/c=np>, [mate/pos=NE])",
+                "matches(<A>,[pos=N]*)",
+                "[base=Auto]matches(<A>,[][pos=N]{4})",
+                "[base=der][][base=Mann]"
+        };
 //		PoliqarpPlusTree.verbose=true;
-		for (String q : queries) {
-			try {
-				System.out.println(q);
+        for (String q : queries) {
+            try {
+                System.out.println(q);
 //				System.out.println(PoliqarpPlusTree.parsePoliqarpQuery(q).toStringTree(PoliqarpPlusTree.parser));
-				@SuppressWarnings("unused")
-				PoliqarpPlusTree pt = new PoliqarpPlusTree(q);
-				System.out.println(q);
-				System.out.println();
-				
-			} catch (Exception npe) {
-				npe.printStackTrace();
-				System.out.println("null\n");
-			}
-		}
-	}
+                @SuppressWarnings("unused")
+                PoliqarpPlusTree pt = new PoliqarpPlusTree(q);
+                System.out.println(q);
+                System.out.println();
+
+            } catch (Exception npe) {
+                npe.printStackTrace();
+                System.out.println("null\n");
+            }
+        }
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java b/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java
index ec32fcb..b8d3ee5 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java
@@ -130,6 +130,7 @@
                              String cli, String cri, int cls, int crs,
                              int num, int page, boolean cutoff, String version)
             throws QueryException {
+        PoliqarpPlusTree.debug = true;
         try {
             if (ql.toLowerCase().equals("poliqarp")) {
                 ast = new PoliqarpPlusTree(query);
@@ -144,6 +145,7 @@
                 throw new QueryException(ql + " is not a supported query language!");
             }
         } catch (QueryException e) {
+            log.error("QUERY EXCEPTION {}", e.getErrorCode());
             throw e;
         } catch (Exception e) {
             throw new QueryException("UNKNOWN: Query could not be parsed");
