Further query serialization tests
diff --git a/src/main/java/de/ids_mannheim/korap/KorapQuery.java b/src/main/java/de/ids_mannheim/korap/KorapQuery.java
index 4044bfc..c37ebd1 100644
--- a/src/main/java/de/ids_mannheim/korap/KorapQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KorapQuery.java
@@ -101,12 +101,41 @@
 		    throw new QueryException("Operation needs position specification");
 
 		// temporary
-		if (json.get("position").asText().equals("contains") || json.get("position").asText().equals("within")) {
+		String position = json.get("position").asText();
+		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
+                    );
+
+		case "endswith":
+		    return new SpanWithinQueryWrapper(
+			this.fromJSON(json.get("operands").get(0)),
+			this.fromJSON(json.get("operands").get(1)),
+			(short) 2
+                    );
+
+		case "match":
+		    return new SpanWithinQueryWrapper(
+			this.fromJSON(json.get("operands").get(0)),
+			this.fromJSON(json.get("operands").get(1)),
+			(short) 3
+                    );
 		};
+
 		throw new QueryException("Unknown position type "+json.get("position").asText());
 
 	    case "shrink":
@@ -120,21 +149,7 @@
 	    throw new QueryException("Unknown group relation");
 
 	case "korap:token":
-	    JsonNode value = json.get("@value");
-	    SpanSegmentQueryWrapper ssegqw = new SpanSegmentQueryWrapper(this.field);
-	    type = value.get("@type").asText();
-	    if (type.equals("korap:term")) {
-		switch (value.get("relation").asText()) {
-		case "=":
-		    ssegqw.with(value.get("@value").asText());
-		    return ssegqw;
-		case "!=":
-		    throw new QueryException("Term relation != not yet supported");
-		};
-		throw new QueryException("Unknown term relation");
-	    };
-	    throw new QueryException("Unknown token type");
-
+	    return this._segFromJSON(json.get("@value"));
 
 	case "korap:sequence":
 	    if (!json.has("operands"))
@@ -145,11 +160,53 @@
 		sseqqw.append(this.fromJSON(operand));
 	    };
 	    return sseqqw;
+
+	case "korap:element":
+	    String value = json.get("@value").asText().replace('=',':');
+	    return this.tag(value);
 	};
 	throw new QueryException("Unknown serialized query type: " + type);
     };
 
 
