Fix build warnings

Change-Id: Ic6a8d8e08f79ca1a41635ca811cb839b100cbd15
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/AnnotationWorkerPool.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/AnnotationWorkerPool.kt
index 4a5f816..7a2e765 100644
--- a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/AnnotationWorkerPool.kt
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/AnnotationWorkerPool.kt
@@ -39,7 +39,7 @@
                     }
                     threadCount.incrementAndGet()
                     successfullyInitialized = true
-                    LOGGER.info("Worker $workerIndex (thread ${self.id}) started.")
+                    LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) started.")
 
                     val process = ProcessBuilder("/bin/sh", "-c", command)
                         .redirectOutput(ProcessBuilder.Redirect.PIPE).redirectInput(ProcessBuilder.Redirect.PIPE)
@@ -47,7 +47,7 @@
                         .start()
 
                     if (process.outputStream == null) {
-                        LOGGER.severe("Worker $workerIndex (thread ${self.id}) failed to open pipe for command '$command'")
+                        LOGGER.severe("Worker $workerIndex (thread ${self.threadId()}) failed to open pipe for command '$command'")
                         return@Thread // Exits thread, finally block will run
                     }
                     // Using try-with-resources for streams to ensure they are closed
@@ -65,7 +65,7 @@
                                         val text = queue.poll(50, TimeUnit.MILLISECONDS) // Reduced timeout for more responsiveness
                                         if (text == null) { // Timeout, continue waiting for more data
                                             if (Thread.currentThread().isInterrupted) {
-                                                LOGGER.info("Worker $workerIndex (thread ${self.id}) writer interrupted, stopping")
+                                                LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) writer interrupted, stopping")
                                                 break
                                             }
                                             continue
@@ -76,23 +76,23 @@
                                                 outputStreamWriter.flush()
                                             } catch (e: IOException) {
                                                 // Log error, but proceed to close
-                                                LOGGER.warning("Worker $workerIndex (thread ${self.id}) failed to write EOF to process: ${e.message}")
+                                                LOGGER.warning("Worker $workerIndex (thread ${self.threadId()}) failed to write EOF to process: ${e.message}")
                                             } finally {
                                                 try { outputStreamWriter.close() } catch (_: IOException) {}
                                             }
-                                            LOGGER.info("Worker $workerIndex (thread ${self.id}) sent EOF to process and writer is stopping.")
+                                            LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) sent EOF to process and writer is stopping.")
                                             break // Exit while loop
                                         }
                                         try {
                                             outputStreamWriter.write(text + "\n# eot\n")
                                             outputStreamWriter.flush()
                                         } catch (e: IOException) {
-                                            LOGGER.severe("Worker $workerIndex (thread ${self.id}) failed to write to process: ${e.message}")
+                                            LOGGER.severe("Worker $workerIndex (thread ${self.threadId()}) failed to write to process: ${e.message}")
                                             break // Exit the loop
                                         }
                                     }
                                 } catch (e: Exception) {
-                                    LOGGER.severe("Writer coroutine in worker $workerIndex (thread ${self.id}) failed: ${e.message}")
+                                    LOGGER.severe("Writer coroutine in worker $workerIndex (thread ${self.threadId()}) failed: ${e.message}")
                                 }
                             }
 
@@ -103,7 +103,7 @@
                                     procInStream.bufferedReader().use { reader ->
                                         while (!inputGotEof) {
                                             if (Thread.currentThread().isInterrupted) {
-                                                LOGGER.info("Worker $workerIndex (thread ${self.id}) reader interrupted, stopping")
+                                                LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) reader interrupted, stopping")
                                                 break
                                             }
                                             val line = reader.readLine()
@@ -117,7 +117,7 @@
                                             }
                                             when (line) {
                                                 "# eof" -> {
-                                                    LOGGER.info("Worker $workerIndex (thread ${self.id}) got EOF in output")
+                                                    LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) got EOF in output")
                                                     inputGotEof = true
                                                     if (output.isNotEmpty()) {
                                                         printOutput(output.toString()) // Print any remaining output
@@ -139,7 +139,7 @@
                                         printOutput(output.toString())
                                     }
                                 } catch (e: Exception) {
-                                    LOGGER.severe("Reader coroutine in worker $workerIndex (thread ${self.id}) failed: ${e.message}")
+                                    LOGGER.severe("Reader coroutine in worker $workerIndex (thread ${self.threadId()}) failed: ${e.message}")
                                 }
                             }
 
