diff --git a/pom.xml b/pom.xml
index a4a0098..f92fff3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,7 +61,7 @@
 	  <source>1.7</source>
 	  <target>1.7</target>
 	  <excludes>
-          <!--exclude>**/CosmasTree.java</exclude-->
+          <exclude>**/CosmasTree.java</exclude>
       </excludes>
 	</configuration>
       </plugin>
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
new file mode 100644
index 0000000..4ea14eb
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CosmasTree.java
@@ -0,0 +1,347 @@
+package de.ids_mannheim.korap.query.serialize;
+
+import java.util.ArrayList;
+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.runtime.ANTLRStringStream;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.tree.Tree;
+
+import de.ids_mannheim.korap.query.cosmas2.c2psLexer;
+import de.ids_mannheim.korap.query.cosmas2.c2psParser;
+
+/**
+ * Map representation of CosmasII syntax tree as returned by ANTLR
+ * @author joachim
+ *
+ */
+public class CosmasTree extends AbstractSyntaxTree {
+	
+	private static c2psParser cosmasParser;
+	/*
+	 * Following collections have the following functions:
+	 * - the request is a map with two keys (meta/query):			{meta=[], query=[]}
+	 * - the query is a list of token group maps: 					{meta=[], query=[tg1=[], tg2=[]]}
+	 * - each token group is a list of tokens: 						{meta=[], query=[tg1=[t1_1, t1_2], tg2=[t2_1, t2_2, t2_3]]}
+	 * - each token corresponds to a single 'fields' linked list	{meta=[], query=[tg1=[t1_1=[], t1_2=[]], ... ]}
+	 * - each fields list contains a logical operator and 'field maps' defining attributes and values
+	 * 																{meta=[], query=[tg1=[t1_1=[[disj, {base=foo}, {base=bar}]], t1_2=[]], ... ]}
+	 */
+	String query;
+	LinkedHashMap<String,Object> requestMap = new LinkedHashMap<String,Object>();
+	LinkedHashMap<String,Object> queryMap = new LinkedHashMap<String,Object>();
+	LinkedHashMap<String,Object> tokenGroup = new LinkedHashMap<String,Object>();
+	ArrayList<Object> fieldGroup = new ArrayList<Object>(); 
+	LinkedHashMap<String,Object> fieldMap;
+	ArrayList<List<Object>> distantTokens;
+	/**
+	 * Makes it possible to store several distantTokenGroups
+	 */
+	LinkedList<ArrayList<List<Object>>> distantTokensStack = new LinkedList<ArrayList<List<Object>>>();
+	/**
+	 * Field for repetition query (Kleene + or * operations, or min/max queries: {2,4}
+	 */
+	String repetition = "";
+	int tokenCount=0;
+	int tokenGroupCount=0;
+	/**
+	 * Keeps track of open node categories
+	 */
+	LinkedList<String> openNodeCats = new LinkedList<String>();
+	/**
+	 * Global control structure for fieldGroups, keeps track of open fieldGroups.
+	 */
+	LinkedList<ArrayList<Object>> openFieldGroups = new LinkedList<ArrayList<Object>>();
+	/**
+	 * Global control structure for tokenGroups, keeps track of open tokenGroups.
+	 */
+	LinkedList<LinkedHashMap<String,Object>> tokenGroupsStack = new LinkedList<LinkedHashMap<String,Object>>();
+	/**
+	 * Flag that indicates whether token fields or meta fields are currently being processed
+	 */
+	boolean inMeta = false;
+	boolean negate = false;
+	
+	Tree cosmasTree;
+	
+	LinkedHashMap<String,Object> treeMap = new LinkedHashMap<String,Object>();
+	/**
+	 * Keeps track of all visited nodes in a tree
+	 */
+	List<Tree> visited = new ArrayList<Tree>();
+	  
+	
+	/**
+	 * 
+	 * @param tree The syntax tree as returned by ANTLR
+	 * @param parser The ANTLR parser instance that generated the parse tree
+	 */
+	public CosmasTree(String query) {
+		this.query = query;
+		process(query);
+		System.out.println(requestMap);
+	}
+	
+	@Override
+	public Map<String, Object> getRequestMap() {
+		return this.requestMap;
+	}
+	
+	@Override
+	public void process(String query) {
+		Tree tree = parseCosmasQuery(query);
+		System.out.println("Processing Cosmas");
+		processNode(tree);
+	}
+	
+	private void processNode(Tree node) {
+		
+		// Top-down processing
+		if (visited.contains(node)) return;
+		else visited.add(node);
+		
+		
+		String nodeCat = getNodeCat(node);
+		openNodeCats.push(nodeCat);
+		
+		
+		
+		System.out.println(openNodeCats);
+		System.out.println(distantTokensStack);
+		
+		/* ***************************************
+		 * Processing individual node categories *
+		 *****************************************/
+		// C2QP is tree root
+		if (nodeCat.equals("C2PQ")) {
+			queryMap = new LinkedHashMap<String,Object>();
+			requestMap.put("query", queryMap);
+		}
+		
+		// Nodes introducing tokens. Process all in the same manner, except for the fieldMap entry
+		if (nodeCat.equals("OPWF") || nodeCat.equals("OPLEM") || nodeCat.equals("OPMORPH")) {
+			
+			if (tokenGroupsStack.isEmpty()) {
+				tokenGroup = new LinkedHashMap<String, Object>();
+				tokenCount=0;
+				tokenGroupCount++;
+				queryMap.put("tokenGroup"+tokenGroupCount, tokenGroup);
+				tokenGroupsStack.push(tokenGroup);
+			} else {
+				tokenGroup = tokenGroupsStack.getFirst();
+			}
+			
+			// check if this token comes after a distant operator (like "/+w3:4") and if yes,
+			// insert the empty tokenGroups before the current token
+			if (openNodeCats.get(1).equals("ARG2")) {
+				if (openNodeCats.get(2).equals("OPPROX") && !distantTokensStack.isEmpty()) {
+					for (List<Object> distantTokenGroup : distantTokensStack.pop()) {
+//						if (tokenGroupsStack.isEmpty()) {
+//							queryMap.put("token"+tokenGroupCount+"_1", distantTokenGroup);
+//						} else {
+						tokenCount++;
+						tokenGroupsStack.getFirst().put("token"+tokenGroupCount+"_"+tokenCount, distantTokenGroup);
+//						}
+//						tokenGroupCount++;
+					}
+				}  
+				// check negation of token by preceding OPNOT
+//				else if (openNodeCats.get(2).equals("OPNOT")) {
+//					negate = true;
+//				}
+			}
+			
+			fieldGroup = new ArrayList<Object>();
+			tokenCount++;
+			tokenGroup.put("token"+tokenGroupCount+"_"+tokenCount, fieldGroup);
+			
+			fieldMap = new LinkedHashMap<String, Object>();
+			fieldGroup.add(fieldMap);
+			
+			// make category-specific fieldMap entry
+			if (nodeCat.equals("OPWF")) {
+				fieldMap.put("form", node.getChild(0).toStringTree());
+			}
+			if (nodeCat.equals("OPLEM")) {
+				fieldMap.put("lemma", node.getChild(0).toStringTree());
+			}
+			if (nodeCat.equals("OPMORPH")) {
+				fieldMap.put("morph", node.toStringTree());
+				//TODO decompose morphology query
+			}
+			// negate field (see above)
+			if (negate) {
+				fieldMap.put("relation", "!=");
+			}
+			
+//			tokenGroupsStack.push(tokenGroup);
+		}
+		
+		// negate every token that's under OPNOT > ARG2
+		if (nodeCat.equals("ARG2") && openNodeCats.get(1).equals("OPNOT")) {
+			negate = true;
+		}
+		
+		if (nodeCat.equals("OPOR")) {
+			tokenGroup = new LinkedHashMap<String, Object>();
+			tokenCount=0;
+			tokenGroupCount++;
+			if (tokenGroupsStack.isEmpty()) {
+				queryMap.put("tokenGroup"+tokenGroupCount, tokenGroup);
+			} else {
+				tokenGroupsStack.getFirst().put("tokenGroup"+tokenGroupCount, tokenGroup);
+			}
+			tokenGroup.put("type", "disj");
+			tokenGroupsStack.push(tokenGroup);
+		}
+		
+		if (nodeCat.equals("OPAND")) {
+			tokenGroup = new LinkedHashMap<String, Object>();
+			tokenCount=0;
+			tokenGroupCount++;
+			if (tokenGroupsStack.isEmpty()) {
+				queryMap.put("tokenGroup"+tokenGroupCount, tokenGroup);
+			} else {
+				tokenGroupsStack.getFirst().put("tokenGroup"+tokenGroupCount, tokenGroup);
+			}
+			tokenGroup.put("type", "conj");
+			tokenGroupsStack.push(tokenGroup);
+		}
+		
+		if (nodeCat.equals("OPPROX")) {
+			distantTokens = new ArrayList<List<Object>>();
+			Tree prox_opts = node.getChild(0);
+			Tree typ = prox_opts.getChild(0);
+			System.err.println(typ.getChild(0).toStringTree());
+			Tree dist_list = prox_opts.getChild(1);
+			// get relevant information
+			String direction = dist_list.getChild(0).getChild(0).getChild(0).toStringTree();
+			String min = dist_list.getChild(0).getChild(1).getChild(0).toStringTree();
+			String max = dist_list.getChild(0).getChild(1).getChild(1).toStringTree();
+			if (min.equals("VAL0")) {
+				min=max;
+			}
+			// create empty tokens and put them on the stack to place them between arg1 and arg2
+			for (int i=0; i<Integer.parseInt(max)-1; i++) {
+				ArrayList<Object> emptyToken = new ArrayList<Object>();
+				LinkedHashMap<String,Object> emptyFieldMap = new LinkedHashMap<String,Object>();
+				emptyToken.add(emptyFieldMap);
+				tokenGroup.put("token"+tokenGroupCount+"_1", emptyToken);
+				// mark all tokens between min and max optional
+				if (i>=Integer.parseInt(min)) {
+					emptyFieldMap.put("optional", "true");
+				}
+				distantTokens.add(emptyToken);
+			}
+			distantTokensStack.push(distantTokens);
+		}
+		
+		
+//		System.err.println(tokenGroupsStack.size()+" "+tokenGroupsStack);
+		// recursion until 'query' node (root of tree) is processed
+		for (int i=0; i<node.getChildCount(); i++) {
+			Tree child = node.getChild(i);
+			processNode(child);
+		}
+		
+		if (nodeCat.equals("ARG2") && openNodeCats.get(1).equals("OPNOT")) {
+			negate = false;
+		}
+
+		if (nodeCat.equals("OPAND") || nodeCat.equals("OPOR")) {
+			tokenGroupsStack.pop();
+//			tokenGroupCount--;
+//			tokenCount=0;
+		}
+		
+		openNodeCats.pop();
+		
+	}
+
+	/**
+	 * Returns the category (or 'label') of the root of a ParseTree.
+	 * @param node
+	 * @return
+	 */
+	public String getNodeCat(Tree node) {
+		String nodeCat = node.toStringTree();
+		Pattern p = Pattern.compile("\\((.*?)\\s"); // from opening parenthesis to 1st whitespace
+		Matcher m = p.matcher(node.toStringTree());
+		if (m.find()) {
+			nodeCat = m.group(1);
+		} 
+		return nodeCat;
+	}
+	
+	private static Tree parseCosmasQuery(String p) {
+		  Tree tree = null;
+		  ANTLRStringStream
+			ss = new ANTLRStringStream(p);
+		  c2psLexer
+			lex = new c2psLexer(ss);
+		  org.antlr.runtime.CommonTokenStream tokens =   //v3
+	  		new org.antlr.runtime.CommonTokenStream(lex);
+		  cosmasParser = new c2psParser(tokens);
+		  c2psParser.c2ps_query_return
+			c2Return = null;
+		  try 
+			{
+			c2Return = cosmasParser.c2ps_query();  // statt t().
+			}
+		  catch (RecognitionException e) 
+			{
+			e.printStackTrace();
+			}
+		  // AST Tree anzeigen:
+		  tree = (Tree)c2Return.getTree();
+		  return tree;
+	}
+	
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		/*
+		 * For testing
+		 */
+		String[] queries = new String[] {
+				/* COSMAS 2 */
+//				"&Mond",
+//				"Mond Sterne",
+//				"Mond*",
+//				"Mond oder Sterne",
+//				"(des oder eines) /+w2 (Bauern oder Bauers oder Bauerns)",
+//				"(Sonne /+w2 Mond) /+w2:3 Sterne",
+//				"Mond oder Sonne /w2 Sterne",
+//				"MORPH(V PCP)",
+//				"MORPH(V PCP) Baum" ,
+//				"Sonne %w2 Mond",
+//				"Sonne /w2 Mond",
+//				"Sonne nicht (Mond Stern)",
+//				"Sonne nicht (Mond oder Stern)",
+//				"Sonne /+w1:4 Mond",
+				"(sonne und mond) oder sterne",
+				"(stern oder (sonne und mond)) und MORPH(V PCP)",
+				"(sonne und (stern oder mond)) /+w2 luna???",
+				"(Tag /+w2 $offenen) /+w1 Tür",
+				"heißt /+w2 \"und\" ,"
+				};
+		for (String q : queries) {
+			try {
+				System.out.println(q);
+				System.out.println(parseCosmasQuery(q).toStringTree());
+				CosmasTree act = new CosmasTree(q);
+				System.out.println();
+				
+			} catch (NullPointerException npe) {
+				npe.printStackTrace();
+				System.out.println("null\n");
+			}
+		}
+	}
+}
\ No newline at end of file
