Finished query de-serialization from Poliqarp+ examples
diff --git a/src/main/java/de/ids_mannheim/korap/KorapQuery.java b/src/main/java/de/ids_mannheim/korap/KorapQuery.java
index c37ebd1..2ee0623 100644
--- a/src/main/java/de/ids_mannheim/korap/KorapQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KorapQuery.java
@@ -19,7 +19,7 @@
  * @author Nils Diewald
  *
  * KorapQuery implements a simple API for wrapping
- * KorAP Index I specific query classes.
+ * KorAP Lucene Index specific query classes.
  */
 public class KorapQuery {
     private String field;
@@ -54,6 +54,7 @@
 
     // http://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/JsonNode.html
     // TODO: Exception messages are horrible!
+    // Todo: Use the shortcuts implemented in this class instead of the wrapper constructors
     public SpanQueryWrapperInterface fromJSON (JsonNode json) throws QueryException {
 
 	if (!json.has("@type")) {
@@ -100,43 +101,25 @@
 		if (!json.has("position"))
 		    throw new QueryException("Operation needs position specification");
 
-		// temporary
 		String position = json.get("position").asText();
+		short flag = 0;
 		switch (position) {
-		case "contains":
-		    return new SpanWithinQueryWrapper(
-		        this.fromJSON(json.get("operands").get(0)),
-			this.fromJSON(json.get("operands").get(1))
-                    );
-		case "within":
-		    return new SpanWithinQueryWrapper(
-			this.fromJSON(json.get("operands").get(0)),
-			this.fromJSON(json.get("operands").get(1))
-                    );
-
 		case "startswith":
-		    return new SpanWithinQueryWrapper(
-			this.fromJSON(json.get("operands").get(0)),
-			this.fromJSON(json.get("operands").get(1)),
-			(short) 1
-                    );
-
+		    flag = (short) 1;
+		    break;
 		case "endswith":
-		    return new SpanWithinQueryWrapper(
-			this.fromJSON(json.get("operands").get(0)),
-			this.fromJSON(json.get("operands").get(1)),
-			(short) 2
-                    );
-
+		    flag = (short) 2;
+		    break;
 		case "match":
-		    return new SpanWithinQueryWrapper(
-			this.fromJSON(json.get("operands").get(0)),
-			this.fromJSON(json.get("operands").get(1)),
-			(short) 3
-                    );
+		    flag = (short) 3;
+		    break;
 		};
 
-		throw new QueryException("Unknown position type "+json.get("position").asText());
+		return new SpanWithinQueryWrapper(
+		    this.fromJSON(json.get("operands").get(0)),
+		    this.fromJSON(json.get("operands").get(1)),
+		    flag
+	        );
 
 	    case "shrink":
 		int number = 0;
@@ -172,14 +155,33 @@
     private SpanQueryWrapperInterface _segFromJSON (JsonNode json) throws QueryException {
 	String type = json.get("@type").asText();
 	switch (type) {
+
 	case "korap:term":
 	    switch (json.get("relation").asText()) {
 	    case "=":
-		return this.seg(json.get("@value").asText());
+		String value = json.get("@value").asText();
+
+		value = value.replaceFirst("base:", "l:").replaceFirst("orth:", "s:");
+	
+		if (json.has("@subtype") && json.get("@subtype").asText().equals("korap:regex")) {
+		    if (value.charAt(0) == '\'' || value.charAt(0) == '"') {
+			value = "s:" + value;
+		    };
+		    value = value.replace("'", "").replace("\"", "");
+
+		    return this.seg(this.re(value));
+		};
+
+		if (!value.matches("[^:]+?:.+"))
+		    value = "s:" + value;
+
+		return this.seg(value);
+
 	    case "!=":
 		throw new QueryException("Term relation != not yet supported");
 	    };
 	    throw new QueryException("Unknown term relation");
+
 	case "korap:group":
 	    SpanSegmentQueryWrapper ssegqw = new SpanSegmentQueryWrapper(this.field);
 	    switch (json.get("relation").asText()) {
@@ -200,6 +202,12 @@
 		    };
 		};
 		return ssegqw;
+	    case "or":
+		SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(this.field);
+		for (JsonNode operand : json.get("operands")) {
+		    ssaq.or(this._segFromJSON(operand));
+		};
+		return ssaq;
 	    };
     };
     throw new QueryException("Unknown token type");    
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestKorapQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestKorapQueryJSON.java
index 43f9fb1..f6b85c7 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestKorapQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestKorapQueryJSON.java
@@ -30,7 +30,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp1b.json").getFile());
 
 	// [base=foo]|([base=foo][base=bar]) meta author=Goethe&year=1815
-	assertEquals(sqwi.toQuery().toString(), "spanOr([tokens:base:foo, spanNext(tokens:base:foo, tokens:base:bar)])");
+	assertEquals(sqwi.toQuery().toString(), "spanOr([tokens:l:foo, spanNext(tokens:l:foo, tokens:l:bar)])");
     };
 
 
@@ -39,7 +39,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp2.json").getFile());
 
 	// ([base=foo]|[base=bar])[base=foobar]
-	assertEquals(sqwi.toQuery().toString(), "spanNext(spanOr([tokens:base:foo, tokens:base:bar]), tokens:base:foobar)");
+	assertEquals(sqwi.toQuery().toString(), "spanNext(spanOr([tokens:l:foo, tokens:l:bar]), tokens:l:foobar)");
     };
 
     @Test
