Merge remote-tracking branch 'origin/master' into new-index

Conflicts:
	src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java
	src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
	src/main/java/de/ids_mannheim/korap/user/User.java
	src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java

Change-Id: I2067b58c279c98915beb0a85462a6f3ea5744f36
diff --git a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
index 6b7f7c2..1ad51dd 100644
--- a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
+++ b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
@@ -1,5 +1,6 @@
 package de.ids_mannheim.korap.config;
 
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import lombok.Getter;
@@ -7,13 +8,17 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.*;
+import java.util.regex.Pattern;
 
 /**
  * if configuration class is extended, loadSubTypes method should be
@@ -73,7 +78,18 @@
     private String default_const;
     
     private String policyConfig;
-
+    private ArrayList<String> foundries;
+    private ArrayList<String> layers;
+    
+//    private List<String> publicLicenses;
+//    private List<String> freeLicenses;
+//    private List<String> allLicenses;
+    
+    private Pattern publicLicensePattern;
+    private Pattern freeLicensePattern;
+    private Pattern allLicensePattern;
+    
+    
     // deprec?!
     private final BACKENDS DEFAULT_ENGINE = BACKENDS.LUCENE;
 
@@ -83,9 +99,11 @@
      * 
      * @param properties
      * @return
+     * @throws IOException 
+     * @throws KustvaktException 
      */
     protected Properties load (Properties properties)
-            throws MalformedURLException {
+            throws IOException {
         maxhits = new Integer(properties.getProperty("maxhits", "50000"));
         returnhits = new Integer(properties.getProperty("returnhits", "50000"));
         indexDir = properties.getProperty("krill.indexDir", "");
@@ -145,7 +163,16 @@
         passcodeSaltField = properties.getProperty("security.passcode.salt",
                 "accountCreation");
         
+//        freeLicenses = Arrays.asList(license.split("|"));
+//        publicLicenses = Arrays.asList(properties.getProperty("kustvakt.availability.public","").split("|"));
+//        allLicenses = Arrays.asList(properties.getProperty("kustvakt.availability.all","").split("|"));
+        
+        freeLicensePattern = Pattern.compile(properties.getProperty("kustvakt.availability.free",""));
+        publicLicensePattern = Pattern.compile(properties.getProperty("kustvakt.availability.public",""));
+        allLicensePattern = Pattern.compile(properties.getProperty("kustvakt.availability.all",""));
+        
         policyConfig = properties.getProperty("policies.config");
+        setFoundriesAndLayers(policyConfig);
         
         KUSTVAKT_USER.put(Attributes.ID, Integer.parseInt(properties.getProperty("kustvakt.init.user.id")));
         KUSTVAKT_USER.put(Attributes.USERNAME, properties.getProperty("kustvakt.init.user.username"));
@@ -160,13 +187,40 @@
         return properties;
     }
 
-
+    public void setFoundriesAndLayers(String config) throws IOException {
+    	foundries = new ArrayList<String>();
+    	layers = new ArrayList<String>();
+    	
+    	BufferedReader br;
+		File f = new File(config);
+		br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
+		String policy = null;
+		String[] policyData = null;
+		String type, layer;
+			while ((policy = br.readLine()) != null) {
+				if (policy.startsWith("#") || policy.isEmpty()){
+					continue;
+				}
+				policyData = policy.split("\t");
+				type = policyData[0];
+				if (type.equals("foundry")){
+					foundries.add(policyData[1]);
+				}
+				else if (type.equals("layer")){
+					layer = policyData[1].split("/")[1];
+					layers.add(layer);
+				}
+			}
+	}
+    
+    
     /**
      * set properties
      * 
      * @param props
+     * @throws IOException 
      */
-    public void setProperties (Properties props) throws MalformedURLException {
+    public void setProperties (Properties props) throws IOException {
         this.load(props);
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java b/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
index fc8322c..41c89ff 100644
--- a/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
+++ b/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
@@ -5,6 +5,8 @@
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.lucene.store.MMapDirectory;
 import org.slf4j.Logger;
@@ -13,6 +15,8 @@
 import de.ids_mannheim.korap.Krill;
 import de.ids_mannheim.korap.KrillCollection;
 import de.ids_mannheim.korap.KrillIndex;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.response.Match;
 import de.ids_mannheim.korap.response.Result;
 import de.ids_mannheim.korap.util.QueryException;
@@ -105,43 +109,66 @@
      * 
      * @param id
      *            match id
+     * @param availabilityList 
+     * @throws KustvaktException 
      */
-    public String getMatch (String id) {
+    public String getMatch (String id, Pattern licensePattern) {
+    	Match km;
         if (this.index != null) {
             try {
-                return this.index.getMatch(id).toJsonString();
+            	km = this.index.getMatch(id);
+            	String availability = km.getAvailability();
+            	if (availability != null){
+            		Matcher m = licensePattern.matcher(availability);
+            		if (!m.matches()){
+            			km.addError(StatusCodes.ACCESS_DENIED, 
+            				"Retrieving match info with ID "+id+" is not allowed.");
+            		}
+            	}
             }
             catch (QueryException qe) {
-                Match km = new Match();
+                km = new Match();
                 km.addError(qe.getErrorCode(), qe.getMessage());
-                return km.toJsonString();
             }
-        };
-        Match km = new Match();
-        km.addError(601, "Unable to find index");
+        }
+        else{
+        	km = new Match();
+        	km.addError(601, "Unable to find index");
+        }
         return km.toJsonString();
     };
 
 
     public String getMatch (String id, List<String> foundries,
             List<String> layers, boolean includeSpans,
-            boolean includeHighlights, boolean sentenceExpansion) {
+            boolean includeHighlights, boolean sentenceExpansion, 
+            Pattern licensePattern) {
+    	 Match km;
         if (this.index != null) {
             try {
-
-                return this.index.getMatchInfo(id, "tokens", true, foundries,
+            	km = this.index.getMatchInfo(id, "tokens", true, foundries,
                         layers, includeSpans, includeHighlights,
-                        sentenceExpansion).toJsonString();
+                        sentenceExpansion);
+            	String availability = km.getAvailability();
+//            	String availability = "QAO-NC";
+            	if (availability != null){
+            		Matcher m = licensePattern.matcher(availability);
+            		if (!m.matches()){
+            			km.addError(StatusCodes.ACCESS_DENIED, 
+            					"Retrieving match info with ID "+id+" is not allowed.");
+            		}
+            	}
+            	
             }
             catch (QueryException qe) {
-                Match km = new Match();
+                km = new Match();
                 km.addError(qe.getErrorCode(), qe.getMessage());
-                return km.toJsonString();
             }
-        };
-
-        Match km = new Match();
-        km.addError(601, "Unable to find index");
+        }
+        else{
+        	km = new Match();
+        	km.addError(601, "Unable to find index");
+        }
         return km.toJsonString();
     };
 
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
index d32174e..c877b04 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
@@ -3,9 +3,11 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -53,6 +55,7 @@
 import de.ids_mannheim.korap.user.DemoUser;
 import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.User.CorpusAccess;
 import de.ids_mannheim.korap.user.User.UserFactory;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
@@ -1170,69 +1173,101 @@
 	        }
         }
         String results;
