diff --git a/src/main/java/de/ids_mannheim/korap/KorapQuery.java b/src/main/java/de/ids_mannheim/korap/KorapQuery.java
index 96bd4ac..60dd0e0 100644
--- a/src/main/java/de/ids_mannheim/korap/KorapQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KorapQuery.java
@@ -1,43 +1,46 @@
 package de.ids_mannheim.korap;
 
-import de.ids_mannheim.korap.query.wrap.*;
-import de.ids_mannheim.korap.response.Notifications;
-import de.ids_mannheim.korap.util.QueryException;
+import java.io.IOException;
 
-import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.lucene.util.automaton.RegExp;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.JsonNode;
-
-import de.ids_mannheim.korap.query.SpanWithinQuery;
-
-import java.util.*;
-import java.io.*;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ids_mannheim.korap.query.SpanWithinQuery;
+import de.ids_mannheim.korap.query.wrap.SpanAlterQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanClassQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanElementQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanMatchModifyQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanRegexQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanRepetitionQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanSegmentQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanSequenceQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanSubspanQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanWildcardQueryWrapper;
+import de.ids_mannheim.korap.query.wrap.SpanWithinQueryWrapper;
+import de.ids_mannheim.korap.response.Notifications;
+import de.ids_mannheim.korap.util.QueryException;
+
 /*
-  Todo: All queries with a final right expansion
-  der alte []
-  should be wrapped in a contains(<base/s=t>) to ensure
-  they are not outside the text.
-
-  TODO: Create Pre-filter while preparing a Query.
-  The pre-filter will contain a boolena query with all
-  necessary terms, supporting boolean OR, ignoring
-  negation terms (and negation subqueries), like
-  [base=Der]([base=alte]|[base=junge])[base=Mann & p!=ADJA]![base=war | base=lag]
-  Search for all documents containing "s:Der" and ("s:alte" or "s:junge") and "s:Mann"
-
-*/
+ * Todo: All queries with a final right expansion der alte [] should be wrapped
+ * in a contains(<base/s=t>) to ensure they are not outside the text. TODO:
+ * Create Pre-filter while preparing a Query. The pre-filter will contain a
+ * boolena query with all necessary terms, supporting boolean OR, ignoring
+ * negation terms (and negation subqueries), like
+ * [base=Der]([base=alte]|[base=junge])[base=Mann & p!=ADJA]![base=war |
+ * base=lag] Search for all documents containing "s:Der" and ("s:alte" or
+ * "s:junge") and "s:Mann"
+ */
 
 /**
  * @author Nils Diewald
- *
- * KorapQuery implements a simple API for wrapping
- * KorAP Lucene Index specific query classes.
+ * 
+ *         KorapQuery implements a simple API for wrapping KorAP Lucene Index
+ *         specific query classes.
  */
 public class KorapQuery extends Notifications {
     private String field;
@@ -49,72 +52,73 @@
     // This advices the java compiler to ignore all loggings
     public static final boolean DEBUG = false;
 
-    public static final byte
-	OVERLAP      = SpanWithinQuery.OVERLAP,
-	REAL_OVERLAP = SpanWithinQuery.REAL_OVERLAP,
-	WITHIN       = SpanWithinQuery.WITHIN,
-	REAL_WITHIN  = SpanWithinQuery.REAL_WITHIN,
-	ENDSWITH     = SpanWithinQuery.ENDSWITH,
-	STARTSWITH   = SpanWithinQuery.STARTSWITH,
-	MATCH        = SpanWithinQuery.MATCH;
+    public static final byte OVERLAP = SpanWithinQuery.OVERLAP,
+            REAL_OVERLAP = SpanWithinQuery.REAL_OVERLAP,
+            WITHIN = SpanWithinQuery.WITHIN,
+            REAL_WITHIN = SpanWithinQuery.REAL_WITHIN,
+            ENDSWITH = SpanWithinQuery.ENDSWITH,
+            STARTSWITH = SpanWithinQuery.STARTSWITH,
+            MATCH = SpanWithinQuery.MATCH;
 
     private static final int MAX_CLASS_NUM = 255; // 127;
 
     /**
      * Constructs a new base object for query generation.
+     * 
      * @param field The specific index field for the query.
      */
-    public KorapQuery (String field) {
-	this.field = field;
-	this.json = new ObjectMapper();
+    public KorapQuery(String field) {
+        this.field = field;
+        this.json = new ObjectMapper();
     };
 
     /**
      * Private class for korap:boundary objects
      */
     private class Boundary {
-	public int min, max;
+        public int min, max;
 
-	public Boundary (JsonNode json, int defaultMin, int defaultMax) throws QueryException {
+        public Boundary(JsonNode json, int defaultMin, int defaultMax)
+                throws QueryException {
 
-	    if (!json.has("@type"))
-		throw new QueryException(701, "JSON-LD group has no @type attribute");
+            if (!json.has("@type"))
+                throw new QueryException(701,
+                        "JSON-LD group has no @type attribute");
 
-	    if (!json.get("@type").asText().equals("korap:boundary"))
-		throw new QueryException(702, "Boundary definition is invalid");
+            if (!json.get("@type").asText().equals("korap:boundary"))
+                throw new QueryException(702, "Boundary definition is invalid");
 
-	    // Set min boundary
-	    if (json.has("min"))
-		this.min = json.get("min").asInt(defaultMin);
-	    else
-		this.min = defaultMin;
+            // Set min boundary
+            if (json.has("min"))
+                this.min = json.get("min").asInt(defaultMin);
+            else
+                this.min = defaultMin;
 
-	    // Set max boundary
-	    if (json.has("max"))
-		this.max = json.get("max").asInt(defaultMax);
-	    else
-		this.max = defaultMax;
+            // Set max boundary
+            if (json.has("max"))
+                this.max = json.get("max").asInt(defaultMax);
+            else
+                this.max = defaultMax;
 
-	    if (DEBUG)
-		log.trace("Found korap:boundary with {}:{}", min, max);
-	};
+            if (DEBUG) log.trace("Found korap:boundary with {}:{}", min, max);
+        };
     };
 
-    public SpanQueryWrapper fromJson (String jsonString) throws QueryException {
-	JsonNode json;
-	try {
-	    json = this.json.readValue(jsonString, JsonNode.class);
-	}
-	catch (IOException e) {
-	    String msg = e.getMessage();
-	    log.warn("Unable to parse JSON: " + msg.split("\n")[0]);
-	    throw new QueryException(621, "Unable to parse JSON");
-	};
+    public SpanQueryWrapper fromJson(String jsonString) throws QueryException {
+        JsonNode json;
+        try {
+            json = this.json.readValue(jsonString, JsonNode.class);
+        }
+        catch (IOException e) {
+            String msg = e.getMessage();
+            log.warn("Unable to parse JSON: " + msg.split("\n")[0]);
+            throw new QueryException(621, "Unable to parse JSON");
+        }
+        ;
 
-	if (!json.has("@type") && json.has("query"))
-	    json = json.get("query");
+        if (!json.has("@type") && json.has("query")) json = json.get("query");
 
-	return this.fromJson(json);
+        return this.fromJson(json);
     };
 
     // http://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/JsonNode.html
@@ -122,887 +126,919 @@
     // TODO: Use the shortcuts implemented in this class instead of the wrapper constructors
     // TODO: Check for isArray()
     // TODO: Rename this span context!
-    public SpanQueryWrapper fromJson (JsonNode json) throws QueryException {
+    public SpanQueryWrapper fromJson(JsonNode json) throws QueryException {
 
-	int number = 0;
+        int number = 0;
 
-	if (!json.has("@type"))
-	    throw new QueryException(701, "JSON-LD group has no @type attribute");
+        if (!json.has("@type"))
+            throw new QueryException(701,
+                    "JSON-LD group has no @type attribute");
 
-	String type = json.get("@type").asText();
+        String type = json.get("@type").asText();
 
-	switch (type) {
+        switch (type) {
 
-	case "korap:group":
-	    SpanClassQueryWrapper classWrapper;
+            case "korap:group":
+                SpanClassQueryWrapper classWrapper;
 
-	    if (!json.has("operation"))
-		throw new QueryException(703, "Group expects operation");
+                if (!json.has("operation"))
+                    throw new QueryException(703, "Group expects operation");
 
-	    String operation = json.get("operation").asText();
+                String operation = json.get("operation").asText();
 
-	    if (DEBUG)
-		log.trace("Found {} group", operation);
+                if (DEBUG) log.trace("Found {} group", operation);
 
-	    if (!json.has("operands"))
-		throw new QueryException(704, "Operation needs operand list");
+                if (!json.has("operands"))
+                    throw new QueryException(704,
+                            "Operation needs operand list");
 
-	    // Get all operands
-	    JsonNode operands = json.get("operands");
+                // Get all operands
+                JsonNode operands = json.get("operands");
 
-	    if (!operands.isArray())
-		throw new QueryException(704, "Operation needs operand list");
+                if (!operands.isArray())
+                    throw new QueryException(704,
+                            "Operation needs operand list");
 
-	    if (DEBUG)
-		log.trace("Operands are {}", operands);
+                if (DEBUG) log.trace("Operands are {}", operands);
 
-	    switch (operation) {
+                switch (operation) {
 
-	    case "operation:or":
-		SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(this.field);
-		for (JsonNode operand : operands) {
-		    ssaq.or(this.fromJson(operand));
-		};
-		return ssaq;
+                    case "operation:or":
+                        SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(
+                                this.field);
+                        for (JsonNode operand : operands) {
+                            ssaq.or(this.fromJson(operand));
+                        }
+                        ;
+                        return ssaq;
 
-	    case "operation:position":
+                    case "operation:position":
 
-		if (operands.size() != 2)
-		    throw new QueryException(705, "Number of operands is not acceptable");
+                        if (operands.size() != 2)
+                            throw new QueryException(705,
+                                    "Number of operands is not acceptable");
 
-		// TODO: Check for operands
-		// TODO: LEGACY and not future proof
-		String frame = json.has("frame") ?
-		    json.get("frame").asText() :
-		    "frame:contains";
+                        // TODO: Check for operands
+                        // TODO: LEGACY and not future proof
+                        String frame = json.has("frame") ? json.get("frame")
+                                .asText() : "frame:contains";
 
-		if (DEBUG)
-		    log.trace("Position frame is '{}'", frame);
+                        if (DEBUG) log.trace("Position frame is '{}'", frame);
 
-		byte flag = WITHIN;
-		switch (frame) {
-		case "frame:contains":
-		    break;
-		case "frame:strictlyContains":
-		    flag = REAL_WITHIN;
-		    break;
-		case "frame:within":
-		    break;
-		case "frame:startswith":
-		    flag = STARTSWITH;
-		    break;
-		case "frame:endswith":
-		    flag = ENDSWITH;
-		    break;
-		case "frame:matches":
-		    flag = MATCH;
-		    break;
-		case "frame:overlaps":
-		    flag = OVERLAP;
-		    break;
-		case "frame:strictlyOverlaps":
-		    flag = REAL_OVERLAP;
-		    break;
-		case "":
-		    // Temporary workaround for wrongly set overlaps
-		    if (json.has("frames")) {
-			frame = json.get("frames").get(0).asText();
-			if (frame.equals("frames:overlapsLeft") ||
-			    frame.equals("frames:overlapsRight")) {
-			    flag = OVERLAP;
-			    break;
-			};
-		    };
-		default:
-		    throw new QueryException(706, "Frame type is unknown");
-		};
+                        byte flag = WITHIN;
+                        switch (frame) {
+                            case "frame:contains":
+                                break;
+                            case "frame:strictlyContains":
+                                flag = REAL_WITHIN;
+                                break;
+                            case "frame:within":
+                                break;
+                            case "frame:startswith":
+                                flag = STARTSWITH;
+                                break;
+                            case "frame:endswith":
+                                flag = ENDSWITH;
+                                break;
+                            case "frame:matches":
+                                flag = MATCH;
+                                break;
+                            case "frame:overlaps":
+                                flag = OVERLAP;
+                                break;
+                            case "frame:strictlyOverlaps":
+                                flag = REAL_OVERLAP;
+                                break;
+                            case "":
+                                // Temporary workaround for wrongly set overlaps
+                                if (json.has("frames")) {
+                                    frame = json.get("frames").get(0).asText();
+                                    if (frame.equals("frames:overlapsLeft")
+                                            || frame.equals("frames:overlapsRight")) {
+                                        flag = OVERLAP;
+                                        break;
+                                    }
+                                    ;
+                                }
+                                ;
+                            default:
+                                throw new QueryException(706,
+                                        "Frame type is unknown");
+                        }
+                        ;
 
-		// Check for exclusion modificator
-		Boolean exclude;
-		if (json.has("exclude") && json.get("exclude").asBoolean())
-		    throw new QueryException(
-			760,
-		        "Exclusion is currently not supported in position operations"
-		    );
+                        // Check for exclusion modificator
+                        Boolean exclude;
+                        if (json.has("exclude")
+                                && json.get("exclude").asBoolean())
+                            throw new QueryException(760,
+                                    "Exclusion is currently not supported in position operations");
 
-		return new SpanWithinQueryWrapper(
-		    this.fromJson(operands.get(0)),
-		    this.fromJson(operands.get(1)),
-		    flag
-		);
+                        return new SpanWithinQueryWrapper(
+                                this.fromJson(operands.get(0)),
+                                this.fromJson(operands.get(1)), flag);
 
-	    // TODO: This is DEPRECATED and should be communicated that way
-	    case "operation:submatch":
+                        // TODO: This is DEPRECATED and should be communicated that way
+                    case "operation:submatch":
 
-		if (operands.size() != 1)
-		    throw new QueryException(705, "Number of operands is not acceptable");
+                        if (operands.size() != 1)
+                            throw new QueryException(705,
+                                    "Number of operands is not acceptable");
 
-		if (json.has("classRef")) {
-		    if (json.has("classRefOp"))
-			throw new QueryException(
-			    761,
-			    "Class reference operators are currently not supported"
-                    );
+                        if (json.has("classRef")) {
+                            if (json.has("classRefOp"))
+                                throw new QueryException(761,
+                                        "Class reference operators are currently not supported");
 
-		    number = json.get("classRef").get(0).asInt();
-		}
-		else if (json.has("spanRef")) {
-		    throw new QueryException(
-			762,
-		        "Span references are currently not supported"
-                    );
-		};
+                            number = json.get("classRef").get(0).asInt();
+                        }
+                        else if (json.has("spanRef")) {
+                            throw new QueryException(762,
+                                    "Span references are currently not supported");
+                        }
+                        ;
 
-		return new SpanMatchModifyQueryWrapper(
-		    this.fromJson(operands.get(0)), number
-                );
+                        return new SpanMatchModifyQueryWrapper(
+                                this.fromJson(operands.get(0)), number);
 
-	    case "operation:sequence":
+                    case "operation:sequence":
 
-		// Sequence with only one operand
-		if (operands.size() == 1)
-		    return this.fromJson(operands.get(0));
+                        // Sequence with only one operand
+                        if (operands.size() == 1)
+                            return this.fromJson(operands.get(0));
 
-		SpanSequenceQueryWrapper sseqqw = this.seq();
+                        SpanSequenceQueryWrapper sseqqw = this.seq();
 
-		// Say if the operand order is important
-		if (json.has("inOrder"))
-		    sseqqw.setInOrder(json.get("inOrder").asBoolean());
+                        // Say if the operand order is important
+                        if (json.has("inOrder"))
+                            sseqqw.setInOrder(json.get("inOrder").asBoolean());
 
-		// Introduce distance constraints
-		// ATTENTION: Distances have to be set before segments are added
-		if (json.has("distances")) {
+                        // Introduce distance constraints
+                        // ATTENTION: Distances have to be set before segments are added
+                        if (json.has("distances")) {
 
-		    // TODO
-		    if (json.has("exclude") && json.get("exclude").asBoolean())
-			throw new QueryException(
-			    763,
-			    "Excluding distance constraints are currently not supported"
-			);
+                            // TODO
+                            if (json.has("exclude")
+                                    && json.get("exclude").asBoolean())
+                                throw new QueryException(763,
+                                        "Excluding distance constraints are currently not supported");
 
-		    if (!json.get("distances").isArray()) {
-			throw new QueryException(
-			    707,
-			    "Distance Constraints have " +
-			    "to be defined as arrays"
-			);
-		    };
+                            if (!json.get("distances").isArray()) {
+                                throw new QueryException(707,
+                                        "Distance Constraints have "
+                                                + "to be defined as arrays");
+                            }
+                            ;
 
-		    // TEMPORARY: Workaround for group distances
-		    JsonNode firstDistance = json.get("distances").get(0);
+                            // TEMPORARY: Workaround for group distances
+                            JsonNode firstDistance = json.get("distances").get(
+                                    0);
 
-		    if (!firstDistance.has("@type"))
-			throw new QueryException(701, "JSON-LD group has no @type attribute");
+                            if (!firstDistance.has("@type"))
+                                throw new QueryException(701,
+                                        "JSON-LD group has no @type attribute");
 
-		    JsonNode distances;
-		    if (firstDistance.get("@type").asText().equals("korap:group")) {
-			if (!firstDistance.has("operands") ||
-			    !firstDistance.get("operands").isArray())
-			    throw new QueryException(704, "Operation needs operand list");
+                            JsonNode distances;
+                            if (firstDistance.get("@type").asText()
+                                    .equals("korap:group")) {
+                                if (!firstDistance.has("operands")
+                                        || !firstDistance.get("operands")
+                                                .isArray())
+                                    throw new QueryException(704,
+                                            "Operation needs operand list");
 
-			distances = firstDistance.get("operands");
-		    }
+                                distances = firstDistance.get("operands");
+                            }
 
-		    // Support korap distances
-		    // Support cosmas distances
-		    else if (
-			     firstDistance.get("@type").asText().equals("korap:distance")
-			     ||
-			     firstDistance.get("@type").asText().equals("cosmas:distance")) {
+                            // Support korap distances
+                            // Support cosmas distances
+                            else if (firstDistance.get("@type").asText()
+                                    .equals("korap:distance")
+                                    || firstDistance.get("@type").asText()
+                                            .equals("cosmas:distance")) {
 
-			distances = json.get("distances");
-		    }
+                                distances = json.get("distances");
+                            }
 
-		    else
-			throw new QueryException(708, "No valid distances defined");
+                            else
+                                throw new QueryException(708,
+                                        "No valid distances defined");
 
-		    // Add all distance constraint to query
-		    for (JsonNode constraint : distances) {
-			String unit = "w";
-			if (constraint.has("key"))
-			    unit = constraint.get("key").asText();
+                            // Add all distance constraint to query
+                            for (JsonNode constraint : distances) {
+                                String unit = "w";
+                                if (constraint.has("key"))
+                                    unit = constraint.get("key").asText();
 
-			// There is a maximum of 100 fix
-			int min = 0, max = 100;
-			if (constraint.has("boundary")) {
-			    Boundary b = new Boundary(constraint.get("boundary"), 0,100);
-			    min = b.min;
-			    max = b.max;
-			}
-			else {
-			    if (constraint.has("min"))
-				min = constraint.get("min").asInt(0);
-			    if (constraint.has("max"))
-				max = constraint.get("max").asInt(100);
-			};
+                                // There is a maximum of 100 fix
+                                int min = 0, max = 100;
+                                if (constraint.has("boundary")) {
+                                    Boundary b = new Boundary(
+                                            constraint.get("boundary"), 0, 100);
+                                    min = b.min;
+                                    max = b.max;
+                                }
+                                else {
+                                    if (constraint.has("min"))
+                                        min = constraint.get("min").asInt(0);
+                                    if (constraint.has("max"))
+                                        max = constraint.get("max").asInt(100);
+                                }
+                                ;
+
+                                // Add foundry and layer to the unit for new indices
+                                if (constraint.has("foundry")
+                                        && constraint.has("layer")
+                                        && constraint.get("foundry").asText()
+                                                .length() > 0
+                                        && constraint.get("layer").asText()
+                                                .length() > 0) {
 
-			// Add foundry and layer to the unit for new indices
-			if (constraint.has("foundry") &&
-			    constraint.has("layer") &&
-			    constraint.get("foundry").asText().length() > 0 &&
-			    constraint.get("layer").asText().length() > 0) {
+                                    StringBuilder value = new StringBuilder();
+                                    value.append(constraint.get("foundry")
+                                            .asText());
+                                    value.append('/');
+                                    value.append(constraint.get("layer")
+                                            .asText());
+                                    value.append(':').append(unit);
+                                    unit = value.toString();
+                                }
+                                ;
 
-			    StringBuilder value = new StringBuilder();
-			    value.append(constraint.get("foundry").asText());
-			    value.append('/');
-			    value.append(constraint.get("layer").asText());
-			    value.append(':').append(unit);
-			    unit = value.toString();
-			};
+                                // Sanitize boundary
+                                if (max < min) max = min;
 
-			// Sanitize boundary
-			if (max < min)
-			    max = min;
+                                if (DEBUG)
+                                    log.trace(
+                                            "Add distance constraint of '{}': {}-{}",
+                                            unit, min, max);
 
-			if (DEBUG)
-			    log.trace("Add distance constraint of '{}': {}-{}",
-				      unit, min, max);
+                                sseqqw.withConstraint(min, max, unit);
+                            }
+                            ;
+                        }
+                        ;
 
-			sseqqw.withConstraint(min, max, unit);
-		    };
-		};
+                        // Add segments to sequence
+                        for (JsonNode operand : operands) {
+                            sseqqw.append(this.fromJson(operand));
+                        }
+                        ;
 
-		// Add segments to sequence
-		for (JsonNode operand : operands) {
-		    sseqqw.append(this.fromJson(operand));
-		};
+                        // inOrder was set to false without a distance constraint
+                        if (!sseqqw.isInOrder() && !sseqqw.hasConstraints()) {
+                            sseqqw.withConstraint(1, 1, "w");
+                        }
+                        ;
 
-		// inOrder was set to false without a distance constraint
-		if (!sseqqw.isInOrder() && !sseqqw.hasConstraints()) {
-		    sseqqw.withConstraint(1,1,"w");
-		};
+                        return sseqqw;
 
-		return sseqqw;
+                    case "operation:class":
+                        number = 1;
 
-	    case "operation:class":
-		number = 1;
+                        if (json.has("classOut")) {
+                            number = json.get("classOut").asInt(0);
+                        }
+                        // Legacy classes
+                        else if (json.has("class")) {
+                            number = json.get("class").asInt(0);
+                        }
+                        ;
 
-		if (json.has("classOut")) {
-		    number = json.get("classOut").asInt(0);
-		}
-		// Legacy classes
-		else if (json.has("class")) {
-		    number = json.get("class").asInt(0);
-		};
+                        if (json.has("classRefCheck"))
+                            this.addWarning(
+                                    764,
+                                    "Class reference checks are currently not supported - results may not be correct");
 
-		if (json.has("classRefCheck"))
-		    this.addWarning(
-		        764,
-			"Class reference checks are currently not supported - results may not be correct"
-                    );
+                        if (json.has("classRefOp"))
+                            throw new QueryException(761,
+                                    "Class reference operators are currently not supported");
 
-		if (json.has("classRefOp"))
-		    throw new QueryException(
-		        761,
-			"Class reference operators are currently not supported"
-                    );
+                        if (number > 0) {
+                            if (operands.size() != 1)
+                                throw new QueryException(705,
+                                        "Number of operands is not acceptable");
 
-		if (number > 0) {
-		    if (operands.size() != 1)
-			throw new QueryException(
-			    705,
-			    "Number of operands is not acceptable"
-			);
+                            if (DEBUG)
+                                log.trace("Found Class definition for {}",
+                                        number);
 
-		    if (DEBUG)
-			log.trace("Found Class definition for {}", number);
+                            if (number > MAX_CLASS_NUM) {
+                                throw new QueryException(709,
+                                        "Valid class numbers exceeded");
+                            }
+                            ;
 
-		    if (number > MAX_CLASS_NUM) {
-			throw new QueryException(
-			    709, "Valid class numbers exceeded"
-                        );
-		    };
+                            SpanQueryWrapper sqw = this.fromJson(operands
+                                    .get(0));
 
-		    SpanQueryWrapper sqw = this.fromJson(operands.get(0));
+                            // Problematic
+                            if (sqw.maybeExtension())
+                                return sqw.setClassNumber(number);
 
-		    // Problematic
-		    if (sqw.maybeExtension())
-			return sqw.setClassNumber(number);
+                            return new SpanClassQueryWrapper(sqw, number);
+                        }
+                        ;
 
-		    return new SpanClassQueryWrapper(sqw, number);
-		};
+                        throw new QueryException(710, "Class attribute missing");
 
-		throw new QueryException(710, "Class attribute missing");
+                    case "operation:repetition":
 
-	    case "operation:repetition":
+                        if (operands.size() != 1)
+                            throw new QueryException(705,
+                                    "Number of operands is not acceptable");
 
-		if (operands.size() != 1)
-		    throw new QueryException(
-		        705,
-			"Number of operands is not acceptable"
-		    );
+                        int min = 0;
+                        int max = 100;
 
-		int min = 0;
-		int max = 100;
+                        if (json.has("boundary")) {
+                            Boundary b = new Boundary(json.get("boundary"), 0,
+                                    100);
+                            min = b.min;
+                            max = b.max;
+                        }
+                        else {
+                            if (json.has("min"))
+                                min = json.get("min").asInt(0);
+                            if (json.has("max"))
+                                max = json.get("max").asInt(100);
 
-		if (json.has("boundary")) {
-		    Boundary b = new Boundary(json.get("boundary"), 0, 100);
-		    min = b.min;
-		    max = b.max;
-		}
-		else {
-		    if (json.has("min"))
-			min = json.get("min").asInt(0);
-		    if (json.has("max"))
-			max = json.get("max").asInt(100);
+                            if (DEBUG)
+                                log.trace(
+                                        "Boundary is set by deprecated {}-{}",
+                                        min, max);
+                        }
+                        ;
 
-		    if (DEBUG)
-			log.trace(
-			    "Boundary is set by deprecated {}-{}",
-			    min,
-			    max);
-		};
+                        // Sanitize max
+                        if (max < 0)
+                            max = 100;
+                        else if (max > 100) max = 100;
 
-		// Sanitize max
-		if (max < 0)
-		    max = 100;
-		else if (max > 100)
-		    max = 100;
+                        // Sanitize min
+                        if (min < 0)
+                            min = 0;
+                        else if (min > 100) min = 100;
 
-		// Sanitize min
-		if (min < 0)
-		    min = 0;
-		else if (min > 100)
-		    min = 100;
-		
-		// Check relation between min and max
-		if (min > max)
-		    max = max;
+                        // Check relation between min and max
+                        if (min > max) max = max;
 
-		SpanQueryWrapper sqw = this.fromJson(operands.get(0));
+                        SpanQueryWrapper sqw = this.fromJson(operands.get(0));
 
-		if (sqw.maybeExtension())
-		    return sqw.setMin(min).setMax(max);
+                        if (sqw.maybeExtension())
+                            return sqw.setMin(min).setMax(max);
 
-		return new SpanRepetitionQueryWrapper(sqw, min, max);
+                        return new SpanRepetitionQueryWrapper(sqw, min, max);
 
-	    case "operation:relation":
-		throw new QueryException(765, "Relations are currently not supported");
-	    };
+                    case "operation:relation":
+                        throw new QueryException(765,
+                                "Relations are currently not supported");
+                }
+                ;
 
-	    throw new QueryException(711, "Unknown group operation");
+                throw new QueryException(711, "Unknown group operation");
 
-	case "korap:reference":
-	    if (json.has("operation") &&
-		!json.get("operation").asText().equals("operation:focus"))
-		throw new QueryException(712, "Unknown reference operation");
+            case "korap:reference":
+                if (json.has("operation")
+                        && !json.get("operation").asText()
+                                .equals("operation:focus"))
+                    throw new QueryException(712, "Unknown reference operation");
 
-	    if (!json.has("operands"))
-		throw new QueryException(
-		    766, "Peripheral references are currently not supported"
-                );
+                if (!json.has("operands"))
+                    throw new QueryException(766,
+                            "Peripheral references are currently not supported");
 
-	    operands = json.get("operands");
+                operands = json.get("operands");
 
-	    if (!operands.isArray())
-		throw new QueryException(704, "Operation needs operand list");
+                if (!operands.isArray())
+                    throw new QueryException(704,
+                            "Operation needs operand list");
 
-	    if (operands.size() == 0)
-		throw new QueryException(704, "Operation needs operand list");
+                if (operands.size() == 0)
+                    throw new QueryException(704,
+                            "Operation needs operand list");
 
-	    if (operands.size() != 1)
-		throw new QueryException(705, "Number of operands is not acceptable");
+                if (operands.size() != 1)
+                    throw new QueryException(705,
+                            "Number of operands is not acceptable");
 
-	    if (json.has("classRef")) {
-		if (json.has("classRefOp")) {
-		    throw new QueryException(
-		        761,
-			"Class reference operators are currently not supported"
-		    );
-		};
+                if (json.has("classRef")) {
+                    if (json.has("classRefOp")) {
+                        throw new QueryException(761,
+                                "Class reference operators are currently not supported");
+                    }
+                    ;
 
-		number = json.get("classRef").get(0).asInt();
+                    number = json.get("classRef").get(0).asInt();
 
+                    if (number > MAX_CLASS_NUM)
+                        throw new QueryException(709,
+                                "Valid class numbers exceeded");
+                }
+                else if (json.has("spanRef")) {
+                    JsonNode spanRef = json.get("spanRef");
+                    return new SpanSubspanQueryWrapper(
+                            fromJson(operands.get(0)), spanRef.get(0).asInt(),
+                            spanRef.get(1).asInt());
 
-		if (number > MAX_CLASS_NUM)
-		    throw new QueryException(
-		        709, "Valid class numbers exceeded"
-                    );
-	    }
-	    else if (json.has("spanRef")) {
-		throw new QueryException(
-		    762,
-		    "Span references are currently not supported"
-	        );
-	    };
+                    //		throw new QueryException(
+                    //		    762,
+                    //		    "Span references are currently not supported"
+                    //	        );
+                }
+                ;
 
-	    if (DEBUG)
-		log.trace("Wrap class reference {}", number);
+                if (DEBUG) log.trace("Wrap class reference {}", number);
 
-	    return new SpanMatchModifyQueryWrapper(
-	        this.fromJson(operands.get(0)), number
-	    );
+                return new SpanMatchModifyQueryWrapper(this.fromJson(operands
+                        .get(0)), number);
 
-	case "korap:token":
+            case "korap:token":
 
-	    // The token is empty and should be treated like []
-	    if (!json.has("wrap"))
-		return new SpanRepetitionQueryWrapper();
+                // The token is empty and should be treated like []
+                if (!json.has("wrap")) return new SpanRepetitionQueryWrapper();
 
-	    return this._segFromJson(json.get("wrap"));
+                return this._segFromJson(json.get("wrap"));
 
-	case "korap:span":
-	    return this._termFromJson(json);
-	};
-	throw new QueryException(713, "Query type is not supported");
+            case "korap:span":
+                return this._termFromJson(json);
+        }
+        ;
+        throw new QueryException(713, "Query type is not supported");
     };
 
+    private SpanQueryWrapper _segFromJson(JsonNode json) throws QueryException {
 
+        if (!json.has("@type"))
+            throw new QueryException(701,
+                    "JSON-LD group has no @type attribute");
 
-    private SpanQueryWrapper _segFromJson (JsonNode json) throws QueryException {
+        String type = json.get("@type").asText();
 
-	if (!json.has("@type"))
-	    throw new QueryException(701, "JSON-LD group has no @type attribute");
+        if (DEBUG) log.trace("Wrap new token definition by {}", type);
 
-	String type = json.get("@type").asText();
+        switch (type) {
 
-	if (DEBUG)
-	    log.trace("Wrap new token definition by {}", type);
+            case "korap:term":
+                String match = "match:eq";
+                if (json.has("match")) match = json.get("match").asText();
 
-	switch (type) {
+                switch (match) {
+                    case "match:ne":
+                        if (DEBUG) log.trace("Term is negated");
+                        SpanSegmentQueryWrapper ssqw = (SpanSegmentQueryWrapper) this
+                                ._termFromJson(json);
+                        ssqw.makeNegative();
+                        return this.seg().without(ssqw);
+                    case "match:eq":
+                        return this._termFromJson(json);
+                }
+                ;
 
-	case "korap:term":
-	    String match = "match:eq";
-	    if (json.has("match"))
-		match = json.get("match").asText();
+                throw new QueryException(741, "Match relation unknown");
 
-	    switch (match) {
-	    case "match:ne":
-		if (DEBUG)
-		    log.trace("Term is negated");
-		SpanSegmentQueryWrapper ssqw =
-		    (SpanSegmentQueryWrapper) this._termFromJson(json);
-		ssqw.makeNegative();
-		return this.seg().without(ssqw);
-	    case "match:eq":
-		return this._termFromJson(json);
-	    };
+            case "korap:termGroup":
 
-	    throw new QueryException(741, "Match relation unknown");
+                if (!json.has("operands"))
+                    throw new QueryException(742,
+                            "Term group needs operand list");
 
-	case "korap:termGroup":
+                // Get operands
+                JsonNode operands = json.get("operands");
 
-	    if (!json.has("operands"))
-		throw new QueryException(742, "Term group needs operand list");
+                SpanSegmentQueryWrapper ssegqw = this.seg();
 
-	    // Get operands
-	    JsonNode operands = json.get("operands");
+                if (!json.has("relation"))
+                    throw new QueryException(743,
+                            "Term group expects a relation");
 
-	    SpanSegmentQueryWrapper ssegqw = this.seg();
+                switch (json.get("relation").asText()) {
+                    case "relation:and":
 
-	    if (!json.has("relation"))
-		throw new QueryException(743, "Term group expects a relation");
+                        for (JsonNode operand : operands) {
+                            SpanQueryWrapper 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(744,
+                                        "Operand not supported in term group");
+                            }
+                            ;
+                        }
+                        ;
+                        return ssegqw;
 
-	    switch (json.get("relation").asText()) {
-	    case "relation:and":
+                    case "relation:or":
 
-		for (JsonNode operand : operands) {
-		    SpanQueryWrapper 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(
-			    744, "Operand not supported in term group"
-                        );
-		    };
-		};
-		return ssegqw;
-
-	    case "relation:or":
-
-		SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(this.field);
-		for (JsonNode operand : operands) {
-		    ssaq.or(this._segFromJson(operand));
-		};
-		return ssaq;
-	    };
-	};
-	throw new QueryException(745, "Token type is not supported");    
+                        SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(
+                                this.field);
+                        for (JsonNode operand : operands) {
+                            ssaq.or(this._segFromJson(operand));
+                        }
+                        ;
+                        return ssaq;
+                }
+                ;
+        }
+        ;
+        throw new QueryException(745, "Token type is not supported");
     };
 
+    private SpanQueryWrapper _termFromJson(JsonNode json) throws QueryException {
+        if (!json.has("key") || json.get("key").asText().length() < 1)
+            throw new QueryException(740,
+                    "Key definition is missing in term or span");
 
-    private SpanQueryWrapper _termFromJson (JsonNode json) throws QueryException {
-	if (!json.has("key") || json.get("key").asText().length() < 1)
-	    throw new QueryException(740, "Key definition is missing in term or span");
-	    
-	if (!json.has("@type"))
-	    throw new QueryException(701, "JSON-LD group has no @type attribute");
+        if (!json.has("@type"))
+            throw new QueryException(701,
+                    "JSON-LD group has no @type attribute");
 
-	Boolean isTerm = json.get("@type").asText().equals("korap:term") ? true : false;
-	Boolean isCaseInsensitive = false;
+        Boolean isTerm = json.get("@type").asText().equals("korap:term") ? true
+                : false;
+        Boolean isCaseInsensitive = false;
 
-	if (json.has("caseInsensitive") && json.get("caseInsensitive").asBoolean())
-	    isCaseInsensitive = true;
+        if (json.has("caseInsensitive")
+                && json.get("caseInsensitive").asBoolean())
+            isCaseInsensitive = true;
 
-	StringBuilder value = new StringBuilder();
+        StringBuilder value = new StringBuilder();
 
-	// expect orth? expect lemma? 
-	// s:den | i:den | cnx/l:die | mate/m:mood:ind | cnx/syn:@PREMOD |
-	// mate/m:number:sg | opennlp/p:ART
+        // expect orth? expect lemma? 
+        // s:den | i:den | cnx/l:die | mate/m:mood:ind | cnx/syn:@PREMOD |
+        // mate/m:number:sg | opennlp/p:ART
 
-	if (json.has("foundry") && json.get("foundry").asText().length() > 0)
-	    value.append(json.get("foundry").asText()).append('/');
+        if (json.has("foundry") && json.get("foundry").asText().length() > 0)
+            value.append(json.get("foundry").asText()).append('/');
 
-	// No default foundry defined
+        // No default foundry defined
 
-	if (json.has("layer") && json.get("layer").asText().length() > 0) {
-	    String layer = json.get("layer").asText();
-	    switch (layer) {
+        if (json.has("layer") && json.get("layer").asText().length() > 0) {
+            String layer = json.get("layer").asText();
+            switch (layer) {
 
-	    case "lemma":
-		layer = "l";
-		break;
+                case "lemma":
+                    layer = "l";
+                    break;
 
-	    case "pos":
-		layer = "p";
-		break;
+                case "pos":
+                    layer = "p";
+                    break;
 
-	    case "orth":
-		// TODO: THIS IS A BUG! AND SHOULD BE NAMED "SURFACE"
-		layer = "s";
-		break;
+                case "orth":
+                    // TODO: THIS IS A BUG! AND SHOULD BE NAMED "SURFACE"
+                    layer = "s";
+                    break;
 
-	    case "struct":
-		layer = "s";
-		break;
+                case "struct":
+                    layer = "s";
+                    break;
 
-	    case "const":
-		layer = "c";
-		break;
-	    };
+                case "const":
+                    layer = "c";
+                    break;
+            }
+            ;
 
-	    if (isCaseInsensitive && isTerm) {
-		if (layer.equals("s")) {
-		    layer = "i";
-		}
-		else {
-		    this.addWarning(
-			767,
-		        "Case insensitivity is currently not supported for this layer"
-		    );
-		};
-	    };
+            if (isCaseInsensitive && isTerm) {
+                if (layer.equals("s")) {
+                    layer = "i";
+                }
+                else {
+                    this.addWarning(767,
+                            "Case insensitivity is currently not supported for this layer");
+                }
+                ;
+            }
+            ;
 
-	    // Ignore foundry for orth layer
-	    if (layer.equals("s") || layer.equals("i"))
-		value.setLength(0);
+            // Ignore foundry for orth layer
+            if (layer.equals("s") || layer.equals("i")) value.setLength(0);
 
-	    value.append(layer).append(':');
-	};
+            value.append(layer).append(':');
+        }
+        ;
 
-	if (json.has("key") && json.get("key").asText().length() > 0) {
-	    String key = json.get("key").asText();
-	    value.append(isCaseInsensitive ? key.toLowerCase() : key);
-	};
+        if (json.has("key") && json.get("key").asText().length() > 0) {
+            String key = json.get("key").asText();
+            value.append(isCaseInsensitive ? key.toLowerCase() : key);
+        }
+        ;
 
-	if (json.has("value") && json.get("value").asText().length() > 0)
-	    value.append(':').append(json.get("value").asText());
+        if (json.has("value") && json.get("value").asText().length() > 0)
+            value.append(':').append(json.get("value").asText());
 
-	// Regular expression or wildcard
-	if (isTerm && json.has("type")) {
-	    switch (json.get("type").asText()) {
-	    case "type:regex":
-		return this.seg(this.re(value.toString(), isCaseInsensitive));
-	    case "type:wildcard":
-		return this.seq(this.wc(value.toString(), isCaseInsensitive));
-	    case "type:string":
-		break;
-	    default:
-		this.addWarning(746, "Term type is not supported - treated as a string");
-	    };
-	};
+        // Regular expression or wildcard
+        if (isTerm && json.has("type")) {
+            switch (json.get("type").asText()) {
+                case "type:regex":
+                    return this
+                            .seg(this.re(value.toString(), isCaseInsensitive));
+                case "type:wildcard":
+                    return this
+                            .seq(this.wc(value.toString(), isCaseInsensitive));
+                case "type:string":
+                    break;
+                default:
+                    this.addWarning(746,
+                            "Term type is not supported - treated as a string");
+            }
+            ;
+        }
+        ;
 
-	if (isTerm)
-	    return this.seg(value.toString());
+        if (isTerm) return this.seg(value.toString());
 
-	if (json.has("attr"))
-	    this.addWarning(
-	        768,
-		"Attributes are currently not supported - results may not be correct");
+        if (json.has("attr"))
+            this.addWarning(768,
+                    "Attributes are currently not supported - results may not be correct");
 
-	return this.tag(value.toString());
+        return this.tag(value.toString());
     };
 
     /*
-    public boolean hasWarning () {
-	if (this.warning != null)
-	    return true;
-	return true;
-    };
-
-    public String getWarning () {
-        return this.warning;
-    };
-
-    public void addWarning (String msg) {
-	if (msg == null)
-	    return;
-	if (this.warning == null)
-	    this.warning = msg;
-	else
-	    this.warning += "; " + msg;
-    };
-
-    public void setWarning (String warning) {
-	this.warning = warning;
-    };
-    */
+     * public boolean hasWarning () { if (this.warning != null) return true;
+     * return true; }; public String getWarning () { return this.warning; };
+     * public void addWarning (String msg) { if (msg == null) return; if
+     * (this.warning == null) this.warning = msg; else this.warning += "; " +
+     * msg; }; public void setWarning (String warning) { this.warning = warning;
+     * };
+     */
 
     // SpanRegexQueryWrapper
     /**
      * Create a query object based on a regular expression.
+     * 
      * @param re The regular expession as a string.
      */
-    public SpanRegexQueryWrapper re (String re) {
-	return new SpanRegexQueryWrapper(this.field, re, RegExp.ALL, false);
+    public SpanRegexQueryWrapper re(String re) {
+        return new SpanRegexQueryWrapper(this.field, re, RegExp.ALL, false);
     };
 
     /**
      * Create a query object based on a regular expression.
+     * 
      * @param re The regular expession as a string.
      * @param flas The regular expession flag as an integer.
      */
-    public SpanRegexQueryWrapper re (String re, int flags) {
-	return new SpanRegexQueryWrapper(this.field, re, flags, false);
+    public SpanRegexQueryWrapper re(String re, int flags) {
+        return new SpanRegexQueryWrapper(this.field, re, flags, false);
     };
 
     /**
      * Create a query object based on a regular expression.
+     * 
      * @param re The regular expession as a string.
      * @param flag The regular expession flag.
      * @param caseinsensitive A boolean value indicating case insensitivity.
      */
-    public SpanRegexQueryWrapper re (String re, int flags, boolean caseinsensitive) {
-	return new SpanRegexQueryWrapper(this.field, re, flags, caseinsensitive);
+    public SpanRegexQueryWrapper re(String re, int flags,
+            boolean caseinsensitive) {
+        return new SpanRegexQueryWrapper(this.field, re, flags, caseinsensitive);
     };
 
     /**
      * Create a query object based on a regular expression.
+     * 
      * @param re The regular expession as a string.
      * @param caseinsensitive A boolean value indicating case insensitivity.
      */
-    public SpanRegexQueryWrapper re (String re, boolean caseinsensitive) {
-	return new SpanRegexQueryWrapper(this.field, re, RegExp.ALL, caseinsensitive);
+    public SpanRegexQueryWrapper re(String re, boolean caseinsensitive) {
+        return new SpanRegexQueryWrapper(this.field, re, RegExp.ALL,
+                caseinsensitive);
     };
 
     // SpanWildcardQueryWrapper
     /**
      * Create a query object based on a wildcard term.
+     * 
      * @param wc The wildcard term as a string.
      */
-    public SpanWildcardQueryWrapper wc (String wc) {
-	return new SpanWildcardQueryWrapper(this.field, wc, false);
+    public SpanWildcardQueryWrapper wc(String wc) {
+        return new SpanWildcardQueryWrapper(this.field, wc, false);
     };
 
     /**
      * Create a query object based on a wildcard term.
+     * 
      * @param wc The wildcard term as a string.
      * @param caseinsensitive A boolean value indicating case insensitivity.
      */
-    public SpanWildcardQueryWrapper wc (String wc, boolean caseinsensitive) {
-	return new SpanWildcardQueryWrapper(this.field, wc, caseinsensitive);
+    public SpanWildcardQueryWrapper wc(String wc, boolean caseinsensitive) {
+        return new SpanWildcardQueryWrapper(this.field, wc, caseinsensitive);
     };
 
-
     // SpanSegmentQueries
     /**
      * Create a segment query object.
      */
-    public SpanSegmentQueryWrapper seg () {
-	return new SpanSegmentQueryWrapper(this.field);
+    public SpanSegmentQueryWrapper seg() {
+        return new SpanSegmentQueryWrapper(this.field);
     };
 
-
     /**
      * Create a segment query object.
+     * 
      * @param terms[] An array of terms, the segment consists of.
      */
-    public SpanSegmentQueryWrapper seg (SpanRegexQueryWrapper ... terms) {
-	SpanSegmentQueryWrapper ssq = new SpanSegmentQueryWrapper(this.field);
-	for (SpanRegexQueryWrapper t : terms) {
-	    ssq.with(t);
-	};
-	return ssq;
+    public SpanSegmentQueryWrapper seg(SpanRegexQueryWrapper... terms) {
+        SpanSegmentQueryWrapper ssq = new SpanSegmentQueryWrapper(this.field);
+        for (SpanRegexQueryWrapper t : terms) {
+            ssq.with(t);
+        }
+        ;
+        return ssq;
     };
 
-    public SpanSegmentQueryWrapper seg (SpanAlterQueryWrapper ... terms) {
-	SpanSegmentQueryWrapper ssq = new SpanSegmentQueryWrapper(this.field);
-	for (SpanAlterQueryWrapper t : terms) {
-	    ssq.with(t);
-	};
-	return ssq;
+    public SpanSegmentQueryWrapper seg(SpanAlterQueryWrapper... terms) {
+        SpanSegmentQueryWrapper ssq = new SpanSegmentQueryWrapper(this.field);
+        for (SpanAlterQueryWrapper t : terms) {
+            ssq.with(t);
+        }
+        ;
+        return ssq;
     };
 
-    public SpanSegmentQueryWrapper seg (String ... terms) {
-	SpanSegmentQueryWrapper ssq = new SpanSegmentQueryWrapper(this.field);
-	for (String t : terms) {
-	    ssq.with(t);
-	};
-	return ssq;
+    public SpanSegmentQueryWrapper seg(String... terms) {
+        SpanSegmentQueryWrapper ssq = new SpanSegmentQueryWrapper(this.field);
+        for (String t : terms) {
+            ssq.with(t);
+        }
+        ;
+        return ssq;
     };
 
     // Create an empty segment
-    public SpanRepetitionQueryWrapper empty () {
-	return new SpanRepetitionQueryWrapper();
+    public SpanRepetitionQueryWrapper empty() {
+        return new SpanRepetitionQueryWrapper();
     };
 
     // SpanSegmentAlterQueries
     /**
      * Create a segment alternation query object.
+     * 
      * @param terms[] An array of alternative terms.
      */
-    public SpanAlterQueryWrapper or (SpanQueryWrapper ... terms) {
-	SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(this.field);
-	for (SpanQueryWrapper t : terms) {
-	    ssaq.or(t);
-	};
-	return ssaq;
+    public SpanAlterQueryWrapper or(SpanQueryWrapper... terms) {
+        SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(this.field);
+        for (SpanQueryWrapper t : terms) {
+            ssaq.or(t);
+        }
+        ;
+        return ssaq;
     };
 
-    public SpanAlterQueryWrapper or (String ... terms) {
-	SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(this.field);
-	for (String t : terms) {
-	    ssaq.or(t);
-	};
-	return ssaq;
+    public SpanAlterQueryWrapper or(String... terms) {
+        SpanAlterQueryWrapper ssaq = new SpanAlterQueryWrapper(this.field);
+        for (String t : terms) {
+            ssaq.or(t);
+        }
+        ;
+        return ssaq;
     };
 
-
     // SpanSegmentSequenceQueries
     /**
      * Create a sequence of segments query object.
      */
-    public SpanSequenceQueryWrapper seq () {
-	return new SpanSequenceQueryWrapper(this.field);
+    public SpanSequenceQueryWrapper seq() {
+        return new SpanSequenceQueryWrapper(this.field);
     };
 
-
     /**
      * Create a sequence of segments query object.
+     * 
      * @param terms[] An array of segment defining terms.
      */
-    public SpanSequenceQueryWrapper seq (SpanQueryWrapper ... terms) {
-	SpanSequenceQueryWrapper sssq = new SpanSequenceQueryWrapper(this.field);
-	for (SpanQueryWrapper t : terms) {
-	    sssq.append(t);
-	};
-	return sssq;
+    public SpanSequenceQueryWrapper seq(SpanQueryWrapper... terms) {
+        SpanSequenceQueryWrapper sssq = new SpanSequenceQueryWrapper(this.field);
+        for (SpanQueryWrapper t : terms) {
+            sssq.append(t);
+        }
+        ;
+        return sssq;
     };
 
-
     /**
      * Create a sequence of segments query object.
+     * 
      * @param re A SpanSegmentRegexQuery, starting the sequence.
      */
-    public SpanSequenceQueryWrapper seq (SpanRegexQueryWrapper re) {
-	return new SpanSequenceQueryWrapper(this.field, re);
+    public SpanSequenceQueryWrapper seq(SpanRegexQueryWrapper re) {
+        return new SpanSequenceQueryWrapper(this.field, re);
     };
 
-
-    public SpanSequenceQueryWrapper seq (Object ... terms) {
-	SpanSequenceQueryWrapper ssq = new SpanSequenceQueryWrapper(this.field);
-	for (Object t : terms) {
-	    if (t instanceof SpanQueryWrapper) {
-		ssq.append((SpanQueryWrapper) t);
-	    }
-	    else if (t instanceof SpanRegexQueryWrapper) {
-		ssq.append((SpanRegexQueryWrapper) t);
-	    }
-	    else {
-		log.error("{} is not an acceptable parameter for seq()", t.getClass());
-		return ssq;
-	    };
-	};
-	return ssq;
+    public SpanSequenceQueryWrapper seq(Object... terms) {
+        SpanSequenceQueryWrapper ssq = new SpanSequenceQueryWrapper(this.field);
+        for (Object t : terms) {
+            if (t instanceof SpanQueryWrapper) {
+                ssq.append((SpanQueryWrapper) t);
+            }
+            else if (t instanceof SpanRegexQueryWrapper) {
+                ssq.append((SpanRegexQueryWrapper) t);
+            }
+            else {
+                log.error("{} is not an acceptable parameter for seq()",
+                        t.getClass());
+                return ssq;
+            }
+            ;
+        }
+        ;
+        return ssq;
     };
 
-    public SpanElementQueryWrapper tag (String element) {
-	return new SpanElementQueryWrapper(this.field, element);
+    public SpanElementQueryWrapper tag(String element) {
+        return new SpanElementQueryWrapper(this.field, element);
     };
 
     /**
      * Create a wrapping within query object.
+     * 
      * @param element A SpanQuery.
      * @param embedded A SpanQuery that is wrapped in the element.
      */
     @Deprecated
-    public SpanWithinQueryWrapper within (SpanQueryWrapper element,
-					  SpanQueryWrapper embedded) {
-	return new SpanWithinQueryWrapper(element, embedded);
+    public SpanWithinQueryWrapper within(SpanQueryWrapper element,
+            SpanQueryWrapper embedded) {
+        return new SpanWithinQueryWrapper(element, embedded);
     };
 
-    public SpanWithinQueryWrapper contains (SpanQueryWrapper element,
-					  SpanQueryWrapper embedded) {
-	return new SpanWithinQueryWrapper(element, embedded, WITHIN);
+    public SpanWithinQueryWrapper contains(SpanQueryWrapper element,
+            SpanQueryWrapper embedded) {
+        return new SpanWithinQueryWrapper(element, embedded, WITHIN);
     };
 
-    public SpanWithinQueryWrapper startswith (SpanQueryWrapper element,
-					      SpanQueryWrapper embedded) {
-	return new SpanWithinQueryWrapper(element, embedded, STARTSWITH);
+    public SpanWithinQueryWrapper startswith(SpanQueryWrapper element,
+            SpanQueryWrapper embedded) {
+        return new SpanWithinQueryWrapper(element, embedded, STARTSWITH);
     };
 
-    public SpanWithinQueryWrapper endswith (SpanQueryWrapper element,
-					    SpanQueryWrapper embedded) {
-	return new SpanWithinQueryWrapper(element, embedded, ENDSWITH);
+    public SpanWithinQueryWrapper endswith(SpanQueryWrapper element,
+            SpanQueryWrapper embedded) {
+        return new SpanWithinQueryWrapper(element, embedded, ENDSWITH);
     };
 
-    public SpanWithinQueryWrapper overlaps (SpanQueryWrapper element,
-					    SpanQueryWrapper embedded) {
-	return new SpanWithinQueryWrapper(element, embedded, OVERLAP);
-    }; 
+    public SpanWithinQueryWrapper overlaps(SpanQueryWrapper element,
+            SpanQueryWrapper embedded) {
+        return new SpanWithinQueryWrapper(element, embedded, OVERLAP);
+    };
 
-    public SpanWithinQueryWrapper matches (SpanQueryWrapper element,
-					   SpanQueryWrapper embedded) {
-	return new SpanWithinQueryWrapper(element, embedded, MATCH);
-    }; 
+    public SpanWithinQueryWrapper matches(SpanQueryWrapper element,
+            SpanQueryWrapper embedded) {
+        return new SpanWithinQueryWrapper(element, embedded, MATCH);
+    };
 
     // Class
-    public SpanClassQueryWrapper _ (byte number, SpanQueryWrapper element) {
-	return new SpanClassQueryWrapper(element, number);
+    public SpanClassQueryWrapper _(byte number, SpanQueryWrapper element) {
+        return new SpanClassQueryWrapper(element, number);
     };
 
-    public SpanClassQueryWrapper _ (int number, SpanQueryWrapper element) {
-	return new SpanClassQueryWrapper(element, number);
+    public SpanClassQueryWrapper _(int number, SpanQueryWrapper element) {
+        return new SpanClassQueryWrapper(element, number);
     };
 
-    public SpanClassQueryWrapper _ (short number, SpanQueryWrapper element) {
-	return new SpanClassQueryWrapper(element, number);
+    public SpanClassQueryWrapper _(short number, SpanQueryWrapper element) {
+        return new SpanClassQueryWrapper(element, number);
     };
 
-    public SpanClassQueryWrapper _ (SpanQueryWrapper element) {
-	return new SpanClassQueryWrapper(element);
+    public SpanClassQueryWrapper _(SpanQueryWrapper element) {
+        return new SpanClassQueryWrapper(element);
     };
 
     // MatchModify
-    public SpanMatchModifyQueryWrapper shrink (byte number, SpanQueryWrapper element) {
-	return new SpanMatchModifyQueryWrapper(element, number);
+    public SpanMatchModifyQueryWrapper shrink(byte number,
+            SpanQueryWrapper element) {
+        return new SpanMatchModifyQueryWrapper(element, number);
     };
 
-    public SpanMatchModifyQueryWrapper shrink (int number, SpanQueryWrapper element) {
-	return new SpanMatchModifyQueryWrapper(element, number);
+    public SpanMatchModifyQueryWrapper shrink(int number,
+            SpanQueryWrapper element) {
+        return new SpanMatchModifyQueryWrapper(element, number);
     };
 
-    public SpanMatchModifyQueryWrapper shrink (short number, SpanQueryWrapper element) {
-	return new SpanMatchModifyQueryWrapper(element, number);
+    public SpanMatchModifyQueryWrapper shrink(short number,
+            SpanQueryWrapper element) {
+        return new SpanMatchModifyQueryWrapper(element, number);
     };
 
-    public SpanMatchModifyQueryWrapper shrink (SpanQueryWrapper element) {
-	return new SpanMatchModifyQueryWrapper(element);
+    public SpanMatchModifyQueryWrapper shrink(SpanQueryWrapper element) {
+        return new SpanMatchModifyQueryWrapper(element);
     };
 
     // Repetition
-    public SpanRepetitionQueryWrapper repeat (SpanQueryWrapper element, int exact) {
-	return new SpanRepetitionQueryWrapper(element, exact);
+    public SpanRepetitionQueryWrapper repeat(SpanQueryWrapper element, int exact) {
+        return new SpanRepetitionQueryWrapper(element, exact);
     };
 
-    public SpanRepetitionQueryWrapper repeat (SpanQueryWrapper element, int min, int max) {
-	return new SpanRepetitionQueryWrapper(element, min, max);
+    public SpanRepetitionQueryWrapper repeat(SpanQueryWrapper element, int min,
+            int max) {
+        return new SpanRepetitionQueryWrapper(element, min, max);
     };
 };
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanExpansionQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanExpansionQuery.java
index 2a0c80e..65f786a 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanExpansionQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanExpansionQuery.java
@@ -75,8 +75,8 @@
  * [large black leather jacket]       non match
  * </pre>
  * 
- * The positions of the expansion parts can be stored in payloads by using a
- * class number (optional).
+ * The positions of the expansion parts can be optionally stored in payloads
+ * together with a class number.
  * 
  * @author margaretha
  * */
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanSubspanQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanSubspanQuery.java
index 2cba5d9..ecb1bd9 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanSubspanQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanSubspanQuery.java
@@ -10,25 +10,26 @@
 import org.apache.lucene.search.spans.Spans;
 import org.apache.lucene.util.Bits;
 
+import de.ids_mannheim.korap.query.spans.ElementSpans;
 import de.ids_mannheim.korap.query.spans.SubSpans;
 
 /**
  * This query extracts a subspan from another span. The subspan starts from a
  * startOffset until startOffset + length. A positive startOffset is counted
- * from the start of the span, while a negative startOffset is counted from the
- * end of the span. <br />
+ * from the start of the span, while a negative startOffset is calculated from
+ * the end of the span. <br />
  * <br />
  * SpanSubspanQuery takes a SpanQuery as its input and creates subspans from the
  * resulting spans of the SpanQuery. For instance:
  * 
  * <pre>
- * SpanTermQuery stq = new SpanTermQuery(new Term("tokens","s:Hund"))
- * SpanSubspanQuery ssq = new SpanSubspanQuery(stq, 0, 2, true);
+ * SpanElementQuery seq = new SpanElementQuery(new SpanElementQuery(&quot;tokens&quot;, &quot;s&quot;);
+ * SpanSubspanQuery ssq = new SpanSubspanQuery(seq, 0, 2, true);
  * </pre>
  * 
- * In this example, the SpanSubspanQuery creates subspans "Hu" from all the
- * occurrences of TermSpans "Hund", that starts from index 0 to 2. It also
- * collects all payloads from the TermSpans for the SubSpans.
+ * In this example, the SpanSubspanQuery creates subspans, that are the first
+ * two tokens of all sentences. It also collects all payloads from the
+ * {@link ElementSpans} for the SubSpans.
  * 
  * @author margaretha
  * */
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java
index cad169a..e4a77d6 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java
@@ -20,7 +20,7 @@
  * spans' occurrences which are not in a sentence or a paragraph (with respect
  * to the element distance type currently used), are ignored.
  * 
- * Note: elements cannot overlap to each other.
+ * Note: elements cannot overlap with each other.
  * 
  * @author margaretha
  * */
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedExclusionSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedExclusionSpans.java
index 2f3857d..d213425 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedExclusionSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedExclusionSpans.java
@@ -25,6 +25,10 @@
  * span, and a positive number (including 0) signifies the expansion to the
  * <em>right</em> of the original span.
  * 
+ * The expansion offsets, namely the start and end position of an expansion
+ * part, can be stored in payloads. A class number is assigned to the offsets
+ * grouping them altogether.
+ * 
  * @author margaretha
  * */
 public class ExpandedExclusionSpans extends SimpleSpans {
@@ -249,8 +253,8 @@
                 //System.out.println(start+","+end);
 
                 cs = new CandidateSpan(start, end, firstSpans.doc(),
-                        firstSpans.cost(), createPayloads(firstSpans.end(),
-                                end));
+                        firstSpans.cost(),
+                        createPayloads(firstSpans.end(), end));
                 candidateSpans.add(cs);
                 counter++;
             }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedSpans.java
index 4e4f551..da70fd9 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/ExpandedSpans.java
@@ -18,6 +18,10 @@
  * <code>n</code> token positions to either left or right direction from the
  * original spans. See examples in {@link SpanExpansionQuery}.
  * 
+ * The expansion offsets, namely the start and end position of an expansion
+ * part, can be stored in payloads. A class number is assigned to the offsets
+ * grouping them altogether.
+ * 
  * @author margaretha
  * */
 public class ExpandedSpans extends SimpleSpans {
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SubSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/SubSpans.java
index c691a46..7af989a 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SubSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SubSpans.java
@@ -55,9 +55,11 @@
      */
     private boolean advance() throws IOException {
         while (hasMoreSpans) {
-            setMatch();
+            if (findMatch()) {
+                hasMoreSpans = firstSpans.next();
+                return true;
+            }
             hasMoreSpans = firstSpans.next();
-            return true;
         }
         return false;
     }
@@ -67,15 +69,28 @@
      * 
      * @throws IOException
      */
-    public void setMatch() throws IOException {
-        if (this.startOffset < 0)
+    public boolean findMatch() throws IOException {
+        if (this.startOffset < 0) {
             matchStartPosition = firstSpans.end() + startOffset;
-        else
+            if (matchStartPosition < firstSpans.start()) {
+                matchStartPosition = firstSpans.start();
+            }
+        }
+        else {
             matchStartPosition = firstSpans.start() + startOffset;
+            if (matchStartPosition >= firstSpans.end()) {
+                return false;
+            }
+        }
 
         matchEndPosition = matchStartPosition + this.length;
+        if (matchEndPosition > firstSpans.end()) {
+            matchEndPosition = firstSpans.end();
+        }
+
         matchPayload = firstSpans.getPayload();
         matchDocNumber = firstSpans.doc();
+        return true;
     }
 
     @Override
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java
index fcfab27..99a83a4 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java
@@ -15,7 +15,9 @@
 /**
  * Enumeration of token-based distance span matches consisting of two child
  * spans having an actual distance in the range of the minimum and maximum
- * distance parameters specified in the corresponding query.
+ * distance parameters specified in the corresponding query. A TokenDistanceSpan
+ * starts from the minimum start positions of its child spans and ends at the
+ * maximum end positions of the child spans.
  * 
  * @author margaretha
  * */
diff --git a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSubspanQueryWrapper.java b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSubspanQueryWrapper.java
new file mode 100644
index 0000000..2af6c19
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSubspanQueryWrapper.java
@@ -0,0 +1,50 @@
+package de.ids_mannheim.korap.query.wrap;
+
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.ids_mannheim.korap.query.SpanSubspanQuery;
+import de.ids_mannheim.korap.util.QueryException;
+
+/**
+ * @author margaretha
+ * 
+ */
+public class SpanSubspanQueryWrapper extends SpanQueryWrapper {
+
+    private SpanQueryWrapper subquery;
+    private int startOffset, length;
+
+    private Logger log = LoggerFactory.getLogger(SpanSubspanQueryWrapper.class);
+
+    public SpanSubspanQueryWrapper(SpanQueryWrapper sqw, int startOffset,
+            int length) {
+        this.subquery = sqw;
+        this.startOffset = startOffset;
+        this.length = length;
+    }
+
+    @Override
+    public SpanQuery toQuery() throws QueryException {
+        if (subquery == null) {
+            log.warn("Subquery of SpanSubspanquery is null.");
+            return null;
+        }
+
+        if (length == 0) {
+            log.warn("Not SpanSubspanQuery. Creating only the subquery.");
+            return subquery.toQuery();
+        }
+
+        SpanQuery sq = subquery.toQuery();
+        if (sq instanceof SpanTermQuery) {
+            log.warn("Not SpanSubspanQuery. Creating only the subquery.");
+            return sq;
+        }
+
+        return new SpanSubspanQuery(subquery.toQuery(), startOffset, length,
+                true);
+    }
+}
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestAttributeIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestAttributeIndex.java
index 293286b..d4a9ae2 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestAttributeIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestAttributeIndex.java
@@ -19,249 +19,234 @@
 import de.ids_mannheim.korap.query.SpanWithAttributeQuery;
 
 public class TestAttributeIndex {
-	
-	private KorapIndex ki = new KorapIndex();
-	private KorapResult kr;
-	private FieldDocument fd;
 
-	public TestAttributeIndex() throws IOException {
-		ki = new KorapIndex();		
-	}
-	
-	private FieldDocument createFieldDoc0(){		
-		fd = new FieldDocument();
-		fd.addString("ID", "doc-0");
-		fd.addTV("base",
-			 "bcbabd",			 
-			 "[(0-1)s:a|_1#0-1|<>:s#0-5$<i>5<s>-1|<>:div#0-3$<i>3<s>1|<>:div#0-2$<i>2<s>2|@:class=header$<s>1<i>3|@:class=header$<s>2<i>2]" +
-			 "[(1-2)s:e|_2#1-2|<>:a#1-2$<i>2<s>1|@:class=header$<s>1<i>2]" +
-			 "[(2-3)s:e|_3#2-3|<>:div#2-3$<i>5<s>1|@:class=time$<s>1<i>5]" +
-			 "[(3-4)s:a|_4#3-4|<>:div#3-5$<i>5<s>1|@:class=header$<s>1<i>5]" + 
-			 "[(4-5)s:b|_5#4-5|<>:div#4-5$<i>5<s>1|<>:a#4-5$<i>5<s>2|@:class=header$<s>2<i>5]" +
-			 "[(5-6)s:d|_6#5-6|<>:s#5-6$<i>6<s>1|<>:div#5-6$<i>6<s>-1|@:class=header$<s>1<i>6]"+
-			 "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7<s>2|<>:div#6-7$<i>7<s>1|@:class=header$<s>1<i>7|@:class=header$<s>2<i>7]");
-			 
-		return fd;
-	}
-	
-	private FieldDocument createFieldDoc1(){
-		fd = new FieldDocument();
-		fd.addString("ID", "doc-1");
-		fd.addTV("base",
-			 "bcbabd",			 
-			 "[(0-1)s:b|_1#0-1|<>:s#0-5$<i>5<s>-1|<>:div#0-3$<i>3<s>1|@:class=header$<s>1<i>3|@:class=title$<s>1<i>3|@:class=book$<s>1<i>3]" +
-			 "[(1-2)s:c|_2#1-2|<>:div#1-2$<i>2<s>1|@:class=header$<s>1<i>2|@:class=title$<s>1<i>2]" +
-			 "[(2-3)s:b|_3#2-3|<>:div#2-3$<i>5<s>1|@:class=book$<s>1<i>5]" +
-			 "[(3-4)s:a|_4#3-4|<>:div#3-5$<i>5<s>1|@:class=title$<s>1<i>5]" +
-			 "[(4-5)s:b|_5#4-5|<>:div#4-5$<i>5<s>1|@:class=header$<s>1<i>5|@:class=book$<s>1<i>5|@:class=title$<s>1<i>5]" +
-			 "[(5-6)s:d|_6#5-6|<>:s#5-6$<i>6<s>-1|<>:div#5-6$<i>6<s>1|@:class=header$<s>1<i>6]"+
-			 "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7<s>2|<>:div#6-7$<i>7<s>1|@:class=header$<s>1<i>7|@:class=title$<s>1<i>7]");
-			 
-		return fd;
-	}
-	
-	private FieldDocument createFieldDoc2(){
-		fd = new FieldDocument();
-		fd.addString("ID", "doc-1");
-		fd.addTV("base",
-			 "bcbabd",			 
-			 "[(0-1)s:b|_1#0-1|<>:s#0-5$<i>5<s>1|<>:div#0-3$<i>3<s>2|@:class=header$<s>2<i>3|@:class=book$<s>1<i>5|@:class=book$<s>2<i>3]" +
-			 "[(1-2)s:e|_2#1-2|<>:div#1-2$<i>2<s>1|<>:a#1-2$<i>2<s>2|@:class=book$<s>2<i>2|@:class=header$<s>1<i>2]" +
-			 "[(2-3)s:b|_3#2-3|<>:div#2-3$<i>5<s>1|<>:a#1-2$<i>2<s>2|@:class=header$<s>2<i>2|@:class=book$<s>1<i>5]" +
-			 "[(3-4)s:a|_4#3-4|<>:div#3-5$<i>5<s>1|@:class=title$<s>1<i>5]" + 
-			 "[(4-5)s:b|_5#4-5|<>:div#4-5$<i>5<s>1|@:class=header$<s>1<i>5|@:class=book$<s>1<i>5|@:class=book$<s>1<i>5]" +
-			 "[(5-6)s:d|_6#5-6|<>:s#5-6$<i>6<s>-1|<>:div#5-6$<i>6<s>1|@:class=header$<s>1<i>6]"+
-			 "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7<s>2|<>:div#6-7$<i>7<s>1|@:class=header$<s>1<i>7|@:class=book$<s>2<i>7]");
-			 
-		return fd;
-	}
-	
-		
-	/** Test matching elementRef
-	 * @throws IOException 
-	 * */
-	@Test
-	public void testCase1() throws IOException {
-		ki.addDoc(createFieldDoc0());
-		ki.commit();
-		
-		SpanAttributeQuery saq = new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=header")), 
-				true);
-		
-		List<SpanQuery> sql = new ArrayList<>();
-		sql.add(saq);
-		
-		// div with @class=header
-		SpanQuery sq = new SpanWithAttributeQuery(
-				new SpanElementQuery("base", "div"),
-				sql, true);
-		
-		kr = ki.search(sq, (short) 10);
-		
-		assertEquals((long) 4, kr.getTotalResults());
-		assertEquals(0,kr.getMatch(0).getStartPos());
-		assertEquals(2,kr.getMatch(0).getEndPos());
-		assertEquals(0,kr.getMatch(1).getStartPos());
-		assertEquals(3,kr.getMatch(1).getEndPos());
-		assertEquals(3,kr.getMatch(2).getStartPos());
-		assertEquals(5,kr.getMatch(2).getEndPos());
-		assertEquals(6,kr.getMatch(3).getStartPos());
-		assertEquals(7,kr.getMatch(3).getEndPos());
-	}	
-	
-	/** Test multiple attributes and negation
-	 * @throws IOException 
-	 * */
-	@Test
-	public void testCase2() throws IOException{
-		ki.addDoc(createFieldDoc1());
-		ki.commit();
-		// header and title
-		List<SpanQuery> sql = new ArrayList<>();
-		sql.add(new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=header")),true)
-		);
-		sql.add(new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=title")),true)
-		);
-		
-		SpanQuery sq = new SpanWithAttributeQuery(
-				new SpanElementQuery("base", "div"),
-				sql, true);
-		
-		kr = ki.search(sq, (short) 10);
-				
-		assertEquals((long) 4, kr.getTotalResults());
-		assertEquals(0,kr.getMatch(0).getStartPos());
-		assertEquals(3,kr.getMatch(0).getEndPos());
-		assertEquals(1,kr.getMatch(1).getStartPos());
-		assertEquals(2,kr.getMatch(1).getEndPos());
-		assertEquals(4,kr.getMatch(2).getStartPos());
-		assertEquals(5,kr.getMatch(2).getEndPos());
-		assertEquals(6,kr.getMatch(3).getStartPos());
-		assertEquals(7,kr.getMatch(3).getEndPos());
-		
-		// Add not Attribute
-		// header and title, not book
-		sql.add(new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=book")),true,true)
-		);
-		
-		sq = new SpanWithAttributeQuery(
-				new SpanElementQuery("base", "div"),
-				sql, true);
-		
-		kr = ki.search(sq, (short) 10);
-		
-		assertEquals((long) 2, kr.getTotalResults());
-		assertEquals(1,kr.getMatch(0).getStartPos());
-		assertEquals(2,kr.getMatch(0).getEndPos());
-		assertEquals(6,kr.getMatch(1).getStartPos());
-		assertEquals(7,kr.getMatch(1).getEndPos());		
-		
-		// Test multiple negations
-		// header, not title, not book
-		sql.remove(1);
-		sql.add(new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=title")),true,true)
-		);
-		
-		sq = new SpanWithAttributeQuery(
-				new SpanElementQuery("base", "div"),
-				sql, true);
-		
-		kr = ki.search(sq, (short) 10);
-		assertEquals((long) 1, kr.getTotalResults());
-		assertEquals(5,kr.getMatch(0).getStartPos());
-		assertEquals(6,kr.getMatch(0).getEndPos());
-	}	
-		
-	/** same attribute types referring to different element types
-	 * */	 
-	@Test
-	public void testCase3() throws IOException{
-		ki.addDoc(createFieldDoc2());
-		ki.commit();
-		
-		List<SpanQuery> sql = new ArrayList<>();
-		sql.add(new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=header")),true)
-		);		
-		sql.add(new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=book")),true,true)
-		);
-		SpanQuery sq = new SpanWithAttributeQuery(
-				new SpanElementQuery("base", "div"),
-				sql, true);
-		
-		kr = ki.search(sq, (short) 10);
-		
-		assertEquals((long) 3, kr.getTotalResults());
-		assertEquals(1,kr.getMatch(0).getStartPos());
-		assertEquals(2,kr.getMatch(0).getEndPos());
-		assertEquals(5,kr.getMatch(1).getStartPos());
-		assertEquals(6,kr.getMatch(1).getEndPos());
-		assertEquals(6,kr.getMatch(2).getStartPos());
-		assertEquals(7,kr.getMatch(2).getEndPos());
-	}
-	
-	/** Test skipto doc for spanWithAttribute*/
-	@Test
-	public void testCase4() throws IOException{
-		ki.addDoc(createFieldDoc1());
-		ki.addDoc(createFieldDoc0());		
-		ki.addDoc(createFieldDoc2());
-		ki.commit();
-		
-		SpanAttributeQuery saq = new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=book")), 
-				true);
-		
-		List<SpanQuery> sql = new ArrayList<>();
-		sql.add(saq);
-		
-		SpanWithAttributeQuery sq = new SpanWithAttributeQuery(
-				new SpanElementQuery("base", "div"),
-				sql, true);
-		
-		kr = ki.search(sq, (short) 10);
-		assertEquals((long) 6,kr.getTotalResults());
-		
-		SpanNextQuery snq = new SpanNextQuery(
-				new SpanTermQuery(new Term("base", "s:e"))
-				,sq);
-		
-		kr = ki.search(snq, (short) 10);
-		
-		assertEquals((long) 1,kr.getTotalResults());
-		assertEquals(2,kr.getMatch(0).getLocalDocID());
-		assertEquals(1,kr.getMatch(0).getStartPos());
-		assertEquals(5,kr.getMatch(0).getEndPos());		
-	}
-	
-	/** Arbitrary elements with a specific attribute
-	 *  This is just spanAttribute query, to get the elementEnd, 
-	 *  you have to use getElementEnd(). Alternatives (unimplemented): 
-	 *  	1) store in payload?
-	 *  	2) wrap as a span
-	 * */
-	@Test
-	public void testCase5() throws IOException{
-		ki.addDoc(createFieldDoc1());
-		ki.commit();
-		SpanAttributeQuery saq = new SpanAttributeQuery(
-				new SpanTermQuery(new Term("base","@:class=book")), 
-				true);
-		kr = ki.search(saq, (short) 10);
-		assertEquals((long) 3, kr.getTotalResults());
-		
-		/*for (int i=0; i< kr.getTotalResults(); i++){
-			System.out.println(
-				kr.match(i).getLocalDocID()+" "+
-				kr.match(i).startPos + " " +
-				kr.match(i).endPos
-		    );
-		}*/
-	}
+    private KorapIndex ki = new KorapIndex();
+    private KorapResult kr;
+    private FieldDocument fd;
+
+    public TestAttributeIndex() throws IOException {
+        ki = new KorapIndex();
+    }
+
+    private FieldDocument createFieldDoc0() {
+        fd = new FieldDocument();
+        fd.addString("ID", "doc-0");
+        fd.addTV(
+                "base",
+                "bcbabd",
+                "[(0-1)s:a|_1#0-1|<>:s#0-5$<i>5<s>-1|<>:div#0-3$<i>3<s>1|<>:div#0-2$<i>2<s>2|@:class=header$<s>1<i>3|@:class=header$<s>2<i>2]"
+                        + "[(1-2)s:e|_2#1-2|<>:a#1-2$<i>2<s>1|@:class=header$<s>1<i>2]"
+                        + "[(2-3)s:e|_3#2-3|<>:div#2-3$<i>5<s>1|@:class=time$<s>1<i>5]"
+                        + "[(3-4)s:a|_4#3-4|<>:div#3-5$<i>5<s>1|@:class=header$<s>1<i>5]"
+                        + "[(4-5)s:b|_5#4-5|<>:div#4-5$<i>5<s>1|<>:a#4-5$<i>5<s>2|@:class=header$<s>2<i>5]"
+                        + "[(5-6)s:d|_6#5-6|<>:s#5-6$<i>6<s>1|<>:div#5-6$<i>6<s>-1|@:class=header$<s>1<i>6]"
+                        + "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7<s>2|<>:div#6-7$<i>7<s>1|@:class=header$<s>1<i>7|@:class=header$<s>2<i>7]");
+
+        return fd;
+    }
+
+    private FieldDocument createFieldDoc1() {
+        fd = new FieldDocument();
+        fd.addString("ID", "doc-1");
+        fd.addTV(
+                "base",
+                "bcbabd",
+                "[(0-1)s:b|_1#0-1|<>:s#0-5$<i>5<s>-1|<>:div#0-3$<i>3<s>1|@:class=header$<s>1<i>3|@:class=title$<s>1<i>3|@:class=book$<s>1<i>3]"
+                        + "[(1-2)s:c|_2#1-2|<>:div#1-2$<i>2<s>1|@:class=header$<s>1<i>2|@:class=title$<s>1<i>2]"
+                        + "[(2-3)s:b|_3#2-3|<>:div#2-3$<i>5<s>1|@:class=book$<s>1<i>5]"
+                        + "[(3-4)s:a|_4#3-4|<>:div#3-5$<i>5<s>1|@:class=title$<s>1<i>5]"
+                        + "[(4-5)s:b|_5#4-5|<>:div#4-5$<i>5<s>1|@:class=header$<s>1<i>5|@:class=book$<s>1<i>5|@:class=title$<s>1<i>5]"
+                        + "[(5-6)s:d|_6#5-6|<>:s#5-6$<i>6<s>-1|<>:div#5-6$<i>6<s>1|@:class=header$<s>1<i>6]"
+                        + "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7<s>2|<>:div#6-7$<i>7<s>1|@:class=header$<s>1<i>7|@:class=title$<s>1<i>7]");
+
+        return fd;
+    }
+
+    private FieldDocument createFieldDoc2() {
+        fd = new FieldDocument();
+        fd.addString("ID", "doc-1");
+        fd.addTV(
+                "base",
+                "bcbabd",
+                "[(0-1)s:b|_1#0-1|<>:s#0-5$<i>5<s>1|<>:div#0-3$<i>3<s>2|@:class=header$<s>2<i>3|@:class=book$<s>1<i>5|@:class=book$<s>2<i>3]"
+                        + "[(1-2)s:e|_2#1-2|<>:div#1-2$<i>2<s>1|<>:a#1-2$<i>2<s>2|@:class=book$<s>2<i>2|@:class=header$<s>1<i>2]"
+                        + "[(2-3)s:b|_3#2-3|<>:div#2-3$<i>5<s>1|<>:a#1-2$<i>2<s>2|@:class=header$<s>2<i>2|@:class=book$<s>1<i>5]"
+                        + "[(3-4)s:a|_4#3-4|<>:div#3-5$<i>5<s>1|@:class=title$<s>1<i>5]"
+                        + "[(4-5)s:b|_5#4-5|<>:div#4-5$<i>5<s>1|@:class=header$<s>1<i>5|@:class=book$<s>1<i>5|@:class=book$<s>1<i>5]"
+                        + "[(5-6)s:d|_6#5-6|<>:s#5-6$<i>6<s>-1|<>:div#5-6$<i>6<s>1|@:class=header$<s>1<i>6]"
+                        + "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7<s>2|<>:div#6-7$<i>7<s>1|@:class=header$<s>1<i>7|@:class=book$<s>2<i>7]");
+
+        return fd;
+    }
+
+    /**
+     * Test matching elementRef
+     * 
+     * @throws IOException
+     * */
+    @Test
+    public void testCase1() throws IOException {
+        ki.addDoc(createFieldDoc0());
+        ki.commit();
+
+        SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(
+                new Term("base", "@:class=header")), true);
+
+        // div with @class=header
+        SpanQuery sq = new SpanWithAttributeQuery(new SpanElementQuery("base",
+                "div"), saq, true);
+
+        kr = ki.search(sq, (short) 10);
+
+        assertEquals((long) 4, kr.getTotalResults());
+        assertEquals(0, kr.getMatch(0).getStartPos());
+        assertEquals(2, kr.getMatch(0).getEndPos());
+        assertEquals(0, kr.getMatch(1).getStartPos());
+        assertEquals(3, kr.getMatch(1).getEndPos());
+        assertEquals(3, kr.getMatch(2).getStartPos());
+        assertEquals(5, kr.getMatch(2).getEndPos());
+        assertEquals(6, kr.getMatch(3).getStartPos());
+        assertEquals(7, kr.getMatch(3).getEndPos());
+    }
+
+    /**
+     * Test multiple attributes and negation
+     * 
+     * @throws IOException
+     * */
+    @Test
+    public void testCase2() throws IOException {
+        ki.addDoc(createFieldDoc1());
+        ki.commit();
+        // header and title
+        List<SpanQuery> sql = new ArrayList<>();
+        sql.add(new SpanAttributeQuery(new SpanTermQuery(new Term("base",
+                "@:class=header")), true));
+        sql.add(new SpanAttributeQuery(new SpanTermQuery(new Term("base",
+                "@:class=title")), true));
+
+        SpanQuery sq = new SpanWithAttributeQuery(new SpanElementQuery("base",
+                "div"), sql, true);
+
+        kr = ki.search(sq, (short) 10);
+
+        assertEquals((long) 4, kr.getTotalResults());
+        assertEquals(0, kr.getMatch(0).getStartPos());
+        assertEquals(3, kr.getMatch(0).getEndPos());
+        assertEquals(1, kr.getMatch(1).getStartPos());
+        assertEquals(2, kr.getMatch(1).getEndPos());
+        assertEquals(4, kr.getMatch(2).getStartPos());
+        assertEquals(5, kr.getMatch(2).getEndPos());
+        assertEquals(6, kr.getMatch(3).getStartPos());
+        assertEquals(7, kr.getMatch(3).getEndPos());
+
+        // Add not Attribute
+        // header and title, not book
+        sql.add(new SpanAttributeQuery(new SpanTermQuery(new Term("base",
+                "@:class=book")), true, true));
+
+        sq = new SpanWithAttributeQuery(new SpanElementQuery("base", "div"),
+                sql, true);
+
+        kr = ki.search(sq, (short) 10);
+
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(1, kr.getMatch(0).getStartPos());
+        assertEquals(2, kr.getMatch(0).getEndPos());
+        assertEquals(6, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+
+        // Test multiple negations
+        // header, not title, not book
+        sql.remove(1);
+        sql.add(new SpanAttributeQuery(new SpanTermQuery(new Term("base",
+                "@:class=title")), true, true));
+
+        sq = new SpanWithAttributeQuery(new SpanElementQuery("base", "div"),
+                sql, true);
+
+        kr = ki.search(sq, (short) 10);
+        assertEquals((long) 1, kr.getTotalResults());
+        assertEquals(5, kr.getMatch(0).getStartPos());
+        assertEquals(6, kr.getMatch(0).getEndPos());
+    }
+
+    /**
+     * same attribute types referring to different element types
+     * */
+    @Test
+    public void testCase3() throws IOException {
+        ki.addDoc(createFieldDoc2());
+        ki.commit();
+
+        List<SpanQuery> sql = new ArrayList<>();
+        sql.add(new SpanAttributeQuery(new SpanTermQuery(new Term("base",
+                "@:class=header")), true));
+        sql.add(new SpanAttributeQuery(new SpanTermQuery(new Term("base",
+                "@:class=book")), true, true));
+        SpanQuery sq = new SpanWithAttributeQuery(new SpanElementQuery("base",
+                "div"), sql, true);
+
+        kr = ki.search(sq, (short) 10);
+
+        assertEquals((long) 3, kr.getTotalResults());
+        assertEquals(1, kr.getMatch(0).getStartPos());
+        assertEquals(2, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(6, kr.getMatch(1).getEndPos());
+        assertEquals(6, kr.getMatch(2).getStartPos());
+        assertEquals(7, kr.getMatch(2).getEndPos());
+    }
+
+    /** Test skipto doc for spanWithAttribute */
+    @Test
+    public void testCase4() throws IOException {
+        ki.addDoc(createFieldDoc1());
+        ki.addDoc(createFieldDoc0());
+        ki.addDoc(createFieldDoc2());
+        ki.commit();
+
+        SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(
+                new Term("base", "@:class=book")), true);
+
+        List<SpanQuery> sql = new ArrayList<>();
+        sql.add(saq);
+
+        SpanWithAttributeQuery sq = new SpanWithAttributeQuery(
+                new SpanElementQuery("base", "div"), sql, true);
+
+        kr = ki.search(sq, (short) 10);
+        assertEquals((long) 6, kr.getTotalResults());
+
+        SpanNextQuery snq = new SpanNextQuery(new SpanTermQuery(new Term(
+                "base", "s:e")), sq);
+
+        kr = ki.search(snq, (short) 10);
+
+        assertEquals((long) 1, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getLocalDocID());
+        assertEquals(1, kr.getMatch(0).getStartPos());
+        assertEquals(5, kr.getMatch(0).getEndPos());
+    }
+
+    /**
+     * Arbitrary elements with a specific attribute This is just spanAttribute
+     * query, to get the elementEnd, you have to use getElementEnd().
+     * Alternatives (unimplemented): 1) store in payload? 2) wrap as a span
+     * */
+    @Test
+    public void testCase5() throws IOException {
+        ki.addDoc(createFieldDoc1());
+        ki.commit();
+        SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(
+                new Term("base", "@:class=book")), true);
+        kr = ki.search(saq, (short) 10);
+        assertEquals((long) 3, kr.getTotalResults());
+
+        /*
+         * for (int i=0; i< kr.getTotalResults(); i++){ System.out.println(
+         * kr.match(i).getLocalDocID()+" "+ kr.match(i).startPos + " " +
+         * kr.match(i).endPos ); }
+         */
+    }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
index 7c5d021..81c3d67 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
@@ -28,7 +28,7 @@
 
 1. return all words that are subjects of (that are linked by the “SUBJ” relation to) the string “beginnt”
 xip/syntax-dep_rel:beginnt >[func=”SUBJ”] xip/syntax-dep_rel:.*
--> rel("SUBJ", highlight(query1), new TermQuery("s:beginnt"))
+-> rel("SUBJ", highlight(query1), new TermQuery("s:beginnt")) 
 
 
 SUBJ ist modelliert mit offset für den gesamten Bereich
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestSubSpanIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestSubSpanIndex.java
index ba9b14f..58f88f5 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestSubSpanIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestSubSpanIndex.java
@@ -15,45 +15,77 @@
 import de.ids_mannheim.korap.query.SpanDistanceQuery;
 import de.ids_mannheim.korap.query.SpanSubspanQuery;
 
-
 public class TestSubSpanIndex {
-	
-	KorapResult kr;
-    KorapIndex ki;  
-    
+
+    KorapResult kr;
+    KorapIndex ki;
+
+    public TestSubSpanIndex() throws IOException {
+        ki = new KorapIndex();
+        ki.addDocFile(getClass().getResource("/wiki/00001.json.gz").getFile(),
+                true);
+        ki.commit();
+    }
+
     @Test
     public void testCase1() throws IOException {
-    	ki = new KorapIndex();
-    	ki.addDocFile(
-    	        getClass().getResource("/wiki/00001.json.gz").getFile(),true);
-		ki.commit();
-		
-		SpanDistanceQuery sdq = new SpanDistanceQuery(
-				new SpanTermQuery(new Term("tokens","tt/p:NN")), 
-				new SpanTermQuery(new Term("tokens","tt/p:VAFIN")), 
-				new DistanceConstraint(5, 5, true, false), 
-				true);
-		
-		SpanSubspanQuery ssq = new SpanSubspanQuery(sdq, 0, 2, true);		
-		kr = ki.search(ssq, (short) 10);
-		
-		assertEquals((long) 8,kr.getTotalResults());
-		assertEquals(35, kr.getMatch(0).getStartPos());
+        SpanDistanceQuery sdq = new SpanDistanceQuery(
+                new SpanTermQuery(new Term("tokens", "tt/p:NN")), 
+                new SpanTermQuery(new Term("tokens", "tt/p:VAFIN")), 
+                new DistanceConstraint(5, 5, true,false), true);
+
+        SpanSubspanQuery ssq = new SpanSubspanQuery(sdq, 0, 2, true);
+        kr = ki.search(ssq, (short) 10);
+
+        assertEquals((long) 8, kr.getTotalResults());
+        assertEquals(35, kr.getMatch(0).getStartPos());
         assertEquals(37, kr.getMatch(0).getEndPos());
         assertEquals(179, kr.getMatch(1).getStartPos());
         assertEquals(181, kr.getMatch(1).getEndPos());
-		
-		ssq = new SpanSubspanQuery(sdq, -2, 2, true);		
-		kr = ki.search(ssq, (short) 10);
-		
-		assertEquals(39, kr.getMatch(0).getStartPos());
+
+        ssq = new SpanSubspanQuery(sdq, -2, 2, true);
+        kr = ki.search(ssq, (short) 10);
+
+        assertEquals(39, kr.getMatch(0).getStartPos());
         assertEquals(41, kr.getMatch(0).getEndPos());
         assertEquals(183, kr.getMatch(1).getStartPos());
         assertEquals(185, kr.getMatch(1).getEndPos());
-		
-		/*for (KorapMatch km : kr.getMatches()){
-			System.out.println(km.getStartPos() +","+km.getEndPos()
-					+km.getSnippetBrackets());
-		}*/
-	}
+
+        /*
+         * for (KorapMatch km : kr.getMatches()){
+         * System.out.println(km.getStartPos() +","+km.getEndPos()
+         * +km.getSnippetBrackets()); }
+         */
+    }
+
+    @Test
+    public void testCase2() {
+        SpanDistanceQuery sdq = new SpanDistanceQuery(
+                new SpanTermQuery(new Term("tokens", "tt/p:NN")), 
+                new SpanTermQuery(new Term("tokens", "tt/p:VAFIN")), 
+                new DistanceConstraint(5, 5, true,false), true);
+        
+        SpanSubspanQuery ssq = new SpanSubspanQuery(sdq, 0, 7, true);
+        kr = ki.search(ssq, (short) 10);
+
+        assertEquals(35, kr.getMatch(0).getStartPos());
+        assertEquals(41, kr.getMatch(0).getEndPos());
+        assertEquals(179, kr.getMatch(1).getStartPos());
+        assertEquals(185, kr.getMatch(1).getEndPos());
+        
+        ssq = new SpanSubspanQuery(sdq, -7, 4, true);
+        kr = ki.search(ssq, (short) 10);
+        
+        assertEquals((long) 8, kr.getTotalResults());
+        assertEquals(35, kr.getMatch(0).getStartPos());
+        assertEquals(39, kr.getMatch(0).getEndPos());
+        assertEquals(179, kr.getMatch(1).getStartPos());
+        assertEquals(183, kr.getMatch(1).getEndPos());
+        
+        /* for (KorapMatch km : kr.getMatches()){
+         System.out.println(km.getStartPos() +","+km.getEndPos()
+         +km.getSnippetBrackets()); }*/
+         
+    }
+
 }
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanSubspanQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanSubspanQueryJSON.java
new file mode 100644
index 0000000..e1e473d
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanSubspanQueryJSON.java
@@ -0,0 +1,26 @@
+package de.ids_mannheim.korap.query;
+
+import static de.ids_mannheim.korap.TestSimple.getJSONQuery;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.lucene.search.spans.SpanQuery;
+import org.junit.Test;
+
+import de.ids_mannheim.korap.query.wrap.SpanQueryWrapper;
+import de.ids_mannheim.korap.util.QueryException;
+
+/**
+ * @author margaretha
+ * 
+ */
+public class TestSpanSubspanQueryJSON {
+
+    @Test
+    public void testCase1() throws QueryException {
+        String filepath = getClass().getResource("/queries/submatch.jsonld")
+                .getFile();
+        SpanQueryWrapper sqwi = getJSONQuery(filepath);
+        SpanQuery sq = sqwi.toQuery();
+        assertEquals(sq.toString(), "subspan(<tokens:s />,1,4)");
+    }
+}
diff --git a/src/test/resources/queries/submatch.jsonld b/src/test/resources/queries/submatch.jsonld
new file mode 100644
index 0000000..36153eb
--- /dev/null
+++ b/src/test/resources/queries/submatch.jsonld
@@ -0,0 +1,30 @@
+{
+   "@context":"http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld",
+   "errors":[
+
+   ],
+   "warnings":[
+
+   ],
+   "messages":[
+
+   ],
+   "collection":null,
+   "query":{
+      "@type":"korap:reference",
+      "operation":"operation:focus",
+      "operands":[
+         {
+            "@type":"korap:span",
+            "key":"s"
+         }
+      ],
+      "spanRef":[
+         1,
+         4
+      ]
+   },
+   "meta":{
+
+   }
+}