@@ -47,7 +47,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp3.json").getFile());
 
 	// shrink({[base=Mann]})
-	assertEquals(sqwi.toQuery().toString(), "shrink(0: {0: tokens:base:Mann})");
+	assertEquals(sqwi.toQuery().toString(), "shrink(0: {0: tokens:l:Mann})");
     };
 
     @Test
@@ -55,7 +55,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp4.json").getFile());
 
 	// shrink({[base=foo]}[orth=bar])
-	assertEquals(sqwi.toQuery().toString(), "shrink(0: spanNext({0: tokens:base:foo}, tokens:orth:bar))");
+	assertEquals(sqwi.toQuery().toString(), "shrink(0: spanNext({0: tokens:l:foo}, tokens:s:bar))");
     };
 
     @Test
@@ -63,7 +63,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp5.json").getFile());
 
 	// shrink(1:[base=Der]{1:[base=Mann]}) 
-	assertEquals(sqwi.toQuery().toString(), "shrink(1: spanNext(tokens:base:Der, {1: tokens:base:Mann}))");
+	assertEquals(sqwi.toQuery().toString(), "shrink(1: spanNext(tokens:l:Der, {1: tokens:l:Mann}))");
     };
 
     @Test
@@ -71,7 +71,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp6.json").getFile());
 
 	// [base=katze]
-	assertEquals(sqwi.toQuery().toString(), "tokens:base:Katze");
+	assertEquals(sqwi.toQuery().toString(), "tokens:l:Katze");
     };
 
     @Ignore
@@ -95,7 +95,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp9.json").getFile());
 
 	// [base=Katze&orth=Katzen]
-	assertEquals(sqwi.toQuery().toString(), "spanNear([tokens:base:Katze, tokens:orth:Katzen], -1, false)");
+	assertEquals(sqwi.toQuery().toString(), "spanNear([tokens:l:Katze, tokens:s:Katzen], -1, false)");
     };
 
     @Test
@@ -103,7 +103,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp10.json").getFile());
 
 	// [base=Katze][orth=und][orth=Hunde]
-	assertEquals(sqwi.toQuery().toString(), "spanNext(spanNext(tokens:base:Katze, tokens:orth:und), tokens:orth:Hunde)");
+	assertEquals(sqwi.toQuery().toString(), "spanNext(spanNext(tokens:l:Katze, tokens:s:und), tokens:s:Hunde)");
     };
 
     @Ignore
@@ -119,7 +119,7 @@
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp12.json").getFile());
 
 	// contains(<np>,[base=Mann])
-	assertEquals(sqwi.toQuery().toString(), "spanWithin(<tokens:np />, tokens:base:Mann)");
+	assertEquals(sqwi.toQuery().toString(), "spanWithin(<tokens:np />, tokens:l:Mann)");
     };
 
     @Ignore
@@ -138,14 +138,37 @@
 	assertEquals(sqwi.toQuery().toString(), "spanWithin(<tokens:np />, tokens:pos:Det, 1)");
     };
 
-    @Ignore
+    @Test
     public void queryJSONBsp14 () {
 	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp14.json").getFile());
 
 	// 'vers{2,3}uch'
-	assertEquals(sqwi.toQuery().toString(), "");
+	assertEquals(sqwi.toQuery().toString(), "SpanMultiTermQueryWrapper(tokens:/s:vers{2,3}uch/)");
     };
 
