Do not serialize duplicated keys for fields

Change-Id: I12d9e52a368ef39f446a09436ee3dbb44e7f1404
diff --git a/Changes b/Changes
index f13c931..dd7573d 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,8 @@
-0.58.5 2019-02-06
+0.58.5 2019-02-07
+    - [bugfix] Fix bug where duplicate keys occured in
+      field data output (diewald)
+    - [bugfix] Fix bug where fields already set where lifted
+      again, but ignored in the fields order list (diewald)
 
 0.58.4 2019-02-05
     - [cleanup] Remove deprecated methods setLicense/getLicense,
diff --git a/src/main/java/de/ids_mannheim/korap/KrillMeta.java b/src/main/java/de/ids_mannheim/korap/KrillMeta.java
index a3db457..6d715e5 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillMeta.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillMeta.java
@@ -40,7 +40,8 @@
         fields = new ArrayList<String>(16);
 
         // Lift following fields per default
-        // These fields are chosen for <legacy /> reasons
+        // These fields are chosen for
+        // <legacy /> reasons
         for (String field : new String[] {
 				"ID",
 				"UID",
diff --git a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
index 413b1d0..7ee4751 100644
--- a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
+++ b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
@@ -38,6 +38,7 @@
  */
 @JsonInclude(Include.NON_EMPTY)
 // @JsonIgnoreProperties(ignoreUnknown = true)
+
 public abstract class AbstractDocument extends Response {
     ObjectMapper mapper = new ObjectMapper();
     
@@ -155,20 +156,13 @@
 
 
     public void populateFields (Document doc, List<String> fields) {
-        // Remove all fields already set
         Iterator<String> fieldsIter = fields.iterator();
-        while (fieldsIter.hasNext()) {
-            if (mFields.contains(fieldsIter.next())) {
-                fieldsIter.remove();
-            };
-        };
-
         
         if (fields.contains("UID")) {
             this.setUID(doc.get("UID"));
         };
         
-        fieldsIter = fields.iterator();
+        // fieldsIter = fields.iterator();
         mFields.fieldsOrder = new ArrayList<>(16);
 
         while (fieldsIter.hasNext()) {
@@ -180,6 +174,11 @@
 
             mFields.fieldsOrder.add(name);
 
+            // Ignore fields already set
+            if (mFields.contains(name)) {
+                continue;
+            };
+
             IndexableField iField = doc.getField(name);
             
             if (iField == null)
@@ -314,6 +313,7 @@
      * 
      * @return The text sigle as a string.
      */
+    @JsonIgnore
     public String getTextSigle () {
         return this.getFieldValue("textSigle");
     };
@@ -324,6 +324,7 @@
      * 
      * @return The document sigle as a string.
      */
+    @JsonIgnore
     public String getDocSigle () {
         return this.getFieldValue("docSigle");
     };
@@ -334,12 +335,14 @@
      * 
      * @return The corpus sigle as a string.
      */
+    @JsonIgnore
     public String getCorpusSigle () {
         return this.getFieldValue("corpusSigle");
     };
 
 
     @Deprecated
+    @JsonIgnore
     public String getAvailability () {
         return this.getFieldValue("availability");
     };
@@ -369,6 +372,7 @@
             if (mf == null)
                 continue;
             String mfs = mf.key;
+
             String value = this.getFieldValue(mfs);
                 if (value != null && (
                         legacyDateFields.contains(mfs) ||
diff --git a/src/main/java/de/ids_mannheim/korap/response/MetaFields.java b/src/main/java/de/ids_mannheim/korap/response/MetaFields.java
index e083769..514292f 100644
--- a/src/main/java/de/ids_mannheim/korap/response/MetaFields.java
+++ b/src/main/java/de/ids_mannheim/korap/response/MetaFields.java
@@ -20,9 +20,6 @@
 
 public class MetaFields extends AbstractDocument {
 
-    // Mapper for JSON serialization
-    ObjectMapper mapper = new ObjectMapper();
-
     public MetaFields (String id) {
 		this.addMessage(0, "Response format is temporary");
     };
diff --git a/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java b/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java
index c6ba70e..1c60b1d 100644
--- a/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java
+++ b/src/main/java/de/ids_mannheim/korap/response/MetaFieldsObj.java
@@ -208,6 +208,7 @@
         return fieldsMap.containsKey(key);
     };
 
+
     private Iterator<String> getIterator () {
         if (this.fieldsOrder == null) {
             return fieldsMap.keySet().iterator();
diff --git a/src/main/java/de/ids_mannheim/korap/response/match/DocIdentifier.java b/src/main/java/de/ids_mannheim/korap/response/match/DocIdentifier.java
index 53280c7..8d69760 100644
--- a/src/main/java/de/ids_mannheim/korap/response/match/DocIdentifier.java
+++ b/src/main/java/de/ids_mannheim/korap/response/match/DocIdentifier.java
@@ -7,9 +7,10 @@
 // TODO: This should only use textSigle!
 
 public class DocIdentifier {
-    protected String textSigle, // fine
-            corpusID, // LEGACY
-            docID;    // LEGACY
+    protected String
+        textSigle, // fine
+        corpusID, // LEGACY
+        docID;    // LEGACY
 
 
     // Legacy
diff --git a/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java b/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
index 3f6ba6d..4eaa4db 100644
--- a/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
+++ b/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
@@ -131,7 +131,7 @@
         Result kr = ks.apply(ki);
         ObjectMapper mapper = new ObjectMapper();
         JsonNode res = mapper.readTree(kr.toJsonString());
-        
+
         assertEquals(0, res.at("/matches/0/UID").asInt());
         assertEquals("GOE_AGX.00002", res.at("/matches/0/textSigle").asText());
         assertEquals("Maximen und Reflexionen",
@@ -220,6 +220,51 @@
 
 
     @Test
+    public void searchMetaFieldsDuplicateKeys () throws IOException {
+
+        // Construct index
+        KrillIndex ki = new KrillIndex();
+        ki.addDoc(getClass().getResourceAsStream("/goe/AGX-00002.json"), false);
+        ki.commit();
+
+        String jsonString = getJsonString(getClass()
+                .getResource("/queries/metas/fields_single.jsonld").getFile());
+
+        Krill ks = new Krill(jsonString);
+        ks.getMeta().setLimit(1);
+        Result kr = ks.apply(ki);
+
+        String resultJson = kr.toJsonString();
+
+        assertTrue(resultJson.indexOf("\"textSigle\":\"GOE_AGX.00002\"") > 0);
+        assertTrue(resultJson.indexOf("\"docSigle\":\"GOE_AGX\"") > 0);
+        assertTrue(resultJson.indexOf("\"corpusSigle\":\"GOE\"") > 0);
+        assertTrue(resultJson.indexOf("\"UID\":") > 0);
+        assertTrue(resultJson.indexOf("\"availability\":") > 0);
+        
+        assertEquals(
+            resultJson.indexOf("\"textSigle\":\"GOE_AGX.00002\""),
+            resultJson.lastIndexOf("\"textSigle\":\"GOE_AGX.00002\"")
+            );
+        assertEquals(
+            resultJson.indexOf("\"docSigle\":\"GOE_AGX\""),
+            resultJson.lastIndexOf("\"docSigle\":\"GOE_AGX\"")
+            );
+        assertEquals(
+            resultJson.indexOf("\"corpusSigle\":\"GOE\""),
+            resultJson.lastIndexOf("\"corpusSigle\":\"GOE\"")
+            );
+        assertEquals(
+            resultJson.indexOf("\"UID\":0"),
+            resultJson.lastIndexOf("\"UID\":0")
+            );
+        assertEquals(
+            resultJson.indexOf("\"availability\":"),
+            resultJson.lastIndexOf("\"availability\":")
+            );
+    };    
+
+    @Test
     public void searchCollectionFields () throws IOException {
         KrillIndex ki = new KrillIndex();
         FieldDocument fd = new FieldDocument();
diff --git a/src/test/resources/queries/metas/fields_single.jsonld b/src/test/resources/queries/metas/fields_single.jsonld
new file mode 100644
index 0000000..4b3ae2a
--- /dev/null
+++ b/src/test/resources/queries/metas/fields_single.jsonld
@@ -0,0 +1,20 @@
+{
+  "@context" : "http://ids-mannheim.de/ns/KorAP/json-ld/v0.3/context.jsonld",
+  "announcements" : [],
+  "errors" : [],
+  "meta" : {
+    "fields":["textSigle", "docSigle","corpusSigle","UID","availability","corpusID","ID"],
+    "count":1
+  },
+  "query" : {
+    "@type" : "koral:token",
+    "wrap" : {
+      "@type" : "koral:term",
+      "key" : "VERB",
+      "foundry" : "xip",
+      "layer" : "pos",
+      "match" : "match:eq"
+    }
+  },
+  "warnings" : []
+}