cosmas #BED() operator: multiple arguments
diff --git a/notes.txt b/notes.txt
index 40da149..a89cf6c 100644
--- a/notes.txt
+++ b/notes.txt
@@ -8,7 +8,9 @@
    the query expresses a sequence of terms) and more in line with other QLs (e.g. Poliqarp)
  - distance operators allow to specify a minimal and maximal distance between their arguments, in the form "/wn:m" where n and m are integers. In case only one number
    is given (like "/w2"), Cosmas II interprets this as the maximal distance. Note that it is not possible to specify a minimal but possibly infinite distance between to
-   tokens - for obvious reasons. 
+   tokens - for obvious reasons.
+ - distance operator: flip arguments and change 'minus' to 'plus' 
  - operands of distance operators to be expressed via shrink/classes?
  - #BEG() and #END() are solved via shrink, with the shrink argument not being a class but a position (first/last) indicating the first or last word in the matched sequence  
-   
\ No newline at end of file
+ - #BED() with two conditions (like 'sa,-pa') can't be mapped to position group as implemented -> make two position groups and embed in 'and'-group
+ 
\ No newline at end of file
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 49e948d..a84249f 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
@@ -359,7 +359,8 @@
 			String subtype = typ.getChild(0).toStringTree().equals("PROX") ? "incl" : "excl"; 
 			proxGroup.put("@subtype", subtype);
 			proxGroup.put("constraint", constraints);
