Merge branch 'master' into cache

Conflicts:
	Changes

Change-Id: I11af8d279cf75019cd8bce2a968ffff057577dc1
diff --git a/Changes b/Changes
index 1b807e2..607d58d 100644
--- a/Changes
+++ b/Changes
@@ -1,11 +1,12 @@
 0.59.7 2021-11-08
     - Implemented a new cache with on disk storage and auto-update (margaretha).
 
-0.59.6 2021-10-26
+0.59.6 2021-11-10
     - [bugfix] Fixed skipping of focus spans (fixed #78; margaretha,
       diewald)
     - [bugfix] Clear matchlist if skip fails in NextSpans
       (margaretha, diewald)
+    - [bugfix] Handle span attributes for milestones correctly (diewald)
 
 0.59.5 2021-10-26
     - [bugfix] Fixed candidate settings in token distance spans
diff --git a/misc/payloads.md b/misc/payloads.md
index 234a97b..26b901d 100644
--- a/misc/payloads.md
+++ b/misc/payloads.md
@@ -190,7 +190,7 @@
 
 * the TUI of the token, span or relation to which the attribute
   belongs to (stored in short)
-* for spans: the corresponding span end position (stored in integer)
+* for non-milestone spans: the corresponding span end position (stored in integer)
 
 For example:
 
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
index 0e96652..db75a14 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
@@ -167,7 +167,17 @@
         // short spanId = payloadBuffer.getShort(5);
         // int end = payloadBuffer.getInt(1);
         short spanId = payloadBuffer.getShort(1);
-        int end = payloadBuffer.getInt(3);
+
+        int end;
+
+        if (payload.get(0).length >= 7) {
+            end = payloadBuffer.getInt(3);
+        }
+
+        // Associated with a milestone element
+        else {
+            end = firstSpans.start();
+        }
 
         return new CandidateAttributeSpan(firstSpans, payloadTypeIdentifier,
                 spanId, end);
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 b69bc75..c210cc5 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestAttributeIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestAttributeIndex.java
@@ -463,6 +463,46 @@
         kr = ki.search(swaq, (short) 10);
     }
 
+    @Test
+    public void testIndexOutOfBoundsBug () throws IOException {
+        FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-1");
+        fd.addTV("base", "abc",
+                 "[(0-1)s:a|_1$<i>0<i>1|<>:a$<b>64<i>0<i>3<i>3<b>0<s>1|@:x=y$<b>17<s>1<i>3]"
+                + "[(1-2)s:b|_2$<i>1<i>2|<>:d$<b>65<i>1<b>0<s>7|@:x=y$<b>17<s>7]"
+                + "[(2-3)s:c|_3$<i>2<i>3|<>:a$<b>64<i>2<i>3<i>3<b>0<s>2]");
+
+        ki.addDoc(fd);
+        ki.commit();
+
+        fd = new FieldDocument();
+        fd.addString("ID", "doc-2");
+        fd.addTV("base", "abc",
+                 "[(0-1)s:a|_1$<i>0<i>1|<>:a$<b>64<i>0<i>3<i>3<b>0<s>1|@:x=y$<b>17<s>1<i>3]"
+                + "[(1-2)s:b|_2$<i>1<i>2]"
+                + "[(2-3)s:c|_3$<i>2<i>3]");
+
+        ki.addDoc(fd);
+        ki.commit();
+        
+        // Check <a x=y>
+        SpanQuery sq = new SpanWithAttributeQuery(
+            new SpanElementQuery("base", "a"),
+            new SpanAttributeQuery(new SpanTermQuery(new Term("base", "@:x=y")), true),
+            true
+            );
+        
+        assertEquals("spanElementWithAttribute(<base:a />, spanAttribute(base:@:x=y))", sq.toString());
+        kr = ki.search(sq, (short) 10);
+
+        assertEquals(2, kr.getTotalResults());
+
+        assertEquals(0, kr.getMatch(0).getStartPos());
+        assertEquals(3, kr.getMatch(0).getEndPos());
+        assertEquals(0, kr.getMatch(1).getStartPos());
+        assertEquals(3, kr.getMatch(1).getEndPos());
+    }
+    
 
     @Test
     public void testAttributeRealIndex () throws QueryException, IOException {