@@ -150,9 +150,9 @@
                                         job.join()
                                     }
                                 }
-                                LOGGER.info("Worker $workerIndex (thread ${self.id}) coroutines completed")
+                                LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) coroutines completed")
                             } catch (e: InterruptedException) {
-                                LOGGER.info("Worker $workerIndex (thread ${self.id}) interrupted while waiting for coroutines")
+                                LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) interrupted while waiting for coroutines")
                                 Thread.currentThread().interrupt() // Restore interrupt status
                             } finally {
                                 coroutineScope.cancel() // Ensure cleanup
@@ -162,17 +162,17 @@
 
                     val exitCode = process.waitFor()
                     if (exitCode != 0) {
-                        LOGGER.warning("Worker $workerIndex (thread ${self.id}) process exited with code $exitCode")
+                        LOGGER.warning("Worker $workerIndex (thread ${self.threadId()}) process exited with code $exitCode")
                     } else {
-                        LOGGER.info("Worker $workerIndex (thread ${self.id}) process finished normally")
+                        LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) process finished normally")
                     }
                 } catch (e: IOException) {
-                    LOGGER.severe("Worker $workerIndex (thread ${self.id}) failed: ${e.message}")
+                    LOGGER.severe("Worker $workerIndex (thread ${self.threadId()}) failed: ${e.message}")
                 } catch (e: InterruptedException) {
-                    LOGGER.info("Worker $workerIndex (thread ${self.id}) was interrupted during processing")
+                    LOGGER.info("Worker $workerIndex (thread ${self.threadId()}) was interrupted during processing")
                     Thread.currentThread().interrupt() // Restore interrupt status
                 } catch (e: Exception) { // Catch any other unexpected exceptions during setup or process handling
-                    LOGGER.severe("Unhandled exception in worker thread ${self.id} (index $workerIndex): ${e.message}")
+                    LOGGER.severe("Unhandled exception in worker thread ${self.threadId()} (index $workerIndex): ${e.message}")
                     e.printStackTrace()
                 } finally {
                     if (successfullyInitialized) {
@@ -180,9 +180,9 @@
                             threads.remove(self)
                         }
                         threadCount.decrementAndGet()
-                        LOGGER.info("Worker thread ${self.id} (index $workerIndex) cleaned up and exiting. Active threads: ${threadCount.get()}")
+                        LOGGER.info("Worker thread ${self.threadId()} (index $workerIndex) cleaned up and exiting. Active threads: ${threadCount.get()}")
                     } else {
-                        LOGGER.warning("Worker thread ${self.id} (index $workerIndex) exiting without full initialization/cleanup.")
+                        LOGGER.warning("Worker thread ${self.threadId()} (index $workerIndex) exiting without full initialization/cleanup.")
                     }
                 }
             }.start()
@@ -270,16 +270,16 @@
                 try {
                     thread.join(10000) // Increased timeout to 10 seconds
                     if (thread.isAlive) {
-                        LOGGER.warning("Thread ${thread.id} did not terminate after 10s. Interrupting.")
+                        LOGGER.warning("Thread ${thread.threadId()} did not terminate after 10s. Interrupting.")
                         thread.interrupt()
                         thread.join(2000) // Wait 2 seconds after interrupt
                         if (thread.isAlive) {
-                            LOGGER.severe("Thread ${thread.id} failed to terminate after interrupt.")
+                            LOGGER.severe("Thread ${thread.threadId()} failed to terminate after interrupt.")
                         }
                     }
                 } catch (e: InterruptedException) {
                     Thread.currentThread().interrupt()
-                    LOGGER.warning("Interrupted while joining thread ${thread.id}. It may not have shut down cleanly.")
+                    LOGGER.warning("Interrupted while joining thread ${thread.threadId()}. It may not have shut down cleanly.")
                 }
             }
         }