-        // fixme: checks for policy matching
-        // fixme: currently disabled, due to mishab in foundry/layer spec
-        // fixme:
-        if (foundries != null && foundries.size() > 1000) {
-            Set<String> f_list = new HashSet<>();
-            Set<String> l_list = new HashSet<>();
-
-            for (String spl : new ArrayList<>(foundries)) {
-                try {
-                    SecurityManager<?> manager = SecurityManager.init(spl, user,
-                            Permissions.Permission.READ);
-                    if (!manager.isAllowed())
-                        continue;
-
-                    String[] sep = StringUtils.splitAnnotations(spl);
-                    if (spl != null) {
-                        f_list.add(sep[0]);
-                        l_list.add(sep[1]);
-                    };
-                    results = searchKrill.getMatch(matchid,
-                            new ArrayList<>(f_list), new ArrayList<>(l_list),
-                            spans, false, true);
-                }
-                catch (NotAuthorizedException e) {
-                    throw KustvaktResponseHandler.throwit(
-                            StatusCodes.ACCESS_DENIED, "Permission denied",
-                            matchid);
-                }
-
-            }
-            // all foundries shall be returned
-        }
-        else if (foundries != null && foundries.contains("*")) {
-            Set<Layer> resources;
-            try {
-                resources = ResourceFinder.search(user, Layer.class);
-            }
-            catch (KustvaktException e) {
-                jlog.error("Exception encountered: {}", e.string());
-                throw KustvaktResponseHandler.throwit(e);
-            }
-            // returns foundries and layers.
-            // todo: needs testing!
-            foundries = new HashSet<>();
-            layers = new HashSet<>();
-            for (Layer r : resources) {
-                String[] spl = StringUtils.splitAnnotations(r.getName());
-                if (spl != null) {
-                    foundries.add(spl[0]);
-                    layers.add(spl[1]);
-                }
-            }
-        }
+//        // fixme: checks for policy matching
+//        // fixme: currently disabled, due to mishab in foundry/layer spec
+//        // fixme:
+//        if (foundries != null && foundries.size() > 1000) {
+//            Set<String> f_list = new HashSet<>();
+//            Set<String> l_list = new HashSet<>();
+//
+//            for (String spl : new ArrayList<>(foundries)) {
+//                try {
+//                    SecurityManager<?> manager = SecurityManager.init(spl, user,
+//                            Permissions.Permission.READ);
+//                    if (!manager.isAllowed())
+//                        continue;
+//
+//                    String[] sep = StringUtils.splitAnnotations(spl);
+//                    if (spl != null) {
+//                        f_list.add(sep[0]);
+//                        l_list.add(sep[1]);
+//                    };
+//                    results = searchKrill.getMatch(matchid,
+//                            new ArrayList<>(f_list), new ArrayList<>(l_list),
+//                            spans, false, true);
+//                }
+//                catch (NotAuthorizedException e) {
+//                    throw KustvaktResponseHandler.throwit(
+//                            StatusCodes.ACCESS_DENIED, "Permission denied",
+//                            matchid);
+//                }
+//
+//            }
+//            // all foundries shall be returned
+//        }
+//        else if (foundries != null && foundries.contains("*")) {
+//            Set<Layer> resources;
+//            try {
+//                resources = ResourceFinder.search(user, Layer.class);
+//            }
+//            catch (KustvaktException e) {
+//                jlog.error("Exception encountered: {}", e.string());
+//                throw KustvaktResponseHandler.throwit(e);
+//            }
+//            // returns foundries and layers.
+//            // todo: needs testing!
+//            foundries = new HashSet<>();
+//            layers = new HashSet<>();
+//            for (Layer r : resources) {
+//                String[] spl = StringUtils.splitAnnotations(r.getName());
+//                if (spl != null) {
+//                    foundries.add(spl[0]);
+//                    layers.add(spl[1]);
+//                }
+//            }
+//        }
+        
+        
+        //EM: CorpusAccess corpusAccess = tokenContext.getCorpusAccess();
+        CorpusAccess corpusAccess = CorpusAccess.FREE;
+        Pattern p;
+        switch (corpusAccess) {
+		case PUB:
+			p = config.getPublicLicensePattern();
+			break;
+		case ALL:
+			p = config.getAllLicensePattern();
+			break;
+		default: // FREE
+			p = config.getFreeLicensePattern();
+			break;
+		}
         try {
-            if (!match_only)
+            if (!match_only){
+            	
+            	ArrayList<String> foundryList = new ArrayList<String>();
+                ArrayList<String> layerList = new ArrayList<String>();
+                
+                // EM: now without user, just list all foundries and layers
+                if (foundries.contains("*")) {
+                	foundryList = config.getFoundries();
+                	layerList = config.getLayers();
+                }
+                else{
+                	foundryList.addAll(foundries);
+                	layerList.addAll(layers);
+                }
+                
                 results = searchKrill.getMatch(matchid,
-                        new ArrayList<>(foundries), new ArrayList<>(layers),
-                        spans, false, true);
-            else
-                results = searchKrill.getMatch(matchid);
+                        foundryList, layerList,
+                        spans, false, true, p);
+            }
+            else{
+                results = searchKrill.getMatch(matchid, p);
+            }
         }
         catch (Exception e) {
-            jlog.error("Exception encountered!", e);
+            jlog.error("Exception in the MatchInfo service encountered!", e);
             throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     e.getMessage(), "");
         }
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java b/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
index 5bb3fa6..946b342 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
@@ -304,7 +304,7 @@
             @PathParam("matchId") String matchId,
             @QueryParam("foundry") Set<String> foundries,
             @QueryParam("layer") Set<String> layers,