-			proxGroup.put("operands", new ArrayList<Object>());
+			ArrayList<Object> operands = new ArrayList<Object>(); 
+			proxGroup.put("operands", operands);
 			
 			// if only one dist_info, put directly into constraints
 			if (dist_list.getChildCount()==1) {
@@ -370,6 +371,10 @@
 				if (min.equals("VAL0")) {
 					min="0";
 				}
+				if (direction.equals("minus")) {
+					direction = "plus";
+					invertedOperandsLists.add(operands);
+				}
 				LinkedHashMap<String, Object> distance = new LinkedHashMap<String, Object>();
 				distance.put("@type", "korap:distance");
 				distance.put("measure", meas);
@@ -462,38 +467,53 @@
 		
 		if (nodeCat.equals("OPEND") || nodeCat.equals("OPBEG")) {
 			// Step I: create group
-			LinkedHashMap<String, Object> bedgroup = new LinkedHashMap<String, Object>();
-			bedgroup.put("@type", "korap:group");
-			bedgroup.put("relation", "shrink");
+			LinkedHashMap<String, Object> beggroup = new LinkedHashMap<String, Object>();
+			beggroup.put("@type", "korap:group");
+			beggroup.put("relation", "shrink");
 			String reduction = nodeCat.equals("OPBEG") ? "first" : "last";
-			bedgroup.put("shrink", reduction);
-			bedgroup.put("operands", new ArrayList<Object>());
-			objectStack.push(bedgroup);
+			beggroup.put("shrink", reduction);
+			beggroup.put("operands", new ArrayList<Object>());
+			objectStack.push(beggroup);
 			stackedObjects++;
 			
 			// Step II: decide where to put
-			putIntoSuperObject(bedgroup, 1);
+			putIntoSuperObject(beggroup, 1);
 		}
 		
 		if (nodeCat.equals("OPBED")) {
 			// Step I: create group
-			LinkedHashMap<String, Object> posgroup = new LinkedHashMap<String, Object>();
-			posgroup.put("@type", "korap:group");
-			posgroup.put("relation", "position");
 			int optsChild = node.getChildCount()-1;
-			String cond = node.getChild(optsChild).getChild(0).getChild(0).getText(); //(OPBED (OPWF "xyz") (OPTS (TPBEG se)))
-			String elem = cond.startsWith("+") ? cond.substring(1,2) : cond.substring(0,1);
-			bedElem = new LinkedHashMap<String, Object>();
-			bedElem.put("@type", "korap:elem");
-			bedElem.put("@value", elem);
-			String position = cond.substring(cond.length()-1).equals("a") ? "startswith" : "endswith";
-			posgroup.put("position", position);
-			posgroup.put("operands", new ArrayList<Object>());
-			objectStack.push(posgroup);
-			stackedObjects++;
-			
-			// Step II: decide where to put
-			putIntoSuperObject(posgroup, 1);
+			Tree conditions = node.getChild(optsChild);
+			if (conditions.getChildCount()==1) {
+				LinkedHashMap<String, Object> posgroup = new LinkedHashMap<String, Object>();
+				posgroup.put("@type", "korap:group");
+				posgroup.put("relation", "position");
+				String cond = conditions.getChild(0).getChild(0).getText(); //(OPBED (OPWF "xyz") (OPTS (TPBEG se)))
+				//TODO: minus
+				String elem = cond.startsWith("+") ? cond.substring(1,2) : cond.substring(0,1);
+				bedElem = new LinkedHashMap<String, Object>();
+				bedElem.put("@type", "korap:elem");
+				bedElem.put("@value", elem);
+				String position = cond.substring(cond.length()-1).equals("a") ? "startswith" : "endswith";
+				posgroup.put("position", position);
+				posgroup.put("operands", new ArrayList<Object>());
+				objectStack.push(posgroup);
+				stackedObjects++;
+				// Step II: decide where to put
+				putIntoSuperObject(posgroup, 1);
+			} else {
+				// node has several conditions (like 'sa, -pa')
+				// -> create 'and' group and embed all position groups there
+				LinkedHashMap<String, Object> conjunct = new LinkedHashMap<String, Object>();
+				conjunct.put("@type", "korap:group");
+				conjunct.put("relation", "and");
+				ArrayList<Object> operands = new ArrayList<Object>();
+				conjunct.put("operands", operands);
+				for (int i=0; i<conditions.getChildCount(); i++) {
+					// TODO for each condition, create a position group. problem: how to get argument into every operands list?
+				}
+			}
+
 		}
 		
 		
@@ -529,7 +549,7 @@
 			System.err.println(objectStack);
 			@SuppressWarnings("unchecked")
 			ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(0).get("operands");
-			topObjectOperands.add(bedElem);
+			topObjectOperands.add(0, bedElem);
 		}
 		
 		for (int i=0; i<objectsToPop.get(0); i++) {
@@ -758,7 +778,9 @@
 				"wegen #IN(%, L) <s>",
 				"wegen #OV('FE,%,MIN') <s>",
 				"#BEG(der /+w1:2 Mann)",
-				"#BEG(der Mann /10w Mann)"
+				"#BEG(der Mann /10w Mann)",
+				"#BED(der Mann , sa,+pe)",
+//				"#BED(der Mann , +pe)"
 				/*
 				 * TODO
 				 * http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/ARGUMENT_I.html
diff --git a/src/test/java/CosmasTreeTest.java b/src/test/java/CosmasTreeTest.java
index 6837282..d30e9ff 100644
--- a/src/test/java/CosmasTreeTest.java
+++ b/src/test/java/CosmasTreeTest.java
@@ -233,6 +233,46 @@
 		ppt = new CosmasTree(query);
 		map = ppt.getRequestMap().get("query").toString();
 		assertEquals(prox4.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		
+		query="Sonne /-w4 Mond";
+		String prox5 = 
+					"{@type=korap:group, relation=distance, match=operands, @subtype=incl, " +
+						"constraint=[" +
+							"{@type=korap:distance, measure=w, direction=plus, min=0, max=4}" +
+						"], " +
+						"operands=[" +
+							"{@type=korap:token, @value={@type=korap:term, @value=orth:Mond, relation==}}," +
+							"{@type=korap:token, @value={@type=korap:term, @value=orth:Sonne, relation==}}" +
+						"]" +
+					"}";
+		ppt = new CosmasTree(query);
+		map = ppt.getRequestMap().get("query").toString();
+		assertEquals(prox5.replaceAll(" ", ""), map.replaceAll(" ", ""));
+	}
+	
+	@Test
+	public void testNestedOPPROX() throws QueryException {	
+		query="Sonne /-w4 Mond /+w2 Sterne";
+		String prox6 = 
+					"{@type=korap:group, relation=distance, match=operands, @subtype=incl, " +
+						"constraint=[" +
+							"{@type=korap:distance, measure=w, direction=plus, min=0, max=4}" +
+						"], " +
+						"operands=[" +
+							"{@type=korap:group, relation=distance, match=operands, @subtype=incl, " +
+								"constraint=[" +
+									"{@type=korap:distance, measure=w, direction=plus, min=0, max=2}" +
+								"], " +
+								"operands=[" +
+									"{@type=korap:token, @value={@type=korap:term, @value=orth:Mond, relation==}}," +
+									"{@type=korap:token, @value={@type=korap:term, @value=orth:Sterne, relation==}}" +
+								"]}," +
+							"{@type=korap:token, @value={@type=korap:term, @value=orth:Sonne, relation==}}" +
+						"]" +
+					"}";
+		ppt = new CosmasTree(query);
+		map = ppt.getRequestMap().get("query").toString();
+		assertEquals(prox6.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
 	@Test
@@ -292,31 +332,6 @@
 		ppt = new CosmasTree(query);
 		map = ppt.getRequestMap().get("query").toString();
 		assertEquals(opin4.replaceAll(" ", ""), map.replaceAll(" ", ""));
-		
-//		// position argument is optional 
-//		query="wegen #IN <s>";
-//		String opin2 = 
-//					"{@type=korap:group, relation=include, operands=[" +
-//						"{@type=korap:token, @value={@type=korap:term, @value=orth:wegen, relation==}}," +
-//						"{@type=korap:elem, @value=s}" +
-//					"]}";
-//		ppt = new CosmasTree(query);
-//		map = ppt.getRequestMap().get("query").toString();
-//		assertEquals(opin2.replaceAll(" ", ""), map.replaceAll(" ", ""));
-//		
-//		// parentheses around 'wegen mir' are optional
-//		query="wegen #IN (wegen mir)";
-//		String opin3 = 
-//					"{@type=korap:group, relation=include, operands=[" +
-//						"{@type=korap:token, @value={@type=korap:term, @value=orth:wegen, relation==}}," +
-//						"{@type=korap:sequence, operands=[" +
-//							"{@type=korap:token, @value={@type=korap:term, @value=orth:wegen, relation==}}," +
-//							"{@type=korap:token, @value={@type=korap:term, @value=orth:mir, relation==}}" +
-//						"]}" +
-//					"]}";
-//		ppt = new CosmasTree(query);
-//		map = ppt.getRequestMap().get("query").toString();
-//		assertEquals(opin3.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
 	@Test
@@ -435,18 +450,15 @@
 	public void testOPALL() throws QueryException {
 		query="#ALL(gehen /w1:10 voran)";
 		String all1 = 
-//				"{@type=korap:group, relation=all, operands=[" +
-					"{@type=korap:group, relation=distance, match=all, @subtype=incl, " +
-						"constraint=[" +
-							"{@type=korap:distance, measure=w, direction=both, min=1, max=10}" +
-						"], " +
-						"operands=[" +
-							"{@type=korap:token, @value={@type=korap:term, @value=orth:gehen, relation==}}," +
-							"{@type=korap:token, @value={@type=korap:term, @value=orth:voran, relation==}}" +
-						"]" +
-					"}" //+
-//				"]}"
-					;
+				"{@type=korap:group, relation=distance, match=all, @subtype=incl, " +
+					"constraint=[" +
+						"{@type=korap:distance, measure=w, direction=both, min=1, max=10}" +
+					"], " +
+					"operands=[" +
+						"{@type=korap:token, @value={@type=korap:term, @value=orth:gehen, relation==}}," +
+						"{@type=korap:token, @value={@type=korap:term, @value=orth:voran, relation==}}" +
+					"]" +
+				"}";
 		ppt = new CosmasTree(query);
 		map = ppt.getRequestMap().get("query").toString();
 		assertEquals(all1.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -456,18 +468,15 @@
 	public void testOPNHIT() throws QueryException {
 		query="#NHIT(gehen /w1:10 voran)";
 		String nhit1 = 
-//				"{@type=korap:group, relation=nhit, operands=[" +
-					"{@type=korap:group, relation=distance, match=between, @subtype=incl, " +
-						"constraint=[" +
-							"{@type=korap:distance, measure=w, direction=both, min=1, max=10}" +
-						"], " +
-						"operands=[" +
-							"{@type=korap:token, @value={@type=korap:term, @value=orth:gehen, relation==}}," +
-							"{@type=korap:token, @value={@type=korap:term, @value=orth:voran, relation==}}" +
-						"]" +
-					"}" //+
-//				"]}"
-					;
+				"{@type=korap:group, relation=distance, match=between, @subtype=incl, " +
+					"constraint=[" +
+						"{@type=korap:distance, measure=w, direction=both, min=1, max=10}" +
+					"], " +
+					"operands=[" +
+						"{@type=korap:token, @value={@type=korap:term, @value=orth:gehen, relation==}}," +
+						"{@type=korap:token, @value={@type=korap:term, @value=orth:voran, relation==}}" +
+					"]" +
+				"}";
 		ppt = new CosmasTree(query);
 		map = ppt.getRequestMap().get("query").toString();
 		assertEquals(nhit1.replaceAll(" ", ""), map.replaceAll(" ", ""));
@@ -478,8 +487,8 @@
 		query = "#BED(der , sa)";
 		String bed1 = 
 				"{@type=korap:group, relation=position, position=startswith, operands=[" +
-					"{@type=korap:token, @value={@type=korap:term, @value=orth:der, relation==}}," +
-					"{@type=korap:elem, @value=s}" +
+						"{@type=korap:elem, @value=s}," +
+					"{@type=korap:token, @value={@type=korap:term, @value=orth:der, relation==}}" +
 				"]}";
 		ppt = new CosmasTree(query);
 		map = ppt.getRequestMap().get("query").toString();
@@ -488,15 +497,37 @@
 		query = "#BED(der Mann , +pe)";
 		String bed2 = 
 				"{@type=korap:group, relation=position, position=endswith, operands=[" +
+					"{@type=korap:elem, @value=p}," +
 					"{@type=korap:sequence, operands=[" +
 						"{@type=korap:token, @value={@type=korap:term, @value=orth:der, relation==}}," +
 						"{@type=korap:token, @value={@type=korap:term, @value=orth:Mann, relation==}}" +
-					"]}," +
-					"{@type=korap:elem, @value=p}" +
+					"]}" +
 				"]}";
 		ppt = new CosmasTree(query);
 		map = ppt.getRequestMap().get("query").toString();
 		assertEquals(bed2.replaceAll(" ", ""), map.replaceAll(" ", ""));
+		
+		query = "#BED(der Mann , sa,-pa)";
+		String bed3 = 
+				"{@type=korap:group, relation=and, operands=[" +
+					"{@type=korap:group, relation=position, position=startswith, operands=[" +
+						"{@type=korap:elem, @value=s}," +
+						"{@type=korap:sequence, operands=[" +
+							"{@type=korap:token, @value={@type=korap:term, @value=orth:der, relation==}}," +
+							"{@type=korap:token, @value={@type=korap:term, @value=orth:Mann, relation==}}" +
+						"]}" +
+					"]}," +
+					"{@type=korap:group, relation=position, position=startswith, @subtype=excl, operands=[" +
+						"{@type=korap:elem, @value=p}," +
+						"{@type=korap:sequence, operands=[" +
+							"{@type=korap:token, @value={@type=korap:term, @value=orth:der, relation==}}," +
+							"{@type=korap:token, @value={@type=korap:term, @value=orth:Mann, relation==}}" +
+						"]}" +
+					"]}" +
+				"]}";
+		ppt = new CosmasTree(query);
+		map = ppt.getRequestMap().get("query").toString();
+		assertEquals(bed3.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
 }