Changed handling errors from Kustvakt and added FCSConstants.

Change-Id: I8c04ddaff0c967b704c0af90dbb63686204b90b5
diff --git a/src/main/java/de/mannheim/ids/korap/sru/FCSConstants.java b/src/main/java/de/mannheim/ids/korap/sru/FCSConstants.java
new file mode 100644
index 0000000..d532e3f
--- /dev/null
+++ b/src/main/java/de/mannheim/ids/korap/sru/FCSConstants.java
@@ -0,0 +1,23 @@
+package de.mannheim.ids.korap.sru;
+
+public class FCSConstants {
+
+    private static final String FCS_DIAGNOSTIC_URI_PREFIX = "http://clarin.eu/fcs/diagnostic/";
+
+    public static final String FCS_PERSISTENT_IDENTIFIER_INVALID = 
+            FCS_DIAGNOSTIC_URI_PREFIX + 1;
+    public static final String FCS_RESOURCE_SET_TOO_LARGE_QUERY_CONTEXT_AUTOMATICALLY_ADJUSTED = 
+            FCS_DIAGNOSTIC_URI_PREFIX + 2;
+    public static final String FCS_RESOURCE_SET_TOO_LARGE_CANNOT_PERFORM_QUERY = 
+            FCS_DIAGNOSTIC_URI_PREFIX + 3;
+    public static final String FCS_REQUESTED_DATAVIEW_INVALID = 
+            FCS_DIAGNOSTIC_URI_PREFIX + 4;
+    public static final String FCS_GENERAL_QUERY_SYNTAX_ERROR = 
+            FCS_DIAGNOSTIC_URI_PREFIX + 10;
+    public static final String FCS_QUERY_TOO_COMPLEX =
+            FCS_DIAGNOSTIC_URI_PREFIX + 11;
+    public static final String FCS_QUERY_REWRITTEN = 
+            FCS_DIAGNOSTIC_URI_PREFIX + 12;
+    public static final String FCS_GENERAL_PROCESSING_HINT = 
+            FCS_DIAGNOSTIC_URI_PREFIX + 14;
+}
diff --git a/src/main/java/de/mannheim/ids/korap/sru/KorapClient.java b/src/main/java/de/mannheim/ids/korap/sru/KorapClient.java
index 69c3c0a..be3ffb9 100644
--- a/src/main/java/de/mannheim/ids/korap/sru/KorapClient.java
+++ b/src/main/java/de/mannheim/ids/korap/sru/KorapClient.java
@@ -28,7 +28,8 @@
 
 public class KorapClient {
 
-    private static final String SERVICE_URI = "http://10.0.10.13:7070/api/v0.1/";
+    private static final String SERVICE_URI = "http://localhost:8089/api/v0.1/"; 
+            //"http://10.0.10.13:7070/api/v0.1/";
     private String CONTEXT_TYPE = "sentence";
 
     private int defaultNumOfRecords = 10;
@@ -130,12 +131,7 @@
             int statusCode = response.getStatusLine().getStatusCode();
             if (statusCode != HttpStatus.SC_OK) {
                 logger.warn("Error response code: " + statusCode);
-                logger.warn("Error message: "
-                        + response.getStatusLine().getReasonPhrase());
-                String[] errorMsg = parseError(response);
-                logger.warn(errorMsg[0] + "#" + errorMsg[1]);
-                throw new HttpResponseException(Integer.parseInt(errorMsg[0]),
-                        errorMsg[1]);
+                parseError(response);
             }
             
             BufferedInputStream jsonStream = new BufferedInputStream(response
@@ -157,8 +153,12 @@
         return result;
     }
 
-    private static String[] parseError(CloseableHttpResponse response)
+    private static void parseError(CloseableHttpResponse response)
             throws IOException {
+        
+        logger.warn("Error message: "
+                + response.getStatusLine().getReasonPhrase());
+        
         InputStream is = response.getEntity().getContent();
         JsonNode node = objectMapper.readTree(is);
         String message = node.get("error").textValue();
@@ -175,8 +175,9 @@
         else {
             errorItems = new String[] { "1", message };
         }
-
-        return errorItems;
+        
+        throw new HttpResponseException(Integer.parseInt(errorItems[0]),
+                errorItems[1]);
     }
 
     private HttpGet createSearchRequest(String query,
@@ -228,7 +229,7 @@
     public static String retrieveAnnotations(KorapMatch match) throws IOException {
         HttpUriRequest httpRequest;
         try {
-            httpRequest = createMatchInfoRequest(match.getCorpusID(), match.getDocID(), match.getPositionID(), "*");
+            httpRequest = createMatchInfoRequest(match.getCorpusId(), match.getDocId(), match.getPositionId(), "*");
         }
         catch (URISyntaxException e) {
             throw new IOException("Failed creating http request for retrieving annotations.");
@@ -244,12 +245,7 @@
             int statusCode = response.getStatusLine().getStatusCode();
             if (statusCode != HttpStatus.SC_OK) {
                 logger.warn("Error response code: " + statusCode);
-                logger.warn("Error message: "
-                        + response.getStatusLine().getReasonPhrase());
-                String[] errorMsg = parseError(response);
-                logger.warn(errorMsg[0] + "#" + errorMsg[1]);
-                throw new HttpResponseException(Integer.parseInt(errorMsg[0]),
-                        errorMsg[1]);
+                parseError(response);
             }
 
             BufferedInputStream jsonStream = new BufferedInputStream(response
@@ -274,6 +270,8 @@
     private static HttpGet createMatchInfoRequest(String resourceId,
             String documentId, String matchId, String foundry) throws URISyntaxException {
         StringBuilder sb = new StringBuilder();
+        sb.append(SERVICE_URI);
+//        sb.append("http://localhost:8089/api/v0.1/");
         sb.append("corpus/");
         sb.append(resourceId);
         sb.append("/");
@@ -284,11 +282,10 @@
         sb.append(foundry);
         sb.append("&spans=false");
 
-        URIBuilder builder = new URIBuilder(SERVICE_URI + sb.toString());
+        URIBuilder builder = new URIBuilder(sb.toString());
         URI uri = builder.build();
-        logger.info("Query URI: " + uri.toString());
+        logger.info("MatchInfo URI: " + uri.toString());
         HttpGet request = new HttpGet(uri);
         return request;
-
     }
 }
diff --git a/src/main/java/de/mannheim/ids/korap/sru/KorapResult.java b/src/main/java/de/mannheim/ids/korap/sru/KorapResult.java
index ea73fb3..73b5a3b 100644
--- a/src/main/java/de/mannheim/ids/korap/sru/KorapResult.java
+++ b/src/main/java/de/mannheim/ids/korap/sru/KorapResult.java
@@ -9,20 +9,32 @@
 public class KorapResult {
 	private int totalResults;
 	private List<KorapMatch> matches;
+	private List<List<Object>> errors;
 	
 	public KorapResult() {
 		matches = new ArrayList<KorapMatch>();
 	}
-	
-	public int getTotalResults() {
+			
+	public List<List<Object>> getErrors() {
+        return errors;
+    }
+
+    public void setErrors(List<List<Object>> errors) {
+        this.errors = errors;
+    }
+
+    public int getTotalResults() {
 		return totalResults;
 	}
-	public List<KorapMatch> getMatches() {
-		return matches;
-	}
+	
 	public void setTotalResults(int totalResults) {
 		this.totalResults = totalResults;
 	}
+	
+	public List<KorapMatch> getMatches() {
+        return matches;
+    }
+	
 	public void setMatches(List<KorapMatch> matches) {
 		this.matches = matches;
 	}
@@ -37,4 +49,6 @@
 	public int getMatchSize(){
 		return matches.size();
 	}
+	
+	
 }
diff --git a/src/main/java/de/mannheim/ids/korap/sru/KorapSRU.java b/src/main/java/de/mannheim/ids/korap/sru/KorapSRU.java
index 4982161..871c3d2 100644
--- a/src/main/java/de/mannheim/ids/korap/sru/KorapSRU.java
+++ b/src/main/java/de/mannheim/ids/korap/sru/KorapSRU.java
@@ -28,190 +28,259 @@
  * */
 public class KorapSRU extends SimpleEndpointSearchEngineBase {
 
-	public static final String CLARIN_FCS_RECORD_SCHEMA = "http://clarin.eu/fcs/resource";
-	public static final String KORAP_WEB_URL = "http://korap.ids-mannheim.de/kalamar";
+    public static final String CLARIN_FCS_RECORD_SCHEMA = "http://clarin.eu/fcs/resource";
+    public static final String KORAP_WEB_URL = "http://korap.ids-mannheim.de/kalamar";
 
-	public static String redirectBaseURI;
-	public static KorapClient korapClient;
-	private KorapEndpointDescription korapEndpointDescription;
-	private SRUServerConfig serverConfig;
+    public static String redirectBaseURI;
+    public static KorapClient korapClient;
+    private KorapEndpointDescription korapEndpointDescription;
+    private SRUServerConfig serverConfig;
 
-	private Logger logger = (Logger) LoggerFactory.getLogger(KorapSRU.class);
+    private Logger logger = (Logger) LoggerFactory.getLogger(KorapSRU.class);
 
-	@Override
-	protected EndpointDescription createEndpointDescription(
-			ServletContext context, SRUServerConfig config,
-			Map<String, String> params) throws SRUConfigException {
-		korapEndpointDescription = new KorapEndpointDescription(context);
-		return korapEndpointDescription;
-	}
+    @Override
+    protected EndpointDescription createEndpointDescription(
+            ServletContext context, SRUServerConfig config,
+            Map<String, String> params) throws SRUConfigException {
+        korapEndpointDescription = new KorapEndpointDescription(context);
+        return korapEndpointDescription;
+    }
 
-	@Override
-	protected void doInit(ServletContext context, SRUServerConfig config,
-			SRUQueryParserRegistry.Builder parserRegistryBuilder,
-			Map<String, String> params) throws SRUConfigException {
-		serverConfig = config;
-		korapClient = new KorapClient(config.getNumberOfRecords(),
-				config.getMaximumRecords());
+    @Override
+    protected void doInit(ServletContext context, SRUServerConfig config,
+            SRUQueryParserRegistry.Builder parserRegistryBuilder,
+            Map<String, String> params) throws SRUConfigException {
+        serverConfig = config;
+        korapClient = new KorapClient(config.getNumberOfRecords(),
+                config.getMaximumRecords());
 
-		StringBuilder sb = new StringBuilder();
-		sb.append(config.getTransports());
-		sb.append("://");
-		sb.append(config.getHost());
-		if (config.getPort() != 80) {
-			sb.append(":").append(config.getPort());
-		}
-		sb.append("/").append(config.getDatabase());
-		sb.append("/").append("redirect/");
-		this.redirectBaseURI = sb.toString();
+        StringBuilder sb = new StringBuilder();
+        sb.append(config.getTransports());
+        sb.append("://");
+        sb.append(config.getHost());
+        if (config.getPort() != 80) {
+            sb.append(":").append(config.getPort());
+        }
+        sb.append("/").append(config.getDatabase());
+        sb.append("/").append("redirect/");
+        this.redirectBaseURI = sb.toString();
+    }
 
-		// queryParser = new ThreadLocal<QueryParser>() {
-		// @Override
-		// protected QueryParser initialValue() {
-		// return new QueryParser("text", new StandardAnalyzer(
-		// CharArraySet.EMPTY_SET));
-		// }
-		// };
-	}
+    @Override
+    public SRUSearchResultSet search(SRUServerConfig config,
+            SRURequest request, SRUDiagnosticList diagnostics)
+            throws SRUException {
 
-	@Override
-	public SRUSearchResultSet search(SRUServerConfig config,
-			SRURequest request, SRUDiagnosticList diagnostics)
-			throws SRUException {
+        checkRequestRecordSchema(request);
 
-		checkRequestRecordSchema(request);
-
-		List<String> dataviews = korapEndpointDescription.getDefaultDataViews();
-		if (request.getExtraRequestDataNames().contains("x-fcs-dataviews")) {
-		    String extraDataview =  getRequestDataView(
+        List<String> dataviews = korapEndpointDescription.getDefaultDataViews();
+        if (request.getExtraRequestDataNames().contains("x-fcs-dataviews")) {
+            String extraDataview = getRequestDataView(
                     request.getExtraRequestData("x-fcs-dataviews"), diagnostics);
-		    if (extraDataview!=null)
-			dataviews.add(extraDataview);
-		}
+            if (extraDataview != null) dataviews.add(extraDataview);
+        }
 
-		String queryType = request.getQueryType();
-		logger.info("Query language: " + queryType);
-		QueryLanguage queryLanguage;
-		if (request.isQueryType(Constants.FCS_QUERY_TYPE_CQL)) {
-			queryLanguage = QueryLanguage.CQL;
-		} else if (request.isQueryType(Constants.FCS_QUERY_TYPE_FCS)) {
-			queryLanguage = QueryLanguage.FCSQL;
-		} else {
-			throw new SRUException(
-					SRUConstants.SRU_CANNOT_PROCESS_QUERY_REASON_UNKNOWN,
-					"Queries with queryType '"
-							+ request.getQueryType()
-							+ "' are not supported by this CLARIN-FCS Endpoint.");
-		}
-		logger.info("Query language: " + queryLanguage);
+        boolean isRewitesAllowed = false;
+        if (request.getExtraRequestDataNames().contains("x-fcs-rewrites-allowed")) {
+             isRewitesAllowed = getRequestDataView(
+                    request.getExtraRequestData("x-fcs-rewrites-allowed"), diagnostics).
+                    equals("true");
+        }
+        
+        String queryType = request.getQueryType();
+        logger.info("Query language: " + queryType);
+        QueryLanguage queryLanguage;
+        if (request.isQueryType(Constants.FCS_QUERY_TYPE_CQL)) {
+            queryLanguage = QueryLanguage.CQL;
+        }
+        else if (request.isQueryType(Constants.FCS_QUERY_TYPE_FCS)) {
+            queryLanguage = QueryLanguage.FCSQL;
+        }
+        else {
+            throw new SRUException(
+                    SRUConstants.SRU_CANNOT_PROCESS_QUERY_REASON_UNKNOWN,
+                    "Queries with queryType '"
+                            + request.getQueryType()
+                            + "' are not supported by this CLARIN-FCS Endpoint.");
+        }
 
-		String queryStr = null;
-		queryStr = request.getQuery().getRawQuery();
-		if ((queryStr == null) || queryStr.isEmpty()) {
-			throw new SRUException(SRUConstants.SRU_EMPTY_TERM_UNSUPPORTED,
-					"An empty term is not supported.");
-		}
-		logger.info("korapsru query: " + queryStr);
+        String queryStr = null;
+        queryStr = request.getQuery().getRawQuery();
+        if ((queryStr == null) || queryStr.isEmpty()) {
+            throw new SRUException(SRUConstants.SRU_EMPTY_TERM_UNSUPPORTED,
+                    "An empty term is not supported.");
+        }
+        logger.info("korapsru query: " + queryStr);
 
-		String version = null;
-		switch (request.getVersion()) {
-			case VERSION_1_1 :
-				version = "1.1";
-			case VERSION_1_2 :
-				version = "1.2";
-			case VERSION_2_0 :
-				version = "2.0";
-			default :
-				serverConfig.getDefaultVersion();
-		}
+        String version = null;
+        switch (request.getVersion()) {
+            case VERSION_1_1:
+                version = "1.1";
+            case VERSION_1_2:
+                version = "1.2";
+            case VERSION_2_0:
+                version = "2.0";
+            default:
+                serverConfig.getDefaultVersion();
+        }
 
-		KorapResult korapResult = new KorapResult();
-		try {
-			korapResult = korapClient.query(queryStr, queryLanguage, version,
-					request.getStartRecord(), request.getMaximumRecords(),
-					getCorporaList(request));
-		} catch (HttpResponseException e) {
-			logger.warn("HttpResponseException: " + e.getStatusCode() + " "
-					+ e.getMessage());
-			switch (e.getStatusCode()) {
-				case 16 :
-					throw new SRUException(SRUConstants.SRU_UNSUPPORTED_INDEX,
-							e.getMessage());
-				case 19 :
-					throw new SRUException(
-							SRUConstants.SRU_UNSUPPORTED_RELATION,
-							e.getMessage());
-				case 20 :
-					throw new SRUException(
-							SRUConstants.SRU_UNSUPPORTED_RELATION_MODIFIER,
-							e.getMessage());
-				case 27 :
-					throw new SRUException(
-							SRUConstants.SRU_EMPTY_TERM_UNSUPPORTED,
-							e.getMessage());
-				case 48 :
-					throw new SRUException(
-							SRUConstants.SRU_QUERY_FEATURE_UNSUPPORTED,
-							e.getMessage());
-				default :
-					throw new SRUException(
-							SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
-							e.getMessage());
-			}
+        KorapResult korapResult = new KorapResult();
+        try {
+            korapResult = korapClient.query(queryStr, queryLanguage, version,
+                    request.getStartRecord(), request.getMaximumRecords(),
+                    getCorporaList(request));
+        }
+        catch (HttpResponseException e) {
+            logger.warn("HttpResponseException: " + e.getStatusCode() + " "
+                    + e.getMessage());
+            switch (e.getStatusCode()) {
+                case 16:
+                    throw new SRUException(SRUConstants.SRU_UNSUPPORTED_INDEX,
+                            e.getMessage());
+                case 19:
+                    throw new SRUException(
+                            SRUConstants.SRU_UNSUPPORTED_RELATION,
+                            e.getMessage());
+                case 20:
+                    throw new SRUException(
+                            SRUConstants.SRU_UNSUPPORTED_RELATION_MODIFIER,
+                            e.getMessage());
+                case 27:
+                    throw new SRUException(
+                            SRUConstants.SRU_EMPTY_TERM_UNSUPPORTED,
+                            e.getMessage());
+                case 48:
+                    throw new SRUException(
+                            SRUConstants.SRU_QUERY_FEATURE_UNSUPPORTED,
+                            e.getMessage());
+                default:
+                    throw new SRUException(
+                            SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
+                            e.getMessage());
+            }
 
-		} catch (IOException e) {
-			throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
-					e.getMessage());
-		}
+        }
+        catch (IOException e) {
+            throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
+                    e.getMessage());
+        }
 
-		return new KorapSRUSearchResultSet(diagnostics, korapResult, dataviews,
-		        korapEndpointDescription);
-	}
+        if (korapResult.getErrors() != null) {
+            for (List<Object> error : korapResult.getErrors()) {
+                int errorCode = (int) error.get(0);
 
-	private String[] getCorporaList(SRURequest request) {
-		try {
-			String corpusPids = request.getExtraRequestData("x-fcs-context");
-			if (!corpusPids.isEmpty() && corpusPids != null) {
-				if (corpusPids.contains(",")) {
-					return corpusPids.split(",");
-				}
-				return new String[]{corpusPids};
-			}
-			return null;
-		} catch (NullPointerException e) {
-			return null;
-		}
-	}
+                switch (errorCode) {
+                    case 301:
+                        throw new SRUException(
+                                SRUConstants.SRU_EMPTY_TERM_UNSUPPORTED,
+                                (String) error.get(1));
+                    case 302:
+                        if (queryLanguage == QueryLanguage.FCSQL) {
+                            throw new SRUException(
+                                    FCSConstants.FCS_GENERAL_QUERY_SYNTAX_ERROR,
+                                    (String) error.get(1));
+                        }
+                        else {
+                            throw new SRUException(
+                                    SRUConstants.SRU_QUERY_SYNTAX_ERROR,
+                                    (String) error.get(1));
+                        }
+                    case 306:
+                        throw new SRUException(
+                                SRUConstants.SRU_QUERY_FEATURE_UNSUPPORTED,
+                                (String) error.get(1));
+                    case 307:
+                        throw new SRUException(
+                                SRUConstants.SRU_UNSUPPORTED_PARAMETER_VALUE,
+                                (String) error.get(1));
+                    case 309:
+                        throw new SRUException(
+                                SRUConstants.SRU_MANDATORY_PARAMETER_NOT_SUPPLIED,
+                                (String) error.get(1));
+                    case 310:
+                        throw new SRUException(
+                                SRUConstants.SRU_UNSUPPORTED_VERSION,
+                                (String) error.get(1));
+                    case 311:
+                        throw new SRUException(
+                                FCSConstants.FCS_QUERY_TOO_COMPLEX,
+                                (String) error.get(1));
+                    case 399:
+                        if (queryLanguage == QueryLanguage.FCSQL) {
+                            throw new SRUException(
+                                    FCSConstants.FCS_GENERAL_QUERY_SYNTAX_ERROR,
+                                    (String) error.get(1));
+                        }
+                        else {
+                            throw new SRUException(
+                                    SRUConstants.SRU_QUERY_SYNTAX_ERROR,
+                                    (String) error.get(1));
+                        }
+                    case 781:
+                        if (isRewitesAllowed){
+                            diagnostics.addDiagnostic(FCSConstants.FCS_QUERY_REWRITTEN,"",(String) error.get(1));
+                        }
+                        else {
+                            throw new SRUException(
+                                    SRUConstants.SRU_RESULT_SET_NOT_CREATED_TOO_MANY_MATCHING_RECORDS);
+                        }
+                    default:
+                        break;
+                }
 
-	private void checkRequestRecordSchema(SRURequest request)
-			throws SRUException {
-		final String recordSchemaIdentifier = request
-				.getRecordSchemaIdentifier();
-		if ((recordSchemaIdentifier != null)
-				&& !recordSchemaIdentifier.equals(CLARIN_FCS_RECORD_SCHEMA)) {
-			throw new SRUException(
-					SRUConstants.SRU_UNKNOWN_SCHEMA_FOR_RETRIEVAL,
-					recordSchemaIdentifier, "Record schema \""
-							+ recordSchemaIdentifier
-							+ "\" is not supported by this endpoint.");
-		}
-	}
+            }
+        }
 
-	private String getRequestDataView(String requestDataview,
-			SRUDiagnosticList diagnostics) {
-		if (requestDataview != null & !requestDataview.isEmpty()) {
-			for (DataView dv : korapEndpointDescription.getSupportedDataViews()) {
-				if (dv.getIdentifier().equals(requestDataview)) {
-					return requestDataview;
-				}
-			}
-			diagnostics.addDiagnostic(
-					Constants.FCS_DIAGNOSTIC_REQUESTED_DATA_VIEW_INVALID,
-					"The requested Data View " + requestDataview
-							+ " is not supported.", "Using the default Data View(s): "
-							+ korapEndpointDescription.getDefaultDataViews()
-							+ " .");
-		}
-		return null;
-	}
+        return new KorapSRUSearchResultSet(diagnostics, korapResult, dataviews,
+                korapEndpointDescription);
+    }
+
+    private String[] getCorporaList(SRURequest request) {
+        try {
+            String corpusPids = request.getExtraRequestData("x-fcs-context");
+            if (!corpusPids.isEmpty() && corpusPids != null) {
+                if (corpusPids.contains(",")) {
+                    return corpusPids.split(",");
+                }
+                return new String[] { corpusPids };
+            }
+            return null;
+        }
+        catch (NullPointerException e) {
+            return null;
+        }
+    }
+
+    private void checkRequestRecordSchema(SRURequest request)
+            throws SRUException {
+        final String recordSchemaIdentifier = request
+                .getRecordSchemaIdentifier();
+        if ((recordSchemaIdentifier != null)
+                && !recordSchemaIdentifier.equals(CLARIN_FCS_RECORD_SCHEMA)) {
+            throw new SRUException(
+                    SRUConstants.SRU_UNKNOWN_SCHEMA_FOR_RETRIEVAL,
+                    recordSchemaIdentifier, "Record schema \""
+                            + recordSchemaIdentifier
+                            + "\" is not supported by this endpoint.");
+        }
+    }
+
+    private String getRequestDataView(String requestDataview,
+            SRUDiagnosticList diagnostics) {
+        if (requestDataview != null & !requestDataview.isEmpty()) {
+            for (DataView dv : korapEndpointDescription.getSupportedDataViews()) {
+                if (dv.getIdentifier().equals(requestDataview)) {
+                    return requestDataview;
+                }
+            }
+            diagnostics.addDiagnostic(
+                    Constants.FCS_DIAGNOSTIC_REQUESTED_DATA_VIEW_INVALID,
+                    "The requested Data View " + requestDataview
+                            + " is not supported.",
+                    "Using the default Data View(s): "
+                            + korapEndpointDescription.getDefaultDataViews()
+                            + " .");
+        }
+        return null;
+    }
 }
diff --git a/src/main/java/de/mannheim/ids/korap/sru/KorapSRUSearchResultSet.java b/src/main/java/de/mannheim/ids/korap/sru/KorapSRUSearchResultSet.java
index 16b3a1b..a260584 100644
--- a/src/main/java/de/mannheim/ids/korap/sru/KorapSRUSearchResultSet.java
+++ b/src/main/java/de/mannheim/ids/korap/sru/KorapSRUSearchResultSet.java
@@ -36,7 +36,7 @@
     private List<String> dataviews;
     private KorapEndpointDescription endpointDescription;
     private SAXParser saxParser;
-    
+
     Layer textLayer;
 
     public KorapSRUSearchResultSet (SRUDiagnosticList diagnostics,
@@ -50,7 +50,7 @@
             saxParser = saxParserFactory.newSAXParser();
         }
         catch (ParserConfigurationException | SAXException e) {
-            throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,e);
+            throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR, e);
         }
 
         this.korapResult = korapResult;
@@ -82,25 +82,21 @@
 
     @Override
     public String getRecordIdentifier() {
-        return korapResult.getMatch(i).getID();
+        return korapResult.getMatch(i).getMatchId();
     }
 
     @Override
     public void writeRecord(XMLStreamWriter writer) throws XMLStreamException {
         KorapMatch match;
         match = parseMatch();
-        match.setPositionID();
+        match.parseMatchId();
 
-        XMLStreamWriterHelper.writeStartResource(writer, match.getID(), null);
+        XMLStreamWriterHelper.writeStartResource(writer, match.getMatchId(),
+                null);
         XMLStreamWriterHelper.writeStartResourceFragment(writer, null, null);
 
         List<AnnotationLayer> annotationLayers;
-        try {
-            annotationLayers = parseAnnotations(match);
-        }
-        catch (SRUException e) {
-            throw new XMLStreamException(e);
-        }
+        annotationLayers = parseAnnotations(match);
 
         writeAdvancedDataView(writer, annotationLayers);
 
@@ -122,34 +118,23 @@
     }
 
     private List<AnnotationLayer> parseAnnotations(KorapMatch match)
-            throws SRUException {
-        String annotationSnippet;
-        AnnotationHandler annotationHandler = new AnnotationHandler(endpointDescription.getAnnotationLayers());
-        InputStream is;
-
+            throws XMLStreamException {
+        AnnotationHandler annotationHandler = new AnnotationHandler(
+                endpointDescription.getAnnotationLayers());
         try {
-            annotationSnippet = KorapClient.retrieveAnnotations(match);
-        }
-        catch (IOException e) {
-            throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
-                    e);
-        }
-
-        is = new ByteArrayInputStream(annotationSnippet.getBytes());
-        
-        try {
+            String annotationSnippet = KorapClient.retrieveAnnotations(match);
+            InputStream is = new ByteArrayInputStream(annotationSnippet.getBytes());
             saxParser.parse(is, annotationHandler);
         }
         catch (SAXException | IOException e) {
-            throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR, e);
+            throw new XMLStreamException(e);
         }
-        
+
         return annotationHandler.getAnnotationLayers();
     }
 
     private void writeAdvancedDataView(XMLStreamWriter writer,
-            List<AnnotationLayer> annotationLayers)
-            throws XMLStreamException {
+            List<AnnotationLayer> annotationLayers) throws XMLStreamException {
 
         AdvancedDataViewWriter helper = new AdvancedDataViewWriter(
                 AdvancedDataViewWriter.Unit.ITEM);
@@ -161,18 +146,13 @@
         if (dataviews.contains("adv")) {
             helper.writeAdvancedDataView(writer);
         }
-
     }
-    
+
     private void addAnnotationsToWriter(AdvancedDataViewWriter helper,
             List<AnnotationLayer> annotationLayers) {
-        
-        boolean isKeywordAktive = false; 
-        String keyword = "";
-        long start=0,end=0; 
-        
-        Map<Integer,List<Annotation>> map;
-        for (AnnotationLayer annotationLayer : annotationLayers) {        
+
+        Map<Integer, List<Annotation>> map;
+        for (AnnotationLayer annotationLayer : annotationLayers) {
             map = annotationLayer.getAnnotationMap();
             Set<Integer> keyset = map.keySet();
             Integer[] keyArray = keyset.toArray(new Integer[keyset.size()]);
@@ -185,33 +165,27 @@
 
                 // FCS advanced dataview does not allow multiple
                 // annotations on the same segment.
-                // for (Annotation annotation : annotations){                
+                // for (Annotation annotation : annotations){
                 Annotation annotation = annotations.get(0);
-                
-                if (annotation.isKeyword()) {
-                    if (!isKeywordAktive){ 
-                        isKeywordAktive = true;
-                        start = annotation.getStart();                        
-                    }
-                    end = annotation.getEnd();
-                    keyword += annotation.getValue();
-//                    helper.addSpan(annotationLayer.getLayerId(),
-//                            annotation.getStart(), annotation.getEnd(),
-//                            annotation.getValue(), 1);
+
+                // if
+                // (annotationLayer.getLayerCode().equals(AnnotationLayer.TYPE.TEXT.toString())){
+                // logger.info(annotation.getStart()+" "+
+                // annotation.getEnd()+" "+
+                // annotation.getValue());
+                // }
+                if (annotation.getHitLevel()>0) {
+                    helper.addSpan(annotationLayer.getLayerId(),
+                            annotation.getStart(), annotation.getEnd(),
+                            annotation.getValue(), annotation.getHitLevel());
                 }
                 else {
-                    if (isKeywordAktive && annotationLayer.getLayerCode().equals(AnnotationLayer.TYPE.TEXT.toString())){
-                        helper.addSpan(annotationLayer.getLayerId(),
-                              start, end,
-                              keyword, 1);
-                        isKeywordAktive = false;
-                    }
                     helper.addSpan(annotationLayer.getLayerId(),
                             annotation.getStart(), annotation.getEnd(),
                             annotation.getValue());
                 }
-                // }
             }
+            map.clear();
         }
     }
 }