+    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());
+	    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()) {
+	    case "and":
+		for (JsonNode operand : json.get("operands")) {
+		    SpanQueryWrapperInterface part = this._segFromJSON(operand);
+		    if (part instanceof SpanAlterQueryWrapper) {
+			ssegqw.with((SpanAlterQueryWrapper) part);			
+		    }
+		    else if (part instanceof SpanRegexQueryWrapper) {
+			ssegqw.with((SpanRegexQueryWrapper) part);
+		    }
+		    else if (part instanceof SpanSegmentQueryWrapper) {
+			ssegqw.with((SpanSegmentQueryWrapper) part);
+		    }
+		    else {
+			throw new QueryException("Object not supported in segment queries");
+		    };
+		};
+		return ssegqw;
+	    };
+    };
+    throw new QueryException("Unknown token type");    
+};
+
+
+
     // SpanSegmentRegexQuery
     /**
      * Create a query object based on a regular expression.
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanWithinQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanWithinQuery.java
index 8e9235d..fff813a 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanWithinQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanWithinQuery.java
@@ -122,7 +122,11 @@
         buffer.append(wrap.toString());
         buffer.append(", ");
 	buffer.append(embedded.toString(field));
-        buffer.append(")");
+	if (flag > 0) {
+	    buffer.append(", ");
+	    buffer.append(flag);
+	};
+	buffer.append(")");
 	buffer.append(ToStringUtils.boost(getBoost()));
 	return buffer.toString();
     };
@@ -186,7 +190,7 @@
     // I don't know what I am doing here
     @Override
     public int hashCode() {
-	int result = 1;
+	int result = flag;
 	result = embedded.hashCode();
 	result += wrap.hashCode();
 	result ^= (result << 4) | (result >>> 29);
diff --git a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSegmentQueryWrapper.java b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSegmentQueryWrapper.java
index b8d07bc..66db669 100644
--- a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSegmentQueryWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSegmentQueryWrapper.java
@@ -88,6 +88,16 @@
 	return this;
     };
 
+    public SpanSegmentQueryWrapper with (SpanSegmentQueryWrapper seg) {
+	for (SpanQuery sq : seg.inclusive) {
+	    this.inclusive.add(sq);
+	};
+	for (SpanQuery sq : seg.exclusive) {
+	    this.exclusive.add(sq);
+	};
+	return this;
+    };
+
     public SpanSegmentQueryWrapper without (String term) {
 	this.exclusive.add(new SpanTermQuery(new Term(field, term)));
 	return this;
diff --git a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanWithinQueryWrapper.java b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanWithinQueryWrapper.java
index 33d7386..8468630 100644
--- a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanWithinQueryWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanWithinQueryWrapper.java
@@ -15,13 +15,21 @@
 public class SpanWithinQueryWrapper implements SpanQueryWrapperInterface {
     private SpanQueryWrapperInterface element;
     private SpanQueryWrapperInterface wrap;
+    private short flag;
 
     public SpanWithinQueryWrapper (SpanQueryWrapperInterface element, SpanQueryWrapperInterface wrap) {
 	this.element = element;
 	this.wrap = wrap;
+	this.flag = (short) 0;
+    };
+
+    public SpanWithinQueryWrapper (SpanQueryWrapperInterface element, SpanQueryWrapperInterface wrap, short flag) {
+	this.element = element;
+	this.wrap = wrap;
+	this.flag = flag;
     };
 
     public SpanQuery toQuery () {
-	return new SpanWithinQuery(this.element.toQuery(), this.wrap.toQuery());
+	return new SpanWithinQuery(this.element.toQuery(), this.wrap.toQuery(), this.flag);
     };
 };
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 9917184..43f9fb1 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestKorapQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestKorapQueryJSON.java
@@ -90,15 +90,62 @@
 	assertEquals(sqwi.toQuery().toString(), "");
     };
 
-    /*
     @Test
     public void queryJSONBsp9 () {
 	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)");
+    };
+
+    @Test
+    public void queryJSONBsp10 () {
+	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)");
+    };
+
+    @Ignore
+    public void queryJSONBsp11 () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp11.json").getFile());
+
+	// [!(base=Katze&orth=Katzen)]
 	assertEquals(sqwi.toQuery().toString(), "");
     };
-    */
+
+    @Test
+    public void queryJSONBsp12 () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp12.json").getFile());
+
+	// contains(<np>,[base=Mann])
+	assertEquals(sqwi.toQuery().toString(), "spanWithin(<tokens:np />, tokens:base:Mann)");
+    };
+
+    @Ignore
+    public void queryJSONBsp13 () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp13.json").getFile());
+
+	// startswith(<np>,[!pos=Det])
+	assertEquals(sqwi.toQuery().toString(), "");
+    };
+
+    @Test
+    public void queryJSONBsp13b () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp13b.json").getFile());
+
+	// startswith(<np>,[!pos=Det])
+	assertEquals(sqwi.toQuery().toString(), "spanWithin(<tokens:np />, tokens:pos:Det, 1)");
+    };
+
+    @Ignore
+    public void queryJSONBsp14 () {
+	SpanQueryWrapperInterface sqwi = jsonQuery(getClass().getResource("/queries/bsp14.json").getFile());
+
+	// 'vers{2,3}uch'
+	assertEquals(sqwi.toQuery().toString(), "");
+    };
+
 
     public static String getString (String path) {
 	StringBuilder contentBuilder = new StringBuilder();
@@ -128,4 +175,4 @@
 	};
 	return sqwi;
     };
-};
\ No newline at end of file
+};
diff --git a/src/test/resources/queries/bsp13b.json b/src/test/resources/queries/bsp13b.json
new file mode 100644
index 0000000..562c80c
--- /dev/null
+++ b/src/test/resources/queries/bsp13b.json
@@ -0,0 +1,40 @@
+{
+    "@context": {
+        "@language": "de", 
+        "class": {
+            "@id": "korap:class", 
+            "@type": "xsd:integer"
+        }, 
+        "filter": "korap:filter", 
+        "korap": "http://korap.ids-mannheim.de/ns/query", 
+        "meta": "korap:meta", 
+        "operands": {
+            "@container": "@list", 
+            "@id": "korap:operands"
+        }, 
+        "query": "korap:query", 
+        "relation": {
+            "@id": "korap:relation", 
+            "@type": "korap:relation#types"
+        }
+    }, 
+    "query": {
+        "@type": "korap:group", 
+        "operands": [
+            {
+                "@type": "korap:element", 
+                "@value": "np"
+            }, 
+            {
+                "@type": "korap:token", 
+                "@value": {
+                    "@type": "korap:term", 
+                    "@value": "pos:Det", 
+                    "relation": "="
+                }
+            }
+        ], 
+        "position": "startswith", 
+        "relation": "position"
+    }
+}
diff --git a/src/test/resources/queries/readme.txt b/src/test/resources/queries/readme.txt
index 36745ce..60a54f7 100644
--- a/src/test/resources/queries/readme.txt
+++ b/src/test/resources/queries/readme.txt
@@ -11,7 +11,8 @@
 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])
\ No newline at end of file
+bsp17.json:	within(<np>,[base=Mann])