Merge "Failing test for focus sort"
diff --git a/Changes b/Changes
index aa15d42..4bc1f21 100644
--- a/Changes
+++ b/Changes
@@ -13,6 +13,7 @@
       korap.index.TestNextIndex.testNextExpansionBug() (margaretha)  
     - [bugfix] Fixed left expansion match order (margaretha)
     - [bugfix] Fixed right expansion match order & expansion over start (margaretha)
+    - [feature] Added opt() method to QueryBuilder (diewald)
 
 0.58.0 2018-09-03
     - [feature] Implemented referencing cached collection (margaretha)
diff --git a/src/main/java/de/ids_mannheim/korap/query/QueryBuilder.java b/src/main/java/de/ids_mannheim/korap/query/QueryBuilder.java
index da433ba..761ddd9 100644
--- a/src/main/java/de/ids_mannheim/korap/query/QueryBuilder.java
+++ b/src/main/java/de/ids_mannheim/korap/query/QueryBuilder.java
@@ -455,4 +455,9 @@
             int max) {
         return new SpanRepetitionQueryWrapper(element, min, max);
     };
+
+    // Optionality
+    public SpanRepetitionQueryWrapper opt (SpanQueryWrapper element) {
+        return new SpanRepetitionQueryWrapper(element, 0, 1);
+    };
 };
diff --git a/src/test/java/de/ids_mannheim/korap/TestSimple.java b/src/test/java/de/ids_mannheim/korap/TestSimple.java
index 64ce39f..b0554ca 100644
--- a/src/test/java/de/ids_mannheim/korap/TestSimple.java
+++ b/src/test/java/de/ids_mannheim/korap/TestSimple.java
@@ -90,9 +90,10 @@
         for (int i = 0; i < characters.length; i++) {
             String fixChar = characters[i];
             surface += fixChar;
-            annotation +=
-                "[("+i+"-"+(i+1)+")s:"+fixChar+
-                "|_"+i+"$<i>"+i+"<i>"+(i+1)+"]";
+            annotation += "[("+i+"-"+(i+1)+")s:"+fixChar;
+            if (i == 0)
+                annotation += "|<>:base/s:t$<b>64<i>0<i>" + characters.length + "<i>" + characters.length + "<b>0";
+            annotation += "|_"+i+"$<i>"+i+"<i>"+(i+1)+"]";
         };
 
         fd.addTV("base",surface, annotation);
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestSpanExpansionIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestSpanExpansionIndex.java
index 71bd0a7..8103dde 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestSpanExpansionIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestSpanExpansionIndex.java
@@ -641,6 +641,29 @@
         assertEquals("a[[bcce]]f", kr.getMatch(6).getSnippetBrackets());
         assertEquals(18, kr.getTotalResults());        
     }
+
+
+    @Test
+    public void testRightExpansionWithTextBoundary () throws IOException, QueryException {
+        KrillIndex ki = new KrillIndex();
+        ki.addDoc(simpleFieldDoc("aabcd"));
+        ki.commit();
+
+        QueryBuilder kq = new QueryBuilder("base");
+
+        // a[ab]?[]{0,2}
+        SpanQuery sq = kq.seq(kq.seg("s:a")).append(kq.opt(kq.or("s:a","s:b"))).append(kq.repeat(kq.empty(),0,5)).toQuery();
+        assertEquals(
+            "focus(254: spanContain(<base:base/s:t />, {254: "+
+            "spanExpansion(spanOr([base:s:a, spanNext(base:s:a, spanOr([base:s:a, base:s:b]))]), []{0, 5}, right)"+
+            "}))", sq.toString());
+
+        Result kr = ki.search(sq, (short) 25);
+        assertEquals("[[aabcd]]", kr.getMatch(8).getSnippetBrackets());
+        assertEquals("a[[a]]bcd", kr.getMatch(9).getSnippetBrackets());
+        assertEquals(16, kr.getTotalResults());        
+    }
+
     
     @Test
     public void testLeftExpansionWrongSorting () throws IOException {
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestKrillQuery.java b/src/test/java/de/ids_mannheim/korap/query/TestKrillQuery.java
index cb4c5b6..af6b568 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestKrillQuery.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestKrillQuery.java
@@ -311,6 +311,14 @@
                 sq.toString());
     };
 
+    @Test
+    public void KorapOptQuery () throws QueryException {
+        QueryBuilder kq = new QueryBuilder("field");
+        SpanQuery sq = kq.seq(kq.opt(kq.seg("x"))).append(kq.seg("y")).toQuery();
+        assertEquals(
+                "spanOr([field:y, spanNext(field:x, field:y)])",
+                sq.toString());
+    };  
 
 
     @Test