KorAP-querySerialization independent from 
- KorAP-PoliqarpParser
- KorAP-AnnisParser
- KorAP-Cosmas2Parser
- KorAP-lucene-index

grammars integrated into querySerialization

still depends on KorAP-Entities (e.g. JsonUtils used in QuerySerializer and CollectionQueryBuilder)
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/IErrorReporter.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/IErrorReporter.java
new file mode 100644
index 0000000..9f92c7b
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/IErrorReporter.java
@@ -0,0 +1,5 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+public interface IErrorReporter {
+	void reportError(String error);
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opAnnot.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opAnnot.java
new file mode 100644
index 0000000..4bb62a2
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opAnnot.java
@@ -0,0 +1,37 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+/* COSMAS II Plain Syntax (c2ps).
+ * lokale Grammatik für Optionen von #IN(Opts).
+ * 12.12.12/FB
+ *
+ * strip(): MORPH(NP sg nom) -> NP sg nom.
+ */
+
+public class c2ps_opAnnot
+
+{
+
+ public static String strip(String input)
+ 	{
+	if( input.startsWith("MORPH(") )
+		{
+		input = input.substring(6,input.length()-1);
+		}
+
+	return input;
+	}
+
+ /*
+  * main: testprogram:
+  */
+
+ public static void main(String args[]) throws Exception 
+  {
+  } // main
+
+} 
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opBED.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opBED.java
new file mode 100644
index 0000000..a6dc19b
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opBED.java
@@ -0,0 +1,101 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+// parses Opts in #BED(x,Opts):
+
+public class c2ps_opBED
+
+{
+
+ public static Tree check(String input, int index)
+ 	{
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_opBEDLexer
+		lex = new c2ps_opBEDLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_opBEDParser 
+		g = new c2ps_opBEDParser(tokens);
+	c2ps_opBEDParser.opBEDOpts_return
+		c2PQReturn = null;
+
+  /*
+  System.out.println("check opBED: " + index + ": " + input);
+  System.out.flush();
+  */
+
+	try 
+		{
+		c2PQReturn = g.opBEDOpts();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = (Tree)c2PQReturn.getTree();
+	//System.out.println("#BED Opts: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+ /*
+  * check Text Position starting at rule textpos.
+  */
+
+ public static Tree checkTPos(String input, int index)
+ 	{
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_opBEDLexer
+		lex = new c2ps_opBEDLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_opBEDParser 
+		g = new c2ps_opBEDParser(tokens);
+	c2ps_opBEDParser.textpos_return
+		c2PQReturn = null;
+
+  /*
+  System.out.println("check opBED: " + index + ": " + input);
+  System.out.flush();
+  */
+
+	try 
+		{
+		c2PQReturn = g.textpos();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = (Tree)c2PQReturn.getTree();
+	// System.out.println("#BED Opts: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+ public static void main(String args[]) throws Exception 
+  {
+   String[]
+		input = {",sa,se,-ta,-te/pa,-pe)", ",sa)", ",/pa,-pe)"};  
+	Tree
+		tree;
+
+	for(int i=0; i<input.length; i++)
+		{
+		tree = check(input[i], 0);
+		System.out.println("Parsing input: " + input[i] + ": " + tree.toStringTree());
+		}
+
+  } // main
+
+} 
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opELEM.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opELEM.java
new file mode 100644
index 0000000..9968e24
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opELEM.java
@@ -0,0 +1,79 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+// parses Search Expression inside #ELEM(...):
+
+public class c2ps_opELEM
+
+{
+
+ /* Method check():
+  * input: e.g. #ELEM(S), #ELEM(W ANA='DET ADJ'),
+  *             #ELEM(ANA <> 'V sg' TYP !=VP), etc.
+  */
+ public static Tree check(String input, int index)
+ 	{
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_opELEMLexer
+		lex = new c2ps_opELEMLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_opELEMParser 
+		g = new c2ps_opELEMParser(tokens);
+	c2ps_opELEMParser.opELEM_return
+		c2PQReturn = null;
+
+  /*
+  System.out.println("check opELEM: " + index + ": " + "'" + input + "'");
+  System.out.flush();
+   */
+
+	try 
+		{
+		c2PQReturn = g.opELEM();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = (Tree)c2PQReturn.getTree();
+	//System.out.println("#ELEM Opts: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+
+ /*
+  * main - Testprogramm for #ELEM(...)
+  */
+
+ public static void main(String args[]) throws Exception 
+  {
+   String[]
+		input = {"#ELEM()", 
+					"#ELEM(   )", 
+					"#ELEM(S)", 
+					"#ELEM(W ANA='DET ADV')", 
+					"#ELEM( TITLE TYPE!=Unterüberschrift )",
+					"#ELEM(v='a b c' w!='d e f' x=y )",
+					"#ELEM(flexion='l\\'été' lemma='été')"};  
+	Tree
+		tree;
+
+	for(int i=0; i<input.length; i++)
+		{
+		System.out.println("#ELEM input: " + input[i]);
+		tree = check(input[i], 0);
+		System.out.println("#ELEM AST  : " + tree.toStringTree());
+		}
+
+  } // main
+
+} 
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opIN.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opIN.java
new file mode 100644
index 0000000..7d50a90
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opIN.java
@@ -0,0 +1,83 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+/* COSMAS II Plain Syntax (c2ps).
+ * lokale Grammatik für Optionen von #IN(Opts).
+ * 12.12.12/FB
+ *
+ * check(input): Input Bsp.: "#IN", "#IN()", "#IN(L)", "#IN(L,min,%)", etc.
+ *
+ * Opts nimmt eine oder mehrere, durch Kommata getrennte Optionen auf:
+ * - Bereichsoptionen: ALL, HIT, -.
+ * - Positionsoptionen: L, R, F, FE, FI, N, -.
+ * - Ausschließungsoptionen: %, -.
+ * - Gruppenbildungsoptionen: min, max, -.
+ * Für die Nutzung ohne Optionen steht Operator #IN zur Verfügung.
+ */
+
+public class c2ps_opIN
+
+{
+
+ public static Tree check(String input, int index)
+ 	{
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_opINLexer
+		lex = new c2ps_opINLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_opINParser 
+		g = new c2ps_opINParser(tokens);
+	c2ps_opINParser.opIN_return
+		c2PQReturn = null;
+
+  /*
+  System.out.println("check opIN:" + index + ": " + input);
+  System.out.flush();
+  */
+
+	try 
+		{
+		c2PQReturn = g.opIN();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = (Tree)c2PQReturn.getTree();
+	// System.out.println("opIN: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+ /*
+  * main: testprogram:
+  */
+
+ public static void main(String args[]) throws Exception 
+  {
+   String[]
+		input = {"#IN", "#IN()", "#IN(L)", "#IN(FE,min)", "#IN(R,%,max)", "#IN(FI,ALL)", 
+					"#IN(FE,ALL,%,MIN)"};  
+	Tree
+		tree;
+
+	System.out.println("Tests von #IN-Optionen:\n");
+
+	for(int i=0; i<input.length; i++)
+		{
+		tree = check(input[i], 0);
+		System.out.println("#IN: input: " + input[i]);
+		System.out.println("#IN: AST  : " + tree.toStringTree() + "\n");
+		}
+
+  } // main
+
+} 
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opOV.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opOV.java
new file mode 100644
index 0000000..c47160c
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opOV.java
@@ -0,0 +1,82 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+/* COSMAS II Plain Syntax (c2ps).
+ * lokale Grammatik für Optionen von #OV(Opts).
+ * 12.12.12/FB
+ *
+ * Input Bsp.: "#OV", "#OV()", "#OV(L)", "#OV(F,%,max)", etc.
+ *
+ * Opts nimmt eine oder mehrere, durch Kommata getrennte Optionen auf:
+ * - Positionsoptionen: L, R, F, FE, FI, X, -.
+ * - Ausschließungsoptionen: %, -.
+ * - Gruppenbildungsoptionen: min, max, -.
+ * Falls keine Optionen eingesetzt werden, kann der Operator #OV eingesetzt werden.
+ */
+
+public class c2ps_opOV
+
+{
+
+ public static Tree check(String input, int index)
+ 	{
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_opOVLexer
+		lex = new c2ps_opOVLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_opOVParser 
+		g = new c2ps_opOVParser(tokens);
+	c2ps_opOVParser.opOV_return
+		c2PQReturn = null;
+
+	try 
+		{
+		c2PQReturn = g.opOV();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = (Tree)c2PQReturn.getTree();
+	// System.out.println("opOV: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+ /*
+  * main: testprogram:
+  */
+
+ // TODOO: input "OV()" führt zu unendlichem loop... 19.12.12/FB
+ // TODOO: input "#OV(FI,ALL)" -> loop, weil ALL nicht bekannter Token...
+
+ public static void main(String args[]) throws Exception 
+  {
+   String[]
+		input = {"#OV", "#OV()", "#OV(L)", "#OV(FE,min)", "#OV(R,% , max)"};  
+	Tree
+		tree;
+
+	System.out.println("Tests von #OV-Optionen:\n");
+
+	for(int i=0; i<input.length; i++)
+		{
+		System.out.println("#OV: input: " + input[i]);
+		tree = check(input[i], 0);
+		System.out.println("#OV: AST  : " + tree.toStringTree() + "\n");
+		}
+
+	System.out.println("Tests von #OV-Optionen: quit.\n");
+	System.out.flush();
+  } // main
+
+} 
+
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opPROX.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opPROX.java
new file mode 100644
index 0000000..4d8561d
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opPROX.java
@@ -0,0 +1,79 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+/*
+ * parses Opts of PROX: /w3:4,s0,min or %w3:4,s0,min.
+ */
+
+public class c2ps_opPROX
+
+{
+
+ public static Tree check(String input, int index)
+ 	{
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_opPROXLexer
+		lex = new c2ps_opPROXLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_opPROXParser 
+		g = new c2ps_opPROXParser(tokens);
+	c2ps_opPROXParser.opPROX_return
+		c2PQReturn = null;
+
+  /*
+  System.out.println("check opPROX:" + index + ": " + input);
+  System.out.flush();
+   */
+
+	try 
+		{
+		c2PQReturn = g.opPROX();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = (Tree)c2PQReturn.getTree();
+	//System.out.println("PROX: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+ /*
+  * main testprogram:
+  */
+
+ public static void main(String args[]) throws Exception 
+  {
+   String[]
+		input = {"/w1:3", "%w5", "/+w3,s0,max"};  
+	Tree
+		tree;
+
+	System.out.println("Tests von PROX-Optionen:\n");
+
+	for(int i=0; i<input.length; i++)
+		{
+		tree = check(input[i], 0);
+		System.out.println("PROX: input: " + input[i]);
+		System.out.println("PROX: AST  : " + tree.toStringTree() + "\n");
+		
+		// Visualize AST Tree:
+		/*
+		DOTTreeGenerator gen = new DOTTreeGenerator();
+		StringTemplate st = gen.toDOT(tree);
+		System.out.println("DOTTREE: " + st);
+		*/
+		}
+
+  } // main
+
+} 
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opWF.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opWF.java
new file mode 100644
index 0000000..5400bec
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_opWF.java
@@ -0,0 +1,126 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+/*
+ * parses prefixed and suffixed options of a search wordform.
+ * E.g. :fi:Hendrix:sa/-pe.
+ */
+
+public class c2ps_opWF
+
+{
+ /* Arguments:
+  * bStrip: true: 'input' contains "wort" -> strip " away -> wort.
+  *        false: 'input' contains no " -> nothing to strip.
+  * bLem: true: input contains a Lemma; generates tree ^(OPLEM...).
+  *       false: input contains a Wordform; generates tree ^(OPWF...).
+  * input: may be a single Lemma or Wform or a list of Wforms.
+  */
+
+ public static Tree check(String input, boolean bStrip, boolean bLem, int index)
+ 	{
+	if( bStrip )
+		input = input.substring(1, input.length()-1);
+
+	if( bLem && input.charAt(0) == '&' )
+		{
+		input = input.substring(1, input.length());
+		//System.out.println("Lemma: strip '&' -> " + input);
+		}
+
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_opWFLexer
+		lex = new c2ps_opWFLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_opWFParser 
+		g = new c2ps_opWFParser(tokens);
+	c2ps_opWFParser.searchWFs_return
+		c2PQWFReturn = null;
+	c2ps_opWFParser.searchLEM_return
+		c2PQLEMReturn = null;
+
+  /*
+  System.out.println("check opWF:" + index + ": " + input);
+  System.out.flush();
+  */
+  
+	try 
+		{
+		if( bLem )
+			c2PQLEMReturn = g.searchLEM();
+		else
+			c2PQWFReturn = g.searchWFs();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = bLem ? (Tree)c2PQLEMReturn.getTree() : (Tree)c2PQWFReturn.getTree();
+	// System.out.println(bLem? "opLEM: " : "opWF: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+	/* Wordform Encoding, e.g. to insert a Wordform into an AST.
+	 * a) wf ->  "wf".
+	 * b) remove escape char before ':': abc\: -> abc:.
+	 * Returns a Tree.
+	 */
+	public static Tree encode(String wf, int tokenType)
+
+	{
+	// b)
+   StringBuffer
+		sbWF = new StringBuffer(wf);
+	
+	for(int i=0; i<sbWF.length()-1; i++)
+		{
+		if( sbWF.charAt(i) == '\\' && sbWF.charAt(i+1) == ':' )
+			sbWF.deleteCharAt(i);
+		}
+
+	return new CommonTree(new CommonToken(tokenType, "\"" + sbWF.toString() + "\""));
+	}
+
+ /*
+  * main testprogram:
+  */
+
+ public static void main(String args[]) throws Exception 
+  {
+   String[]
+		input = {":fi:Hendrix:sa", ":FiOlDs:été:sa", "&Gitarre", "&Gitarre:sa/-pe",
+					" \"Institut für \\:Deutsche\\: Sprache\" ",
+					":Fi:der:-sa Wilde:-se Western:/se" };
+	Tree
+		tree;
+	boolean
+		bLem;
+
+	System.out.println("Tests von WF und Lemma-Optionen:\n");
+
+	for(int i=0; i<input.length; i++)
+		{
+		bLem = input[i].charAt(0) == '&' ? true : false; 
+
+		System.out.println(bLem? "LEM: " : "WF: " + "input: " + input[i]);
+
+		if( bLem )
+			tree = check(input[i], false, true, 0); // bStrip=false, bLem=true;
+		else
+			tree = check(input[i], false, false, 0); // bStrip=false, bLem=false.
+			
+		System.out.println(bLem? "LEM: " : "WF: " + "AST  : " + tree.toStringTree() + "\n");
+		}
+
+  } // main
+
+} 
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_optCase.java b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_optCase.java
new file mode 100644
index 0000000..8f1ad28
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/cosmas/c2ps_optCase.java
@@ -0,0 +1,68 @@
+package de.ids_mannheim.korap.query.parse.cosmas;
+
+import java.io.*;
+import org.antlr.runtime.*;
+import org.antlr.runtime.debug.DebugEventSocketProxy;
+import org.antlr.runtime.tree.*;
+
+// parses Case Options.
+
+public class c2ps_optCase
+
+{
+
+ public static Tree check(String input, int index)
+ 	{
+	ANTLRStringStream
+		ss = new ANTLRStringStream(input);
+	c2ps_optCaseLexer
+		lex = new c2ps_optCaseLexer(ss);
+	CommonTokenStream tokens = 
+  		new CommonTokenStream(lex);
+	c2ps_optCaseParser 
+		g = new c2ps_optCaseParser(tokens);
+	c2ps_optCaseParser.optCase_return
+		c2PQReturn = null;
+
+  /*
+  System.out.println("check optCase: " + index + ": " + input);
+  System.out.flush();
+  */
+
+	try 
+		{
+		c2PQReturn = g.optCase();
+		}
+	catch (RecognitionException e) 
+		{
+		e.printStackTrace();
+		}
+
+	// AST Tree anzeigen:
+	Tree tree = (Tree)c2PQReturn.getTree();
+	//System.out.println("Case Opts: " + tree.toStringTree() );
+
+	return tree;
+	}
+
+ /*
+  * Main Text programm.
+  *
+  */
+
+ public static void main(String args[]) throws Exception 
+  {
+   String[]
+		input = {"Fi", "FiOsDi"};  
+	Tree
+		tree;
+
+	for(int i=0; i<input.length; i++)
+		{
+		tree = check(input[i], 0);
+		System.out.println("Parsing input: " + input[i] + ": " + tree.toStringTree());
+		}
+
+  } // main
+
+} 
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
index 624e42c..8232617 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
@@ -8,11 +8,10 @@
 import java.util.Map;
 
 import org.antlr.v4.runtime.tree.ParseTree;
-import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 
 import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 
 public abstract class AbstractSyntaxTree {
 	
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
index 57c958f..58e5a16 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
@@ -20,10 +20,10 @@
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
-import de.ids_mannheim.korap.query.annis.AqlLexer;
-import de.ids_mannheim.korap.query.annis.AqlParser;
+import de.ids_mannheim.korap.query.parse.annis.AqlLexer;
+import de.ids_mannheim.korap.query.parse.annis.AqlParser;
 import de.ids_mannheim.korap.query.serialize.util.Antlr4DescriptiveErrorListener;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 
 /**
  * Map representation of ANNIS QL syntax tree as returned by ANTLR
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CQLTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CQLTree.java
index a9c1d2a..15e4f0e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CQLTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CQLTree.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.query.serialize;
 
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 import org.z3950.zing.cql.*;
 
 import java.io.IOException;
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder.java
index 3dfcb12..96b94a0 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder.java
@@ -4,6 +4,7 @@
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multiset;
+
 import de.ids_mannheim.korap.resource.Relation;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
index 5f37988..333fd30 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
@@ -1,7 +1,7 @@
 package de.ids_mannheim.korap.query.serialize;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
 import java.io.IOException;
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
index 786ab94..f3a1bbd 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.query.serialize;
 
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
 import java.io.IOException;
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java
index 71a96fc..9909d25 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java
@@ -1,10 +1,10 @@
 package de.ids_mannheim.korap.query.serialize;
 
+import de.ids_mannheim.korap.query.parse.collection.CollectionQueryLexer;
+import de.ids_mannheim.korap.query.parse.collection.CollectionQueryParser;
 import de.ids_mannheim.korap.query.serialize.util.Antlr4DescriptiveErrorListener;
-import de.ids_mannheim.korap.query.serialize.util.CollectionQueryLexer;
-import de.ids_mannheim.korap.query.serialize.util.CollectionQueryParser;
 import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 
 import org.antlr.v4.runtime.*;
 import org.antlr.v4.runtime.tree.*;
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java
index c83dff7..162b17c 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java
@@ -1,11 +1,11 @@
 package de.ids_mannheim.korap.query.serialize;
 
-import de.ids_mannheim.korap.query.cosmas2.c2psLexer;
-import de.ids_mannheim.korap.query.cosmas2.c2psParser;
+import de.ids_mannheim.korap.query.parse.cosmas.c2psLexer;
+import de.ids_mannheim.korap.query.parse.cosmas.c2psParser;
 import de.ids_mannheim.korap.query.serialize.util.Antlr3DescriptiveErrorListener;
 import de.ids_mannheim.korap.query.serialize.util.ResourceMapper;
 import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 
 import org.antlr.runtime.ANTLRStringStream;
 import org.antlr.runtime.RecognitionException;
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 1429d9b..0c1da76 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,10 +1,10 @@
 package de.ids_mannheim.korap.query.serialize;
 
-import de.ids_mannheim.korap.query.poliqarp.PoliqarpPlusLexer;
-import de.ids_mannheim.korap.query.poliqarp.PoliqarpPlusParser;
+import de.ids_mannheim.korap.query.parse.poliqarpplus.PoliqarpPlusLexer;
+import de.ids_mannheim.korap.query.parse.poliqarpplus.PoliqarpPlusParser;
 import de.ids_mannheim.korap.query.serialize.util.Antlr4DescriptiveErrorListener;
 import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 
 import org.antlr.v4.runtime.*;
 import org.antlr.v4.runtime.tree.ParseTree;
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpTree.java
deleted file mode 100644
index 614fcdd..0000000
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpTree.java
+++ /dev/null
@@ -1,468 +0,0 @@
-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 java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-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 org.slf4j.LoggerFactory;
-
-import de.ids_mannheim.korap.query.poliqarp.PoliqarpPlusLexer;
-import de.ids_mannheim.korap.query.poliqarp.PoliqarpPlusParser;
-import de.ids_mannheim.korap.query.serialize.AbstractSyntaxTree;
-
-/**
- * Map representation of Poliqarp syntax tree as returned by ANTLR
- * @author joachim
- *
- */
-public class PoliqarpTree extends Antlr4AbstractSyntaxTree {
-    private static org.slf4j.Logger log = LoggerFactory
-            .getLogger(PoliqarpTree.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;
-	/**
-	 * Parser object deriving the ANTLR parse tree.
-	 */
-	static Parser poliqarpParser;
-	/**
-	 * 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 sequences.
-	 */
-	LinkedList<LinkedHashMap<String,Object>> sequenceStack = new LinkedList<LinkedHashMap<String,Object>>();
-	/**
-	 * Keeps track of active tokens.
-	 */
-	LinkedList<LinkedHashMap<String,Object>> tokenStack = new LinkedList<LinkedHashMap<String,Object>>();
-	/**
-	 * Keeps track of sequence/token/field groups.
-	 */
-	LinkedList<ArrayList<Object>> groupStack = new LinkedList<ArrayList<Object>>();
-	/**
-	 * Marks the currently active object (sequence/token/group...) in order to know where to add stuff like occurrence info etc.
-	 */
-	LinkedHashMap<String,Object> curObject = new 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>();
-	
-	/**
-	 * 
-	 * @param tree The syntax tree as returned by ANTLR
-	 * @param parser The ANTLR parser instance that generated the parse tree
-	 */
-	public PoliqarpTree(String query) {
-		prepareContext();
-		process(query);
-		System.out.println(">>> "+requestMap+" <<<");
-	}
-
-	private void prepareContext() {
-		LinkedHashMap<String,Object> context = new LinkedHashMap<String,Object>();
-		LinkedHashMap<String,Object> operands = new LinkedHashMap<String,Object>();
-		LinkedHashMap<String,Object> relation = new LinkedHashMap<String,Object>();
-		LinkedHashMap<String,Object> classMap = new LinkedHashMap<String,Object>();
-		
-		operands.put("@id", "korap:operands");
-		operands.put("@container", "@list");
-		
-		relation.put("@id", "korap:relation");
-		relation.put("@type", "korap:relation#types");
-		
-		classMap.put("@id", "korap:class");
-		classMap.put("@type", "xsd:integer");
-		
-		context.put("korap", "http://korap.ids-mannheim.de/ns/query");
-		context.put("@language", "de");
-		context.put("operands", operands);
-		context.put("relation", relation);
-		context.put("class", classMap);
-		context.put("query", "korap:query");
-		context.put("filter", "korap:filter");
-		context.put("meta", "korap:meta");
-		
-		requestMap.put("@context", context);		
-	}
-
-	@Override
-	public Map<String, Object> getRequestMap() {
-		return requestMap;
-	}
-	
-	@Override
-	public void process(String query) {
-		ParseTree tree = parsePoliqarpQuery(query);
-		log.info("Processing Poliqarp query.");
-		System.out.println("Processing Poliqarp");
-		processNode(tree);
-		log.info(requestMap.toString());
-	}
-	
-	@SuppressWarnings("unchecked")
-	private void processNode(ParseTree node) {
-		// Top-down processing
-		if (visited.contains(node)) return;
-		else visited.add(node);
-		
-		String nodeCat = getNodeCat(node);
-		openNodeCats.push(nodeCat);
-		
-//		System.out.println(openNodeCats);
-
-		/*
-		 ****************************************************************
-		 **************************************************************** 
-		 * 			Processing individual node categories  				*
-		 ****************************************************************
-		 ****************************************************************
-		 */
-		if (nodeCat.equals("query")) {
-		}
-
-		// cq_segments/sq_segments: token group
-		if (nodeCat.equals("cq_segments") || nodeCat.equals("sq_segments")) {
-			// disregard empty segments in simple queries (parsed by ANTLR as empty cq_segments)
-			if (node.getChildCount() > 0 && !node.getChild(0).toStringTree(poliqarpParser).equals(" ")) {
-				LinkedHashMap<String,Object> sequence = new LinkedHashMap<String,Object>();
-				curObject = sequence;
-				// Step I: decide type of element (one or more elements? -> token or sequence)
-				if (node.getChildCount()>1) {
-					sequence.put("@type", "korap:sequence");
-					ArrayList<Object> sequenceOperands = new ArrayList<Object>();
-					sequence.put("operands", sequenceOperands);
-				} else {
-					// if only child, make the sequence a mere korap:token
-					sequence.put("@type", "korap:token");
-					tokenStack.push(sequence);
-				}
-				// Step II: decide where to put this element (top query node or embedded in super sequence?)
-				if (openNodeCats.get(1).equals("query")) {
-					requestMap.put("query", sequence);
-				} else if (!groupStack.isEmpty()) {
-					groupStack.getFirst().add(sequence);
-				} else {
-					ArrayList<Object> topSequenceOperands = (ArrayList<Object>) sequenceStack.getFirst().get("operands");
-					topSequenceOperands.add(sequence);
-				}
-				sequenceStack.push(sequence);
-			}
-		}
-		
-		// cq_segment
-		if (nodeCat.equals("cq_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);
-			} else {
-				// in case cq_segments has already added the token
-				token = tokenStack.getFirst();
-			}
-			curObject = token;
-			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")
-			if (node.getParent().getChildCount()>1) {
-				ArrayList<Object> topSequenceOperands = (ArrayList<Object>) sequenceStack.getFirst().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>();
-			curObject = disjunction;
-			ArrayList<Object> disjOperands = new ArrayList<Object>();
-			disjunction.put("@type", "korap:group");
-			disjunction.put("relation", "or");
-			disjunction.put("operands", disjOperands);
-			groupStack.push(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>) sequenceStack.getFirst().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 featureName = node.getChild(0).getChild(0).toStringTree(poliqarpParser);   //e.g. (field_name base) (field_op !=) (re_query "bar*")
-			String relation = node.getChild(1).getChild(0).toStringTree(poliqarpParser);
-			String value = "";
-			ParseTree 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(poliqarpParser);   //e.g. (simple_query (sq_segment foo))
-			} else if (valType.equals("re_query")) {
-				value = valNode.getChild(0).toStringTree(poliqarpParser); 				//e.g. (re_query "bar*")
-				fieldMap.put("@subtype", "korap:value#regex");
-			}
-			fieldMap.put("@value", featureName+":"+value);
-			fieldMap.put("relation", 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("@value", fieldMap);
-				} else {
-					((HashMap<String, Object>) requestMap.get("meta")).put("@value", fieldMap);
-				}
-			} else {
-				fieldStack.getFirst().add(fieldMap);
-			}
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(1));
-			visited.add(node.getChild(2));
-		}
-		
-		// conj_field serves for both conjunctions and disjunctions
-		if (nodeCat.equals("conj_field")) {
-			LinkedHashMap<String,Object> group = new LinkedHashMap<String,Object>(); 
-			ArrayList<Object> groupOperands = new ArrayList<Object>();
-			
-			group.put("@type", "korap:group");
-			group.put("operands", groupOperands);
-			fieldStack.push(groupOperands);
-			
-			// Step I: get operator (& or |)
-			ParseTree operatorNode = node.getChild(1).getChild(0);
-			String operator = getNodeCat(operatorNode);
-			if (operator.equals("|")) {
-				group.put("relation", "or");
-			} else if (operator.equals("&")) {
-				group.put("relation", "and");
-			}
-			
-			// 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("@value", group);
-			} else if (openNodeCats.get(1).equals("meta_field_group")) {
-				((HashMap<String, Object>) requestMap.get("meta")).put("@value", group);
-			} else {
-				fieldStack.get(1).add(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);
-			} else {
-				// in case sq_segments has already added the token
-				token = tokenStack.getFirst();
-			}
-			curObject = token;
-			curToken = token;
-			// Step II: fill object (token values) and put into containing sequence
-			token.put("@type", "korap:token");
-			String word = node.getChild(0).toStringTree(poliqarpParser);
-			LinkedHashMap<String,Object> tokenValues = new LinkedHashMap<String,Object>();
-			token.put("@value", tokenValues);
-			tokenValues.put("orth", word);
-			tokenValues.put("relation", "=");
-			
-			// 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>) sequenceStack.getFirst().get("operands");
-				topSequenceOperands.add(token);
-			}
-		}
-		
-		// repetition of token group
-		if (nodeCat.equals("occ")) {
-			ParseTree occChild = node.getChild(0);
-			String repetition = occChild.toStringTree(poliqarpParser);
-			curObject.put("repetition", repetition);
-			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
-			((HashMap<String, Object>) curToken.get("@value")).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")) {
-			ParseTree domainNode = node.getChild(2);
-			String domain = getNodeCat(domainNode);
-//			queryOperands.add("within:"+domain);
-			curObject.put("within", domain);
-			visited.add(node.getChild(0));
-			visited.add(node.getChild(1));
-			visited.add(domainNode);
-		}
-		
-		/*
-		 ****************************************************************
-		 **************************************************************** 
-		 *  recursion until 'request' node (root of tree) is processed  *
-		 * **************************************************************
-		 ****************************************************************
-		 */
-		for (int i=0; i<node.getChildCount(); i++) {
-			ParseTree child = node.getChild(i);
-			processNode(child);
-		}
-				
-		// Stuff that happens when leaving a node (taking it off the stack)
-		if (nodeCat.equals("cq_segments") || nodeCat.equals("sq_segments")) {
-			// exclude whitespaces analysed as empty cq_segments
-			if (node.getChildCount() > 0 && !getNodeCat(node.getChild(0)).equals(" ")) {
-				sequenceStack.pop();
-			}
-		}
-		
-		if (nodeCat.equals("cq_disj_segments")) {
-			groupStack.pop();
-		}
-		
-		if (nodeCat.equals("cq_segment") || nodeCat.equals("sq_segment")){
-			tokenStack.pop();
-		}
-		
-		if (nodeCat.equals("conj_field")) {
-			fieldStack.pop();
-		}
-		
-		openNodeCats.pop();
-		
-	}
-
-//	/**
-//	 * Returns the category (or 'label') of the root of a ParseTree.
-//	 * @param node
-//	 * @return
-//	 */
-//	public String getNodeCat(ParseTree node) {
-//		String nodeCat = node.toStringTree(poliqarpParser);
-//		Pattern p = Pattern.compile("\\((.*?)\\s"); // from opening parenthesis to 1st whitespace
-//		Matcher m = p.matcher(node.toStringTree(poliqarpParser));
-//		if (m.find()) {
-//			nodeCat = m.group(1);
-//		} 
-//		return nodeCat;
-//	}
-	
-	private static ParserRuleContext parsePoliqarpQuery (String p) {
-		Lexer poliqarpLexer = new PoliqarpPlusLexer((CharStream)null);
-	    ParserRuleContext tree = null;
-	    // Like p. 111
-	    try {
-
-	      // Tokenize input data
-	      ANTLRInputStream input = new ANTLRInputStream(p);
-	      poliqarpLexer.setInputStream(input);
-	      CommonTokenStream tokens = new CommonTokenStream(poliqarpLexer);
-	      poliqarpParser = new PoliqarpPlusParser(tokens);
-
-	      // Don't throw out erroneous stuff
-	      poliqarpParser.setErrorHandler(new BailErrorStrategy());
-	      poliqarpParser.removeErrorListeners();
-
-	      // Get starting rule from parser
-	      Method startRule = PoliqarpPlusParser.class.getMethod("request");
-	      tree = (ParserRuleContext) startRule.invoke(poliqarpParser, (Object[])null);
-	    }
-
-	    // Some things went wrong ...
-	    catch (Exception e) {
-	    	log.error(e.getMessage());
-	    	System.err.println( e.getMessage() );
-	    }
-
-	    // Return the generated tree
-	    return tree;
-	  }
-	
-	public static void main(String[] args) {
-		/*
-		 * For testing
-		 */
-		String[] queries = new String[] {
-//				"[base=foo]|([base=foo][base=bar])*",
-//				"([base=foo]|[base=bar])[base=foobar]",
-//				"[base=foo]([base=bar]|[base=foobar/i])",
-//				"[base=bar|base=foo]",
-//				"[base=bar]",
-//				"[base=foo][base=bar]",
-//				"[(base=bar|base=foo)&orth=wee]",
-//				"[base=foo/i][base=bar]{2,4}",
-//				"foo bar/i"
-				"[base=foo] meta author=Goethe&year=1885",
-				"[base=foo]|([base=foo][base=bar])* meta author=Goethe&year=1815",
-				"[base=foo]*",
-				};
-		for (String q : queries) {
-			try {
-				System.out.println(q);
-				System.out.println(PoliqarpTree.parsePoliqarpQuery(q).toStringTree(PoliqarpTree.poliqarpParser));
-				@SuppressWarnings("unused")
-				PoliqarpTree pt = new PoliqarpTree(q);
-				System.out.println(PoliqarpTree.parsePoliqarpQuery(q).toStringTree(PoliqarpTree.poliqarpParser));
-				System.out.println();
-				
-			} catch (NullPointerException npe) {
-				npe.printStackTrace();
-				System.out.println("null\n");
-			}
-		}
-	}
-
-}
\ No newline at end of file
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java b/src/main/java/de/ids_mannheim/korap/query/serialize/QuerySerializer.java
index 635b2c8..fb8104f 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
@@ -4,7 +4,7 @@
 import com.fasterxml.jackson.databind.JsonMappingException;
 
 import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.KorAPLogger;
 
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java b/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
index 2f5c237..537e578 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
@@ -1,9 +1,5 @@
 package de.ids_mannheim.korap.query.serialize;
 
-import de.ids_mannheim.korap.util.QueryException;
-
-import org.apache.commons.lang.StringUtils;
-
 import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -11,7 +7,6 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.Stack;
 import java.util.regex.Matcher;
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java b/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java
index 7030f5c..d64e983 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/TreeTemplate.java
@@ -15,9 +15,9 @@
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTree;
 
-import de.ids_mannheim.korap.query.annis.AqlLexer;
-import de.ids_mannheim.korap.query.annis.AqlParser;
-import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.query.parse.annis.AqlLexer;
+import de.ids_mannheim.korap.query.parse.annis.AqlParser;
+import de.ids_mannheim.korap.query.serialize.util.QueryException;
 
 /**
  * Map representation of syntax tree as returned by ANTLR
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java
index 2a0fb63..6ae78b9 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/Antlr3DescriptiveErrorListener.java
@@ -5,7 +5,7 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import de.ids_mannheim.korap.query.cosmas2.IErrorReporter;
+import de.ids_mannheim.korap.query.parse.cosmas.IErrorReporter;
 import de.ids_mannheim.korap.query.serialize.QueryUtils;
 
 /**
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/QueryException.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/QueryException.java
new file mode 100644
index 0000000..ff63f79
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/QueryException.java
@@ -0,0 +1,36 @@
+package de.ids_mannheim.korap.query.serialize.util;
+
+public class QueryException extends Exception {
+	
+  int errorCode;
+  
+  public QueryException() {
+      super();
+  }
+
+  public QueryException(String message) {
+      super(message);
+  }
+
+  public QueryException(String message, Throwable cause) {
+      super(message, cause);
+  };
+
+  public QueryException(Throwable cause) {
+      super(cause);
+  };  
+  
+  public QueryException(int code, String message) {	  
+	  super(message);
+	  setErrorCode(code);      
+  }
+
+  public int getErrorCode() {
+	return errorCode;
+  }
+
+  public void setErrorCode(int errorCode) {
+	this.errorCode = errorCode;
+  }
+
+};