Fixed support for textual match expansion (ugly)

Change-Id: I23cf1f8548ea7b7975dc6b7b5018dc8655c68dc6
diff --git a/src/main/java/de/ids_mannheim/korap/response/Match.java b/src/main/java/de/ids_mannheim/korap/response/Match.java
index d3f45f4..9a752e5 100644
--- a/src/main/java/de/ids_mannheim/korap/response/Match.java
+++ b/src/main/java/de/ids_mannheim/korap/response/Match.java
@@ -87,6 +87,9 @@
 	// end marker of highlights that are pagebreaks
 	private static final int PB_MARKER = -99999;
 
+	// Textual elements that are in context
+	private static final int CONTEXT = -99998;
+
     // This advices the java compiler to ignore all loggings
     public static final boolean DEBUG = true;
 
@@ -1550,18 +1553,19 @@
                 int[] e = openList.removeFirst().clone();
 
 				// Mark as opener
-                e[3] = 1;
+				e[3] = 1;
 
 				if (DEBUG) {
 
 					//      -1: match
 					//    < -1: relation target
+					//  -99998: context
 					// >= 2048: relation source
 					// >=  256: annotation
 					
 					log.trace(
-						"Add open with number {} to stack at {}-{}",
-						e[2], e[0], e[1]
+						"Add open with number {} to stack at {}-{} as {}",
+						e[2], e[0], e[1], e[3]
 						);
 				};
 
@@ -1663,10 +1667,13 @@
         // Add match span, in case no inner match is defined
         if (this.innerMatchEndPos == -1) {
 			if (DEBUG)
-				log.debug("Added array to span with {} (1)", intArray);
+				log.debug("Added array to match span with {} (1)", intArray);
             this.span.add(intArray);
 		};
 
+		// Add context highlight
+		this.span.add(new int[]{intArray[0], intArray[1], CONTEXT, 0});
+
         // highlights
         // -- I'm not sure about this.
         if (this.highlight != null) {
diff --git a/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinator.java b/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinator.java
index 93c1f67..610df0b 100644
--- a/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinator.java
+++ b/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinator.java
@@ -77,11 +77,13 @@
 			log.trace("Add opening {} to stack", number);
     };
 
-	// Add empty highlight to the stack
+
+    // Add empty highlight to the stack
     public void addEmpty (int pagenumber) {
         this.combine.add(new HighlightCombinatorElement((byte) 3, pagenumber));
     };
 