-            @QueryParam("spans") Boolean spans) {
+            @QueryParam("spans") Boolean spans) throws KustvaktException {
         String matchid = searchKrill.getMatchId(corpusId, docId, textId, matchId);
         List<String> f_list = null;
         List<String> l_list = null;
@@ -320,10 +320,10 @@
         boolean match_only = foundries == null || foundries.isEmpty();
         String results;
         if (match_only)
-            results = searchKrill.getMatch(matchid);
+            results = searchKrill.getMatch(matchid, config.getFreeLicensePattern());
         else
             results = searchKrill.getMatch(matchid, f_list, l_list, spans,
-                    false, true);
+                    false, true, config.getFreeLicensePattern());
 
         return Response.ok(results).build();
     }
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java b/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java
index 40fb0ad..867d8e6 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java
@@ -56,11 +56,11 @@
     }
 
 	@Test
-    public void testMatchInfo () {
+    public void testMatchInfo () throws KustvaktException {
         KustvaktConfiguration config = helper().getContext().getConfiguration();
         SearchKrill krill = new SearchKrill(config.getIndexDir());
         assertNotNull(krill);
-		String matchinfo = krill.getMatch("WPD/AAA.00002/p169-197");
+		String matchinfo = krill.getMatch("WPD/AAA.00002/p169-197", config.getFreeLicensePattern());
 		JsonNode node = JsonUtils.readTree(matchinfo);
 		assertEquals("Invalid match identifier", node.at("/errors/0/1").asText());
 	}
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoLegacyServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoLegacyServiceTest.java
index d5b85fc..f0527ab 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoLegacyServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoLegacyServiceTest.java
@@ -44,14 +44,13 @@
                 node.at("/subTitle").asText());
         assertEquals("Goethe, Johann Wolfgang von",
                 node.at("/author").asText());