@@ -291,7 +291,7 @@
             LOGGER.warning("$finalCount worker thread(s) still marked as active according to counter. This might indicate an issue in thread lifecycle management.")
             synchronized(threadsLock) {
                 if (threads.isNotEmpty()) {
-                    LOGGER.warning("The internal threads list is not empty: ${threads.map { it.id }}. Forcing clear.")
+                    LOGGER.warning("The internal threads list is not empty: ${threads.map { it.threadId() }}. Forcing clear.")
                     threads.clear() // Clean up if any refs are lingering despite count issues
                 }
             }
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
index fc97baf..869fe63 100644
--- a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
@@ -490,7 +490,7 @@
     private fun processZipFile(zipFilePath: String, foundry: String = "base") {
         val ord = zipOrdinals[zipFilePath] ?: 0
         val size = zipSizes[zipFilePath] ?: 0L
-        LOGGER.info("Processing zip ${if (ord>0) ord else "?"}/$totalZips: ${zipFilePath} (${humanBytes(size)}) in thread ${Thread.currentThread().id}")
+        LOGGER.info("Processing zip ${if (ord>0) ord else "?"}/$totalZips: ${zipFilePath} (${humanBytes(size)}) in thread ${Thread.currentThread().threadId()}")
         LOGGER.info("Foundry: $foundry $dbFactory")
         if (outputFormat == OutputFormat.KORAPXML && dbFactory == null) {
             var targetFoundry = "base"
@@ -545,7 +545,7 @@
     private fun processZipFileSequentially(zipFilePath: String, foundry: String = "base") {
         val ord = zipOrdinals[zipFilePath] ?: 0
         val size = zipSizes[zipFilePath] ?: 0L
-        LOGGER.info("Processing zip ${if (ord>0) ord else "?"}/$totalZips: ${zipFilePath} (${humanBytes(size)}) in thread ${Thread.currentThread().id}")
+        LOGGER.info("Processing zip ${if (ord>0) ord else "?"}/$totalZips: ${zipFilePath} (${humanBytes(size)}) in thread ${Thread.currentThread().threadId()}")
         if (zipFilePath.hasCorrespondingBaseZip()) {
             // Process the two related zips strictly sequentially to limit memory growth
             val zips = arrayOf(zipFilePath, zipFilePath.correspondingBaseZip()!!)
@@ -554,7 +554,7 @@
                     // Iterate entries in a deterministic order to keep related files close together
                     zipFile.stream()
                         .filter { extractMetadataRegex.isNotEmpty() || !it.name.contains("header.xml") }
-                        .sorted(Comparator.comparing(ZipEntry::getName))
+                        .sorted(Comparator.comparing<ZipEntry, String> { it.name })
                         .forEachOrdered { zipEntry ->
                             processZipEntry(zipFile, foundry, zipEntry, true)
                         }
@@ -564,7 +564,7 @@
             ZipFile(zipFilePath).use { zipFile ->
                 zipFile.stream()
                     .filter { extractMetadataRegex.isNotEmpty() || !it.name.contains("header.xml") }
-                    .sorted(Comparator.comparing(ZipEntry::getName))
+                    .sorted(Comparator.comparing<ZipEntry, String> { it.name })
                     .forEachOrdered { zipEntry ->
                         processZipEntry(zipFile, foundry, zipEntry, false)
                     }
@@ -616,21 +616,21 @@
     fun processZipEntry(zipFile: ZipFile, _foundry: String, zipEntry: ZipEntry, passedWaitForMorpho: Boolean) {
         var foundry = _foundry
         var waitForMorpho = passedWaitForMorpho
-        LOGGER.finer("Processing ${zipEntry.name} in thread ${Thread.currentThread().id}")
-        if (taggerName != null && !taggerToolBridges.containsKey(Thread.currentThread().id)) {
+        LOGGER.finer("Processing ${zipEntry.name} in thread ${Thread.currentThread().threadId()}")
+        if (taggerName != null && !taggerToolBridges.containsKey(Thread.currentThread().threadId())) {
             val tagger = AnnotationToolBridgeFactory.getAnnotationToolBridge(taggerName!!, taggerModel!!, LOGGER) as TaggerToolBridge?
-            taggerToolBridges[Thread.currentThread().id] = tagger
+            taggerToolBridges[Thread.currentThread().threadId()] = tagger
             if (tagger != null) {
                 foundry = tagger.foundry
             }
 
         }
-        if (parserName != null && !parserToolBridges.containsKey(Thread.currentThread().id)) {
+        if (parserName != null && !parserToolBridges.containsKey(Thread.currentThread().threadId())) {
             val parser = AnnotationToolBridgeFactory.getAnnotationToolBridge(parserName!!, parserModel!!, LOGGER) as ParserToolBridge?
-            parserToolBridges[Thread.currentThread().id] = parser
+            parserToolBridges[Thread.currentThread().threadId()] = parser
             if (parser != null) {
                 foundry = "$foundry dependency:${parser.foundry}"
-                LOGGER.fine("Initialized parser ${parserName} with foundry $foundry in thread ${Thread.currentThread().id}")
+                LOGGER.fine("Initialized parser ${parserName} with foundry $foundry in thread ${Thread.currentThread().threadId()}")
             }
         }
 
@@ -707,7 +707,7 @@
                     && (extractMetadataRegex.isEmpty() || metadata[docId] != null)
                 ) {
                     // Be quiet on INFO; per-text logs only on FINE and below
-                    LOGGER.fine("Processing text: $docId in thread ${Thread.currentThread().id}")
+                    LOGGER.fine("Processing text: $docId in thread ${Thread.currentThread().threadId()}")
                     processText(docId, foundry)
                 }
             } else if (extractMetadataRegex.isNotEmpty() && zipEntry.name.matches(Regex(".*/header\\.xml$"))) {
@@ -735,7 +735,7 @@
                          && (!morphoRequired || morpho[docId] != null)
                      ) {
                         // Be quiet on INFO; per-text logs only on FINE and below
-                        LOGGER.fine("Processing text (meta-ready): $docId in thread ${Thread.currentThread().id}")
+                        LOGGER.fine("Processing text (meta-ready): $docId in thread ${Thread.currentThread().threadId()}")
                         processText(docId, foundry)
                     }
                 }
@@ -749,7 +749,7 @@
         docId: String,
         foundry: String,
     ) {
-        LOGGER.fine("Processing text: $docId in thread ${Thread.currentThread().id}")
+        LOGGER.fine("Processing text: $docId in thread ${Thread.currentThread().threadId()}")
         var morphoFoundry = getMorphoFoundry()
         val output =
         if (outputFormat == OutputFormat.WORD2VEC) {
@@ -757,27 +757,27 @@
         } else if (outputFormat == OutputFormat.NOW) {
             nowOutput(docId)
         } else {
-            if (taggerToolBridges[Thread.currentThread().id] != null) {
-                morpho[docId] = taggerToolBridges[Thread.currentThread().id]!!.tagText(
+            if (taggerToolBridges[Thread.currentThread().threadId()] != null) {
+                morpho[docId] = taggerToolBridges[Thread.currentThread().threadId()]!!.tagText(
                     tokens[docId]!!,
                     sentences[docId],
                     texts[docId]!!
                 )
 
             }
-            if (parserToolBridges[Thread.currentThread().id] != null) {
+            if (parserToolBridges[Thread.currentThread().threadId()] != null) {
                 if (morpho[docId] == null) {
                     LOGGER.severe("No morpho data for $docId")
                     //exitProcess(1)
                 }
-                LOGGER.finer("Parsing text: $docId in thread ${Thread.currentThread().id}")
-                morpho[docId] = parserToolBridges[Thread.currentThread().id]!!.parseText(
+                LOGGER.finer("Parsing text: $docId in thread ${Thread.currentThread().threadId()}")
+                morpho[docId] = parserToolBridges[Thread.currentThread().threadId()]!!.parseText(
                     tokens[docId]!!,
                     morpho[docId],
                     sentences[docId],
                     texts[docId]!!
                 )
-                LOGGER.finer("Parsed text: $docId in thread ${Thread.currentThread().id}")
+                LOGGER.finer("Parsed text: $docId in thread ${Thread.currentThread().threadId()}")
             }
             if (outputFormat == OutputFormat.KORAPXML && annotationWorkerPool == null) {
                 korapXmlOutput(getMorphoFoundry(), docId)
@@ -837,7 +837,7 @@
         }
     }
 
-    private fun getMorphoFoundry() = taggerToolBridges[Thread.currentThread().id]?.foundry ?: "base"
+    private fun getMorphoFoundry() = taggerToolBridges[Thread.currentThread().threadId()]?.foundry ?: "base"
 
     private fun logMemoryStats(count: Int) {
         try {
@@ -1107,7 +1107,6 @@
         // If no text is available (e.g., lemma-only mode), emit lemmas
         if (texts[docId] == null) {
             tokens[docId]?.forEach { span ->
-                if (span == null) return@forEach
                 val key = "${span.from}-${span.to}"
                 val lemmaVal = morpho[docId]?.get(key)?.lemma
                 output.append((lemmaVal?.takeIf { it != "_" } ?: "_"), " ")
@@ -1116,7 +1115,6 @@
             return output
         }
         tokens[docId]?.forEach { span ->
-            if (span == null) return@forEach
             token_index++
             if (sentences[docId] != null && (sentence_index >= sentences[docId]!!.size || span.from >= sentences[docId]!![sentence_index].to)) {
                 if (output.isNotEmpty()) {
@@ -1166,7 +1164,6 @@
         if (texts[docId] == null) {
             // Lemma-only fallback when original text is not loaded
             tokens[docId]?.forEach { span ->
-                if (span == null) return@forEach
                 if (sentences[docId] != null && (sentence_index >= sentences[docId]!!.size || span.from >= sentences[docId]!![sentence_index].to)) {
                     if (output.isNotEmpty() && !output.endsWith("@@$docId ")) {
                         output.append(" <p> ")
@@ -1184,7 +1181,6 @@
         }
         
         tokens[docId]?.forEach { span ->
-            if (span == null) return@forEach
             token_index++
             if (sentences[docId] != null && (sentence_index >= sentences[docId]!!.size || span.from >= sentences[docId]!![sentence_index].to)) {
                 // Replace sentence end with <p> tag instead of newline
@@ -1239,8 +1235,12 @@
         return when (columns) {
             1 -> ("$token\n")
             10 -> ("$token_index\t$token\t$lemma\t$myUpos\t$xpos\t$feats\t$head\t$deprel\t$deps\t$misc$tokenSeparator")
-            else -> arrayOf(token_index, token, lemma, myUpos, xpos, feats, head, deprel, deps, misc).slice(0..<min(columns, 10))
-                .joinToString("\t", postfix = tokenSeparator)
+            else -> {
+                val fields = listOf(
+                    token_index.toString(), token, lemma, myUpos, xpos, feats, head, deprel, deps, misc
+                )
+                fields.subList(0, min(columns, 10)).joinToString("\t", postfix = tokenSeparator)
+            }
         }
     }
 
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/MaltParserBridge.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/MaltParserBridge.kt
index d48e2e4..8e75350 100644
--- a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/MaltParserBridge.kt
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/MaltParserBridge.kt
@@ -30,7 +30,7 @@
     override fun tagSentence(
         sentenceTokens: MutableList<String>,
         sentenceTokenOffsets: MutableList<String>,
-        morpho: MutableMap<String, KorapXmlTool.MorphoSpan>?
+        morphoMap: MutableMap<String, KorapXmlTool.MorphoSpan>?
     ) {
         val result = tagger.parse(sentenceTokens.toTypedArray())
 
@@ -40,8 +40,8 @@
             val label = edge.toString()
             if (label.contains("DEPREL:")) {
                 val rel = edge.toString().substringAfter("DEPREL:").trim()
-                val old = morpho?.get(sentenceTokenOffsets[head - 1])
-                morpho?.set(
+                val old = morphoMap?.get(sentenceTokenOffsets[head - 1])
+                morphoMap?.set(
                     sentenceTokenOffsets[head - 1], KorapXmlTool.MorphoSpan(
                         lemma = old?.lemma, xpos = old?.xpos, feats = old?.feats, head = from.toString(), deprel = rel
                     )
@@ -49,4 +49,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/test/kotlin/de/ids_mannheim/korapxmltools/KorapXmlToolTest.kt b/app/src/test/kotlin/de/ids_mannheim/korapxmltools/KorapXmlToolTest.kt
index 4aa98ac..7acd6b0 100644
--- a/app/src/test/kotlin/de/ids_mannheim/korapxmltools/KorapXmlToolTest.kt
+++ b/app/src/test/kotlin/de/ids_mannheim/korapxmltools/KorapXmlToolTest.kt
@@ -273,7 +273,7 @@
     @Test
     fun korapXmlOutputWorks() {
         val sourceFile = loadResource("wdf19.zip").path
-        val tmpSourceFileName = createTempFile("tmp", ".zip", null).absolutePath
+        val tmpSourceFileName = java.io.File.createTempFile("tmp", ".zip").absolutePath
         File(sourceFile).copyTo(File(tmpSourceFileName), true)
 
         val args = arrayOf("-o", "-f", "zip", tmpSourceFileName)
@@ -286,7 +286,7 @@
     @Test
     fun overwriteWorks() {
         val sourceFile = loadResource("wdf19.zip").path
-        val tmpSourceFileName = createTempFile("tmp", ".zip", null).absolutePath
+        val tmpSourceFileName = java.io.File.createTempFile("tmp", ".zip").absolutePath
         File(sourceFile).copyTo(File(tmpSourceFileName), true)
         val resultFile = tmpSourceFileName.toString().replace(".zip", ".base.zip")
         File(resultFile).createNewFile()