+    @Test
+    public void queryJSONBsp15 () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp15.json").getFile());
+
+	// [orth='vers.*ch']
+	assertEquals(sqwi.toQuery().toString(), "SpanMultiTermQueryWrapper(tokens:/s:vers.*ch/)");
+    };
+
+    @Test
+    public void queryJSONBsp16 () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp16.json").getFile());
+
+	// [(base=bar|base=foo)&orth=foobar]
+	assertEquals(sqwi.toQuery().toString(), "spanNear([spanOr([tokens:l:bar, tokens:l:foo]), tokens:s:foobar], -1, false)");
+    };
+
+    @Test
+    public void queryJSONBsp17 () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp17.json").getFile());
+
+	// within(<np>,[base=Mann])
+	assertEquals(sqwi.toQuery().toString(), "spanWithin(<tokens:np />, tokens:l:Mann)");
+    };
 
     public static String getString (String path) {
 	StringBuilder contentBuilder = new StringBuilder();
diff --git a/src/test/resources/queries/bsp14.json b/src/test/resources/queries/bsp14.json
index 6737c80..b76110c 100644
--- a/src/test/resources/queries/bsp14.json
+++ b/src/test/resources/queries/bsp14.json
@@ -24,7 +24,7 @@
             "@subtype": "korap:regex", 
             "@value": "'vers{2,3}uch'", 
             "relation": "=", 
-            "type": "korap:term"
+            "@type": "korap:term"
         }
     }
 }
diff --git a/src/test/resources/queries/bsp15.json b/src/test/resources/queries/bsp15.json
index 371820c..c287d88 100644
--- a/src/test/resources/queries/bsp15.json
+++ b/src/test/resources/queries/bsp15.json
@@ -21,7 +21,7 @@
     "query": {
         "@type": "korap:token", 
         "@value": {
-            "@subtype": "korap:value#regex", 
+            "@subtype": "korap:regex", 
             "@type": "korap:term", 
             "@value": "orth:'vers.*ch'", 
             "relation": "="
diff --git a/src/test/resources/queries/readme.txt b/src/test/resources/queries/readme.txt
index 60a54f7..5fa4709 100644
--- a/src/test/resources/queries/readme.txt
+++ b/src/test/resources/queries/readme.txt
@@ -1,18 +1,18 @@
-bsp1.json: [base=foo]|([base=foo][base=bar])* meta author=Goethe&year=1815
-bsp2.json: ([base=foo]|[base=bar])[base=foobar]
-bsp3.json: shrink({[base=Mann]})
-bsp4.json: shrink({[base=foo]}[orth=bar])
-bsp5.json: shrink(1:[base=Der]{1:[base=Mann]}) 
-bsp6.json: [base=Katze]
-bsp7.json: [base!=Katze]
-bsp8.json: [!base=Katze]
-bsp9.json: [base=Katze&orth=Katzen]
-bsp10.json:	[base=Katze][orth=und][orth=Hunde]
-bsp11.json:	[!(base=Katze&orth=Katzen)]
-bsp12.json:	contains(<np>,[base=Mann])
-bsp13.json:	startswith(<np>,[!pos=Det])
-bsp13b.json:	startswith(<np>,[pos=Det])
-bsp14.json:	'vers{2,3}uch'
-bsp15.json:	[orth='vers.*ch']
-bsp16.json: [(base=bar|base=foo)&orth=foobar]
-bsp17.json:	within(<np>,[base=Mann])
+bsp1.json:   [base=foo]|([base=foo][base=bar])* meta author=Goethe&year=1815
+bsp2.json:   ([base=foo]|[base=bar])[base=foobar]
+bsp3.json:   shrink({[base=Mann]})
+bsp4.json:   shrink({[base=foo]}[orth=bar])
+bsp5.json:   shrink(1:[base=Der]{1:[base=Mann]}) 
+bsp6.json:   [base=Katze]
+bsp7.json:   [base!=Katze]
+bsp8.json:   [!base=Katze]
+bsp9.json:   [base=Katze&orth=Katzen]
+bsp10.json:  [base=Katze][orth=und][orth=Hunde]
+bsp11.json:  [!(base=Katze&orth=Katzen)]
+bsp12.json:  contains(<np>,[base=Mann])
+bsp13.json:  startswith(<np>,[!pos=Det])
+bsp13b.json: startswith(<np>,[pos=Det])
+bsp14.json:  'vers{2,3}uch'
+bsp15.json:  [orth='vers.*ch']
+bsp16.json:  [(base=bar|base=foo)&orth=foobar]
+bsp17.json:  within(<np>,[base=Mann])