-        assertTrue(node.at("/snippet").asText()
-                .startsWith("<span class=\"context-left\"></span>"
-                        + "<span class=\"match\"><span title=\"corenlp/p:ADV\">"
-                        + "<span title=\"opennlp/p:ADV\">"
-                        + "<span title=\"tt/l:fern\">"
-                        ));
+		assertTrue(node.at("/snippet").asText()
+				   .startsWith("<span class=\"context-left\"></span>"
+							   + "<span class=\"match\">"
+					   ));
     }
     
+    // EM: need reimplementation
     @Test
     public void testGetMatchOnlyUnauthorizeCorpus () {
         ClientResponse response = resource().path(getAPIVersion())
@@ -61,7 +60,7 @@
         assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
                 response.getStatus());
         String entity = response.getEntity(String.class);
-        System.out.println(entity);
+       // System.out.println(entity);
         JsonNode node = JsonUtils.readTree(entity);
         assertNotNull(node);
         assertEquals(101, node.at("/errors/0/0").asInt());
@@ -91,4 +90,4 @@
     public void initMethod () throws KustvaktException {
         helper().runBootInterfaces();
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
index 8ff5794..6706967 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
@@ -5,6 +5,7 @@
 import static org.junit.Assert.assertTrue;
 
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -49,12 +50,11 @@
                 node.at("/author").asText());
         assertTrue(node.at("/snippet").asText()
                 .startsWith("<span class=\"context-left\"></span>"
-                        + "<span class=\"match\"><span title=\"corenlp/p:ADV\">"
-                        + "<span title=\"opennlp/p:ADV\">"
-                        + "<span title=\"tt/l:fern\">"
-                        ));
+                        + "<span class=\"match\">"
+					));
     }
 
+    // EM: Cannot be tested yet
     @Test
     public void testGetMatchInfoWithAuthentication () {
         ClientResponse response = resource().path(getAPIVersion())
@@ -101,4 +101,4 @@
     public void initMethod () throws KustvaktException {
         helper().runBootInterfaces();
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
index 94e7a29..be69d6e 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
@@ -23,7 +23,6 @@
 import de.ids_mannheim.korap.resources.Corpus;
 import de.ids_mannheim.korap.security.ac.ResourceFinder;
 import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
-import de.ids_mannheim.korap.security.auth.KustvaktAuthenticationManager;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.service.FastJerseyTest;
@@ -152,7 +151,7 @@
         assertEquals("corpusSigle", node.at("/collection/key").asText());
         assertEquals("GOE", node.at("/collection/value").asText());
         assertNotEquals(0, node.path("matches").size());
-        assertEquals(32, node.at("/meta/totalResults").asInt());
+        assertEquals(33, node.at("/meta/totalResults").asInt());
     }
 
 
@@ -165,7 +164,6 @@
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
         String ent = response.getEntity(String.class);
-        System.out.println(ent);
         JsonNode node = JsonUtils.readTree(ent);
         assertNotNull(node);
         assertEquals("koral:docGroup", node.at("/collection/@type").asText());
@@ -245,7 +243,8 @@
         assertEquals("koral:doc", node.at("/collection/@type").asText());
         assertEquals("corpusSigle", node.at("/collection/key").asText());
         assertEquals("WPD15", node.at("/collection/value").asText());
-        assertNotEquals(0, node.path("matches").size());
+        // EM: sample index does not include this corpus
+//        assertNotEquals(0, node.path("matches").size());
     }
 
 