+
     // Add closing highlight combinator to the stack
     public void addClose (int number) {
         HighlightCombinatorElement lastComb;
diff --git a/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinatorElement.java b/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinatorElement.java
index d2701a6..272a9f1 100644
--- a/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinatorElement.java
+++ b/src/main/java/de/ids_mannheim/korap/response/match/HighlightCombinatorElement.java
@@ -15,6 +15,10 @@
 */
 public class HighlightCombinatorElement {
 
+	// Number -1:     Match
+	// Number -99998: Context
+	private final static int CONTEXT = -99998;
+	
     // Type 0: Textual data
     // Type 1: Opening
     // Type 2: Closing
@@ -58,7 +62,7 @@
 
 
     // Return html fragment for this combinator element
-public String toHTML (Match match, FixedBitSet level, byte[] levelCache, HashSet joins) {
+	public String toHTML (Match match, FixedBitSet level, byte[] levelCache, HashSet joins) {
 
         // Opening
         if (this.type == 1) {
@@ -69,6 +73,11 @@
                 sb.append("<mark>");
             }
 
+			// This is context
+			else if (this.number == CONTEXT) {
+				// DO nothing
+			}
+
 			// This is a relation target
             else if (this.number < -1) {
 
@@ -142,6 +151,9 @@
 
         // This is a Closing tag
         else if (this.type == 2) {
+			if (this.number == CONTEXT)
+				return "";
+			
             if (this.number < -1 || this.number >= 256)
                 return "</span>";
 
@@ -173,6 +185,11 @@
                 sb.append("[");
             }
 
+			// This is context
+			else if (this.number == CONTEXT) {
+				// DO nothing
+			}
+
             // Identifier
             else if (this.number < -1) {
                 sb.append("{#");
@@ -203,6 +220,11 @@
             return sb.toString();
         }
         else if (this.type == 2) {
+
+			// This is context
+			if (this.number == CONTEXT)
+				return "";
+			
             if (this.number == -1)
                 return "]";
             return "}";
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index bca8731..20f61ae 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -14,7 +14,7 @@
             level="trace">
       <AppenderRef ref="Console"/>
     </Logger>
-    <Logger name="de.ids_mannheim.korap.KrillIndex"
+    <Logger name="de.ids_mannheim.korap.response.Match"
             additivity="false"
             level="trace">
       <AppenderRef ref="Console"/>
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java b/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
index 7f659ed..f4bbc45 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
@@ -20,6 +20,7 @@
 import de.ids_mannheim.korap.query.QueryBuilder;
 import de.ids_mannheim.korap.index.FieldDocument;
 import de.ids_mannheim.korap.response.Match;
+import de.ids_mannheim.korap.response.SearchContext;
 import de.ids_mannheim.korap.response.Result;
 import de.ids_mannheim.korap.response.match.MatchIdentifier;
 import de.ids_mannheim.korap.response.match.PosIdentifier;
@@ -409,21 +410,126 @@
         ki.addDoc(getClass().getResourceAsStream("/wiki/WPD17-H81-63495.json.gz"), true);
         ki.commit();
 
-        Match km = ki.getMatchInfo("match-WPD17/H81/63495-p88-91", "tokens",
-								   "xyz", "s", true, true, true);
-		String snippet = km.getSnippetHTML();
+        Match km;
+		String snippet;
+		km = ki.getMatchInfo("match-WPD17/H81/63495-p88-91", "tokens",
+							 "xyz", "s", false, false, false);
+		km.setContext(new SearchContext(true, (short) 2, true, (short) 2));
+
+		snippet = km.getSnippetHTML();
 		assertEquals(
 			"<span class=\"context-left\">"+
+			"<span class=\"more\"></span>"+
+			"angesehen wurde. "+
 			"</span>"+
 			"<span class=\"match\">"+
 			"<mark>Der alte Baum</mark>"+
 			"</span>"+
 			"<span class=\"context-right\">"+
-			" war eine Sommerlinde (Tilia platyphyllos) , der neue ist eine Winterlinde (Tilia cordata)."+
+			" war eine"+
+			"<span class=\"more\"></span>"+
 			"</span>",
 			snippet
 			);
-		/*
+
+		km = ki.getMatchInfo("match-WPD17/H81/63495-p88-91", "tokens",
+								   "xyz", "s", true, true, true);
+		//km.setContext(new SearchContext(true, (short) 2, true, (short) 2));
+		snippet = km.getSnippetHTML();
+		assertEquals(
+			"<span class=\"context-left\">"+
+			"</span>"+
+			"<span class=\"match\">"+
+			"<mark>Der alte Baum</mark>"+
+			" war eine Sommerlinde (Tilia platyphyllos) , der neue ist eine Winterlinde (Tilia cordata)."+
+			"</span>"+
+			"<span class=\"context-right\">"+
+			"</span>",
+			snippet
+			);
+
+		km = ki.getMatchInfo("match-WPD17/H81/63495-p88-91", "tokens",
+							 null, null, false, true, true);
+		snippet = km.getSnippetHTML();
+		assertEquals(
+			"<span class=\"context-left\"></span>"+
+			"<span class=\"match\">"+
+			"<mark>"+
+			"<span title=\"tt/l:die\">"+
+			"<span title=\"tt/p:ART\">Der</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:alt\">"+
+			"<span title=\"tt/p:ADJA\">alte</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:Baum\">"+
+			"<span title=\"tt/p:NN\">Baum</span>"+
+			"</span>"+
+			"</mark>"+
+			" "+
+			"<span title=\"tt/l:sein\">"+
+			"<span title=\"tt/p:VAFIN\">war</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:eine\">"+
+			"<span title=\"tt/p:ART\">eine</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:Sommerlinde\">"+
+			"<span title=\"tt/l:Sommerlinde\">"+
+			"<span title=\"tt/p:NE\">"+
+			"<span title=\"tt/p:NN\">Sommerlinde</span>"+
+			"</span>"+
+			"</span>"+
+			"</span>"+
+			" ("+
+			"<span title=\"tt/p:NE\">Tilia</span>"+
+			" "+
+			"<span title=\"tt/p:ADJA\">"+
+			"<span title=\"tt/p:ADJD\">"+
+			"<span title=\"tt/p:NE\">"+
+			"<span title=\"tt/p:NN\">"+
+			"<span title=\"tt/p:VVFIN\">platyphyllos</span>"+
+			"</span>"+
+			"</span>"+
+			"</span>"+
+			"</span>"+
+			") , "+
+			"<span title=\"tt/l:die\">"+
+			"<span title=\"tt/p:ART\">der</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:neu\">"+
+			"<span title=\"tt/p:ADJA\">neue</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:sein\">"+
+			"<span title=\"tt/p:VAFIN\">ist</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:eine\">"+
+			"<span title=\"tt/p:ART\">eine</span>"+
+			"</span>"+
+			" "+
+			"<span title=\"tt/l:Winterlinde\">"+
+			"<span title=\"tt/l:Winterlinde\">"+
+			"<span title=\"tt/p:NE\">"+
+			"<span title=\"tt/p:NN\">Winterlinde</span>"+
+			"</span>"+
+			"</span>"+
+			"</span>"+
+			" ("+
+			"<span title=\"tt/p:NE\">Tilia</span>"+
+			" "+
+			"<span title=\"tt/p:NE\">cordata</span>"+
+			")."+
+			"</span>"+
+			"<span class=\"context-right\">"+
+			"</span>",
+			snippet
+			);
+/*
 
 		Match km = ki.getMatchInfo("match-WPD17/H81/63495-p88-91", "tokens",
 								   "dereko", "s", true, true, true);