@@ -280,7 +279,7 @@
         assertEquals("koral:doc", node.at("/collection/@type").asText());
         assertEquals("corpusSigle", node.at("/collection/key").asText());
         assertEquals("WPD15", node.at("/collection/value").asText());
-        assertNotEquals(0, node.path("matches").size());
+//        assertNotEquals(0, node.path("matches").size());
     }
 
 
diff --git a/src/test/resources/sample-index/_0.cfe b/src/test/resources/sample-index/_0.cfe
index 8abc486..58273ca 100644
--- a/src/test/resources/sample-index/_0.cfe
+++ b/src/test/resources/sample-index/_0.cfe
Binary files differ
diff --git a/src/test/resources/sample-index/_0.cfs b/src/test/resources/sample-index/_0.cfs
index 63efeb7..afc777d 100644
--- a/src/test/resources/sample-index/_0.cfs
+++ b/src/test/resources/sample-index/_0.cfs
Binary files differ
diff --git a/src/test/resources/sample-index/_0.si b/src/test/resources/sample-index/_0.si
index fe1bebe..c06026b 100644
--- a/src/test/resources/sample-index/_0.si
+++ b/src/test/resources/sample-index/_0.si
Binary files differ
diff --git a/src/test/resources/sample-index/_1.cfe b/src/test/resources/sample-index/_1.cfe
index a515fac..4a1de26 100644
--- a/src/test/resources/sample-index/_1.cfe
+++ b/src/test/resources/sample-index/_1.cfe
Binary files differ
diff --git a/src/test/resources/sample-index/_1.cfs b/src/test/resources/sample-index/_1.cfs
index be27ceb..d782bc2 100644
--- a/src/test/resources/sample-index/_1.cfs
+++ b/src/test/resources/sample-index/_1.cfs
Binary files differ
diff --git a/src/test/resources/sample-index/_1.si b/src/test/resources/sample-index/_1.si
index 5764d53..b3ceb25 100644
--- a/src/test/resources/sample-index/_1.si
+++ b/src/test/resources/sample-index/_1.si
Binary files differ
diff --git a/src/test/resources/sample-index/_2.cfe b/src/test/resources/sample-index/_2.cfe
new file mode 100644
index 0000000..9727b2d
--- /dev/null
+++ b/src/test/resources/sample-index/_2.cfe
Binary files differ
diff --git a/src/test/resources/sample-index/_2.cfs b/src/test/resources/sample-index/_2.cfs
new file mode 100644
index 0000000..4efac7e
--- /dev/null
+++ b/src/test/resources/sample-index/_2.cfs
Binary files differ
diff --git a/src/test/resources/sample-index/_2.si b/src/test/resources/sample-index/_2.si
new file mode 100644
index 0000000..f9de6cf
--- /dev/null
+++ b/src/test/resources/sample-index/_2.si
Binary files differ
diff --git a/src/test/resources/sample-index/_3.cfe b/src/test/resources/sample-index/_3.cfe
new file mode 100644
index 0000000..0627196
--- /dev/null
+++ b/src/test/resources/sample-index/_3.cfe
Binary files differ
diff --git a/src/test/resources/sample-index/_3.cfs b/src/test/resources/sample-index/_3.cfs
new file mode 100644
index 0000000..553221a
--- /dev/null
+++ b/src/test/resources/sample-index/_3.cfs
Binary files differ
diff --git a/src/test/resources/sample-index/_3.si b/src/test/resources/sample-index/_3.si
new file mode 100644
index 0000000..5bfd786
--- /dev/null
+++ b/src/test/resources/sample-index/_3.si
Binary files differ
diff --git a/src/test/resources/sample-index/segments_1 b/src/test/resources/sample-index/segments_1
index b1944d5..6549b6b 100644
--- a/src/test/resources/sample-index/segments_1
+++ b/src/test/resources/sample-index/segments_1
Binary files differ