diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000000000000000000000000000000000000..47dba988d8366b6b3fb26883dcf5ece502e00b3d
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+briar-desktop
\ No newline at end of file
diff --git a/.idea/scopes/briar_desktop_kotlin.xml b/.idea/scopes/briar_desktop_kotlin.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba0d4c4bc7000e4668b70bd6da196b66bfeb2bc7
--- /dev/null
+++ b/.idea/scopes/briar_desktop_kotlin.xml
@@ -0,0 +1,3 @@
+<component name="DependencyValidationManager">
+  <scope name="briar-desktop-kotlin" pattern="file[briar-desktop.main]:kotlin//*||file[briar-desktop.test]:kotlin//*||file[briar-desktop.buildSrc.main]:kotlin//*" />
+</component>
\ No newline at end of file
diff --git a/.idea/scopes/briar_desktop_kotlin_main.xml b/.idea/scopes/briar_desktop_kotlin_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5827510279bd3f02c43f2eca688d2ac352a0337a
--- /dev/null
+++ b/.idea/scopes/briar_desktop_kotlin_main.xml
@@ -0,0 +1,3 @@
+<component name="DependencyValidationManager">
+  <scope name="briar-desktop-kotlin-main" pattern="file[briar-desktop.main]:kotlin//*" />
+</component>
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/org/briarproject/briar/desktop/builddata/BuildDataPlugin.kt b/buildSrc/src/main/kotlin/org/briarproject/briar/desktop/builddata/BuildDataPlugin.kt
index 59337918a488eea16f68e1b34041578a33991cfc..a94e0c65a04518ef271c45b4b1bb06306ab97fdf 100644
--- a/buildSrc/src/main/kotlin/org/briarproject/briar/desktop/builddata/BuildDataPlugin.kt
+++ b/buildSrc/src/main/kotlin/org/briarproject/briar/desktop/builddata/BuildDataPlugin.kt
@@ -26,7 +26,7 @@ import org.gradle.api.plugins.JavaPluginExtension
 class BuildDataPlugin : Plugin<Project> {
     override fun apply(project: Project) {
         val logger = project.logger
-        logger.info("applying version access plugin")
+        logger.info("applying version access plugin") // NON-NLS
 
         val extension = project.extensions.create(
             "buildData", BuildDataPluginExtension::class.java
@@ -38,7 +38,8 @@ class BuildDataPlugin : Plugin<Project> {
         project.tasks.findByName("compileJava")!!.dependsOn(task)
         val pathBuildDir = project.buildDir.toPath()
         val source = Util.getSourceDir(pathBuildDir)
-        val sourceSets = project.extensions.getByType(JavaPluginExtension::class.java).sourceSets.findByName("main")
+        val sourceSets =
+            project.extensions.getByType(JavaPluginExtension::class.java).sourceSets.findByName("main") // NON-NLS
         sourceSets!!.java { sourceSet: SourceDirectorySet -> sourceSet.srcDir(source) }
     }
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/Main.kt b/src/main/kotlin/org/briarproject/briar/desktop/Main.kt
index 78b2e9f617cc17cce3c85c15e0f6db4b9bcc6819..013368fba8ffaf403bfc31049cdb0df5b1fa6e94 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/Main.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/Main.kt
@@ -34,7 +34,9 @@ import org.briarproject.briar.BriarCoreEagerSingletons
 import org.briarproject.briar.desktop.utils.FileUtils
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
 import org.briarproject.briar.desktop.utils.LogUtils
+import org.jetbrains.annotations.NonNls
 import java.io.File.separator
 import java.io.IOException
 import java.lang.System.getProperty
@@ -48,10 +50,11 @@ import java.util.logging.Level.ALL
 import java.util.logging.Level.INFO
 import java.util.logging.Level.WARNING
 
+@NonNls
 private val DEFAULT_DATA_DIR = getProperty("user.home") + separator + ".briar" + separator + "desktop"
 
 private class Main : CliktCommand(
-    name = "briar-desktop",
+    name = "briar-desktop", // NON-NLS
     help = i18n("main.help.title")
 ) {
 
@@ -59,26 +62,27 @@ private class Main : CliktCommand(
         private val LOG = KotlinLogging.logger {}
     }
 
-    private val debug by option("--debug", "-d", help = i18n("main.help.debug")).flag(
-        default = false
-    )
+    private val debug by option(
+        "--debug", "-d", // NON-NLS
+        help = i18n("main.help.debug")
+    ).flag(default = false)
     private val verbosity by option(
-        "--verbose",
-        "-v",
+        "--verbose", // NON-NLS
+        "-v", // NON-NLS
         help = i18n("main.help.verbose")
     ).counted()
     private val dataDir by option(
-        "--data-dir",
+        "--data-dir", // NON-NLS
         help = i18nF("main.help.data", DEFAULT_DATA_DIR),
         metavar = "PATH",
-        envvar = "BRIAR_DATA_DIR"
+        envvar = "BRIAR_DATA_DIR" // NON-NLS
     ).default(DEFAULT_DATA_DIR)
     private val socksPort by option(
-        "--socks-port",
+        "--socks-port", // NON-NLS
         help = i18n("main.help.tor.port.socks")
     ).int().default(DEFAULT_SOCKS_PORT)
     private val controlPort by option(
-        "--control-port",
+        "--control-port", // NON-NLS
         help = i18n("main.help.tor.port.control")
     ).int().default(DEFAULT_CONTROL_PORT)
 
@@ -93,12 +97,12 @@ private class Main : CliktCommand(
         LogUtils.setupLogging(level)
 
         val buildTime = Instant.ofEpochMilli(BuildData.GIT_TIME).atZone(ZoneId.systemDefault()).toLocalDateTime()
-        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
-        LOG.info { "This is briar-desktop version ${BuildData.VERSION}" }
-        LOG.info { "Build info:" }
-        LOG.info { "  Git hash ${BuildData.GIT_HASH}" }
-        LOG.info { "  Commit time ${formatter.format(buildTime)}" }
-        LOG.info { "  Branch ${BuildData.GIT_BRANCH}" }
+        val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") // NON-NLS
+        LOG.i { "This is briar-desktop version ${BuildData.VERSION}" }
+        LOG.i { "Build info:" }
+        LOG.i { "  Git hash ${BuildData.GIT_HASH}" }
+        LOG.i { "  Commit time ${formatter.format(buildTime)}" }
+        LOG.i { "  Branch ${BuildData.GIT_BRANCH}" }
 
         val dataDir = getDataDir()
         val app =
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/attachment/media/ImageCompressorImpl.kt b/src/main/kotlin/org/briarproject/briar/desktop/attachment/media/ImageCompressorImpl.kt
index fe811dc42209e872644c838cbcca238d79b56684..8399876c5d0fdb6269901fd14e47b31b3885e022 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/attachment/media/ImageCompressorImpl.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/attachment/media/ImageCompressorImpl.kt
@@ -20,6 +20,7 @@ package org.briarproject.briar.desktop.attachment.media
 
 import mu.KotlinLogging
 import org.briarproject.briar.api.attachment.MediaConstants.MAX_IMAGE_SIZE
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
 import java.awt.geom.AffineTransform
 import java.awt.image.AffineTransformOp
 import java.awt.image.BufferedImage
@@ -77,7 +78,7 @@ class ImageCompressorImpl @Inject internal constructor() : ImageCompressor {
 
             jpgWriter.dispose()
             if (out.size() <= MAX_IMAGE_SIZE) {
-                LOG.info { "Compressed image to ${out.size()} bytes, quality $quality" }
+                LOG.i { "Compressed image to ${out.size()} bytes, quality $quality" }
                 return ByteArrayInputStream(out.toByteArray())
             }
             out.reset()
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
index cb40cc85f25f73b3e7534a07e38ade782ef112c9..d390e3ee1ad035eca43f8e5afc3fb0a8f9dcb458 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt
@@ -53,6 +53,7 @@ import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp
 import java.time.Instant
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "name" to "Paul",
     "alias" to "UI Master",
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt
index ec90f4a020584ccfda1873dada7223317ebf6785..b0f14f035b82b8eb3b266456fa7cae85e0f22886 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt
@@ -36,6 +36,7 @@ import org.briarproject.briar.api.identity.AuthorManager
 import org.briarproject.briar.desktop.conversation.ConversationMessagesReadEvent
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.utils.ImageUtils
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
 import org.briarproject.briar.desktop.viewmodel.asState
 import javax.inject.Inject
 
@@ -104,18 +105,18 @@ constructor(
         super.eventOccurred(e)
         when (e) {
             is ConversationMessageTrackedEvent -> {
-                LOG.info { "Conversation message tracked, updating item" }
+                LOG.i { "Conversation message tracked, updating item" }
                 updateItem(e.contactId) { it.updateTimestampAndUnread(e.timestamp, e.read) }
             }
             is ContactAliasChangedEvent -> {
                 updateItem(e.contactId) { it.updateAlias(e.alias) }
             }
             is ConversationMessagesReadEvent -> {
-                LOG.info("${e.count} conversation messages read, updating item")
+                LOG.i { "${e.count} conversation messages read, updating item" }
                 updateItem(e.contactId) { it.updateFromMessagesRead(e.count) }
             }
             is AvatarUpdatedEvent -> {
-                LOG.info("received avatar update: ${e.attachmentHeader}")
+                LOG.i { "received avatar update: ${e.attachmentHeader}" }
                 if (e.attachmentHeader == null) {
                     updateItem(e.contactId) { it.updateAvatar(null) }
                 } else {
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt
index d4f1aeb8c73ef6256c8141fec7f4ab9f62f984e4..ffb28a17834d0813d604d40b92faee24a173f9d0 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt
@@ -38,6 +38,7 @@ import org.briarproject.briar.api.conversation.ConversationManager
 import org.briarproject.briar.api.identity.AuthorManager
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.utils.ImageUtils.loadAvatar
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
 import org.briarproject.briar.desktop.utils.clearAndAddAll
 import org.briarproject.briar.desktop.utils.removeFirst
 import org.briarproject.briar.desktop.utils.replaceFirst
@@ -98,25 +99,25 @@ abstract class ContactsViewModel(
     override fun eventOccurred(e: Event?) {
         when (e) {
             is ContactAddedEvent -> {
-                LOG.info("Contact added, reloading")
+                LOG.i { "Contact added, reloading" }
                 loadContacts()
             }
             is PendingContactAddedEvent -> {
-                LOG.info("Pending contact added, reloading")
+                LOG.i { "Pending contact added, reloading" }
                 loadContacts()
             }
             is ContactConnectedEvent -> {
-                LOG.info("Contact connected, update state")
+                LOG.i { "Contact connected, update state" }
                 updateItem(e.contactId) {
                     it.updateIsConnected(true)
                 }
             }
             is ContactDisconnectedEvent -> {
-                LOG.info("Contact disconnected, update state")
+                LOG.i { "Contact disconnected, update state" }
                 updateItem(e.contactId) { it.updateIsConnected(false) }
             }
             is ContactRemovedEvent -> {
-                LOG.info("Contact removed, removing item")
+                LOG.i { "Contact removed, removing item" }
                 removeItem(e.contactId)
             }
         }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
index 1ea6c34601a06ec891ca6aa15422238ea3481551..cb6b3f19a259e7d4e4b7e5a08e5861ba17d62795 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactDialog.kt
@@ -59,9 +59,12 @@ import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
 import org.briarproject.briar.desktop.utils.PreviewUtils
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import org.briarproject.briar.desktop.viewmodel.viewModel
+import org.jetbrains.annotations.NonNls
 
+@NonNls
 const val link = "briar://ady23gvb2r76afe5zhxh5kvnh4b22zrcnxibn63tfknrdcwrw7zrs"
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "visible" to true,
     "remote link" to "",
@@ -96,6 +99,7 @@ fun main() = preview(
     )
 }
 
+@Suppress("HardCodedStringLiteral")
 private fun PreviewUtils.PreviewScope.mapErrors(name: String?): AddContactError? = when (name) {
     OwnLinkError::class.simpleName!! -> OwnLinkError(link)
     RemoteInvalidError::class.simpleName!! -> RemoteInvalidError(link)
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactViewModel.kt
index 7794117494d78ee68c6300a862657d5c248f946e..486e39c1975a08073ffb067aecb665264b7f2751 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/add/remote/AddContactViewModel.kt
@@ -30,6 +30,7 @@ import org.briarproject.bramble.api.identity.AuthorConstants
 import org.briarproject.bramble.api.lifecycle.LifecycleManager
 import org.briarproject.bramble.util.StringUtils
 import org.briarproject.briar.desktop.threading.BriarExecutors
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import org.briarproject.briar.desktop.viewmodel.DbViewModel
 import org.briarproject.briar.desktop.viewmodel.asState
 import java.security.GeneralSecurityException
@@ -115,21 +116,21 @@ constructor(
         val matcher = HandshakeLinkConstants.LINK_REGEX.matcher(link.trim())
         // check if the link is well-formed
         if (!matcher.matches()) {
-            LOG.warn { "Remote handshake link is invalid" }
+            LOG.w { "Remote handshake link is invalid" }
             _error.value = RemoteInvalidError(link)
             return
         }
         // compare with own link
         val withoutSchema = matcher.group(2)
-        val withSchema = "briar://$withoutSchema"
+        val withSchema = "briar://$withoutSchema" // NON-NLS
         if (_handshakeLink.value == withSchema) {
-            LOG.warn { "Please enter contact's link, not your own" }
+            LOG.w { "Please enter contact's link, not your own" }
             _error.value = OwnLinkError(link)
             return
         }
 
         if (aliasIsInvalid(alias)) {
-            LOG.warn { "Alias is invalid" }
+            LOG.w { "Alias is invalid" }
             _error.value = AliasInvalidError(link, alias)
             return
         }
@@ -143,10 +144,10 @@ constructor(
                     _remoteHandshakeLink.value = ""
                 }
             } catch (e: FormatException) {
-                LOG.warn { "Link is invalid: $link" }
+                LOG.w { "Link is invalid: $link" }
                 _error.value = LinkInvalidError(link)
             } catch (e: GeneralSecurityException) {
-                LOG.warn { "Public key is invalid: $link" }
+                LOG.w { "Public key is invalid: $link" }
                 _error.value = PublicKeyInvalidError(link)
             }
             /*
@@ -154,10 +155,10 @@ constructor(
              See https://code.briarproject.org/briar/briar-desktop/-/issues/240
             */
             catch (e: ContactExistsException) {
-                LOG.warn { "Contact already exists: $link" }
+                LOG.w { "Contact already exists: $link" }
                 _error.value = ContactAlreadyExistsError(link, e.remoteAuthor.name, alias)
             } catch (e: PendingContactExistsException) {
-                LOG.warn { "Pending contact already exists: $link" }
+                LOG.w { "Pending contact already exists: $link" }
                 _error.value = PendingAlreadyExistsError(link, e.pendingContact.alias, alias)
             }
         }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt
index f43dc960efb702e42e67d76901681f71d6e37ac9..d18b95e4fcec36dab15fa7dee441951629c1e430 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt
@@ -37,6 +37,7 @@ import org.briarproject.briar.api.conversation.DeletionResult
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "introduction_pending" to false,
     "invitation_pending" to false,
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt
index fb12f55dd75808ebbc284cc4db8a4c67b9df9297..606611748896f1b867ba35347239799177b72216 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationInput.kt
@@ -59,6 +59,7 @@ import org.briarproject.briar.desktop.utils.ImagePicker.pickImageUsingDialog
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 
+@Suppress("HardCodedStringLiteral")
 @OptIn(ExperimentalMaterialApi::class, ExperimentalComposeUiApi::class)
 fun main() = preview {
     val bitmap = ResourceLoader.Default.load("images/logo_circle.png").use {
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationItemView.kt
index 7dbc9376a397a32269d17e3a8333b56638432b21..0c133629b20e0144a2b2a11bada24a17c10a4734 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationItemView.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationItemView.kt
@@ -59,6 +59,7 @@ import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp
 import java.time.Instant
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview {
     LazyColumn {
         item {
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationList.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationList.kt
index 56d09463713f1a7415d8c173492f94e98616b621..62c9ec49a3a463adefd6a420a27277ef51a79925 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationList.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationList.kt
@@ -67,6 +67,7 @@ import org.briarproject.briar.desktop.utils.replaceIfIndexed
 import org.briarproject.briar.desktop.viewmodel.SingleStateEvent
 import java.time.Instant
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "num_messages" to 20,
     "first_unread_index" to 5
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationMessageItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationMessageItemView.kt
index 5089dc0826c6b6a6049149511e4b612545f2d42e..1bb873d71eb6d4629c3336619c046de2aa118037 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationMessageItemView.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationMessageItemView.kt
@@ -35,6 +35,7 @@ import org.briarproject.briar.desktop.theme.textPrimary
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import java.time.Instant
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "text" to "This is a long long long message that spans over several lines.\n\nIt ends here.",
     "time" to Instant.now().toEpochMilli(),
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationNoticeItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationNoticeItemView.kt
index e12981c49b5b7fabea5d561c5e2de99bcfba177b..9ab2ebac87a333b4c5ec38ef6af0a04bb8ec408d 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationNoticeItemView.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationNoticeItemView.kt
@@ -43,6 +43,7 @@ import org.briarproject.briar.desktop.theme.textSecondary
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import java.time.Instant
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "notice" to "Text of notice message.",
     "text" to "This is a long long long message that spans over several lines.\n\nIt ends here.",
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationRequestItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationRequestItemView.kt
index 7dc4390046c5f2e091fc251dce56281d873c6cb0..65883608235dbdf46f14c130dcc1ef08019a2d5c 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationRequestItemView.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationRequestItemView.kt
@@ -52,6 +52,7 @@ import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 import java.time.Instant
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "canBeOpened" to false,
     "answered" to false,
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt
index c2c98b3c8b19ecf4a1c584ddb6e5f876efdeabc5..33ed0e2adb9fe7afcd31b9bb7ea904df49eb0904 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt
@@ -62,7 +62,9 @@ import org.briarproject.briar.desktop.contact.ContactItem
 import org.briarproject.briar.desktop.conversation.ConversationRequestItem.RequestType.INTRODUCTION
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.utils.ImageUtils.loadAvatar
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
 import org.briarproject.briar.desktop.utils.KLoggerUtils.logDuration
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import org.briarproject.briar.desktop.utils.addAfterLast
 import org.briarproject.briar.desktop.utils.clearAndAddAll
 import org.briarproject.briar.desktop.utils.replaceIf
@@ -198,10 +200,10 @@ constructor(
                     txn.attach { addMessage(msg) }
                 } catch (e: UnexpectedTimerException) {
                     // todo: handle this properly
-                    LOG.warn(e) {}
+                    LOG.w(e) {}
                 } catch (e: DbException) {
                     // todo: handle this properly
-                    LOG.warn(e) {}
+                    LOG.w(e) {}
                 }
             }
         }
@@ -280,7 +282,7 @@ constructor(
             return contactItem
         } catch (e: NoSuchContactException) {
             // todo: handle this properly
-            LOG.warn(e) {}
+            LOG.w(e) {}
             throw e
         }
     }
@@ -308,7 +310,7 @@ constructor(
             }
         } catch (e: NoSuchContactException) {
             // todo: handle this properly
-            LOG.warn(e) {}
+            LOG.w(e) {}
         } finally {
             _loadingMessages.value = false
         }
@@ -318,7 +320,7 @@ constructor(
         when (e) {
             is ConversationMessageReceivedEvent<*> -> {
                 if (e.contactId == _contactId.value) {
-                    LOG.info("Message received, adding")
+                    LOG.i { "Message received, adding" }
                     val h = e.messageHeader
                     // insert at start of list according to descending sort order
                     runOnDbThreadWithTransaction(true) { txn ->
@@ -337,32 +339,32 @@ constructor(
             }
             is MessagesSentEvent -> {
                 if (e.contactId == _contactId.value) {
-                    LOG.info("Messages sent")
+                    LOG.i { "Messages sent" }
                     markMessages(e.messageIds, sent = true, seen = false)
                 }
             }
             is MessagesAckedEvent -> {
                 if (e.contactId == _contactId.value) {
-                    LOG.info("Messages acked")
+                    LOG.i { "Messages acked" }
                     markMessages(e.messageIds, sent = true, seen = true)
                 }
             }
             is ConversationMessagesDeletedEvent -> {
                 if (e.contactId == _contactId.value) {
-                    LOG.info("Messages auto-deleted")
+                    LOG.i { "Messages auto-deleted" }
                     val messages = HashSet(e.messageIds)
                     _messages.removeIf { messages.contains(it.id) }
                 }
             }
             is ContactConnectedEvent -> {
                 if (e.contactId == _contactId.value) {
-                    LOG.info("Contact connected")
+                    LOG.i { "Contact connected" }
                     _contactItem.value = _contactItem.value!!.updateIsConnected(true)
                 }
             }
             is ContactDisconnectedEvent -> {
                 if (e.contactId == _contactId.value) {
-                    LOG.info("Contact disconnected")
+                    LOG.i { "Contact disconnected" }
                     _contactItem.value = _contactItem.value!!.updateIsConnected(false)
                 }
             }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationVisitor.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationVisitor.kt
index ca40ff293e24b694fefb03c5191a04586fc82d98..d8fe35903eaed2be8d1dce8466a0460ee06c8f33 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationVisitor.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationVisitor.kt
@@ -39,6 +39,7 @@ import org.briarproject.briar.desktop.DesktopFeatureFlags
 import org.briarproject.briar.desktop.utils.ImageUtils
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import org.briarproject.briar.desktop.utils.UiUtils.getContactDisplayName
 
 internal class ConversationVisitor(
@@ -58,7 +59,7 @@ internal class ConversationVisitor(
         try {
             return messagingManager.getMessageText(txn, m)
         } catch (e: DbException) {
-            LOG.warn(e) {}
+            LOG.w(e) {}
         }
         return null
     }
@@ -76,7 +77,7 @@ internal class ConversationVisitor(
         if (h.hasText()) {
             item.text = loadMessageText(txn, h.id)
         } else {
-            LOG.warn { "private message without text" }
+            LOG.w { "private message without text" }
         }
         return item
     }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt b/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt
index 2f24f2fa2fe137107585aaa2510ca08930d4ea2f..0e0c9043e374f1249ce818aab7eaeb27757fd634 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/expiration/ExpirationBanner.kt
@@ -44,6 +44,7 @@ import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nP
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview {
     Column {
         ExpirationBanner {}
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
index 4ea03ecc1542e777cd9ca7159b9dac395ba77852..beddb1c7184959441919330b9c5be7f7e817a600 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/ErrorScreen.kt
@@ -58,6 +58,7 @@ import org.briarproject.briar.desktop.ui.Constants.STARTUP_FIELDS_WIDTH
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 import org.briarproject.briar.desktop.utils.PreviewUtils.preview
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview {
     var error: ErrorSubViewModel.Error by remember { mutableStateOf(RegistrationSubViewModel.RegistrationError) }
 
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationSubViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationSubViewModel.kt
index 9042d20af0fbaa9947a7e859103f935a4c733c5a..eae000878cd1a5e8f10183935eb1586ff976be41 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationSubViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationSubViewModel.kt
@@ -29,6 +29,8 @@ import org.briarproject.briar.desktop.login.RegistrationSubViewModel.State.CREAT
 import org.briarproject.briar.desktop.login.RegistrationSubViewModel.State.INSERT_NICKNAME
 import org.briarproject.briar.desktop.login.RegistrationSubViewModel.State.INSERT_PASSWORD
 import org.briarproject.briar.desktop.threading.BriarExecutors
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import org.briarproject.briar.desktop.viewmodel.asState
 
 class RegistrationSubViewModel(
@@ -116,10 +118,10 @@ class RegistrationSubViewModel(
         _state.value = CREATING
         briarExecutors.onIoThread {
             if (accountManager.createAccount(_nickname.value, _password.value)) {
-                LOG.info { "Created account" }
+                LOG.i { "Created account" }
                 viewModel.startBriarCore()
             } else {
-                LOG.warn { "Failed to create account" }
+                LOG.w { "Failed to create account" }
                 viewModel.showError(RegistrationError)
             }
         }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/StartupViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/StartupViewModel.kt
index 247d7451dac89e1e88848651d2d8932e8d261266..21af167213a438998facd91090c13c9611617ad6 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/login/StartupViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/StartupViewModel.kt
@@ -31,6 +31,8 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREA
 import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS
 import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent
 import org.briarproject.briar.desktop.threading.BriarExecutors
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel
 import org.briarproject.briar.desktop.viewmodel.asState
 import javax.inject.Inject
@@ -98,9 +100,9 @@ constructor(
         val result = lifecycleManager.startServices(dbKey)
         when (result) {
             SUCCESS -> lifecycleManager.waitForStartup()
-            ALREADY_RUNNING -> LOG.info { "Already running" }
+            ALREADY_RUNNING -> LOG.i { "Already running" }
             else -> {
-                LOG.warn { "Startup failed: $result" }
+                LOG.w { "Startup failed: $result" }
                 showError(StartingError(result))
             }
         }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/StrengthMeter.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/StrengthMeter.kt
index 0f980ecbb2c377ab6d23887e7032b9afcfdcc483..681b787b31a3be1ead69a55e87462cebc788f12b 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/login/StrengthMeter.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/StrengthMeter.kt
@@ -39,6 +39,7 @@ val YELLOW = Color(255, 255, 0)
 val LIME = Color(180, 255, 0)
 val GREEN = Color(0, 255, 0)
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "strength" to PreviewUtils.FloatSlider(0f, 0f, 1f)
 ) {
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutDialog.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutDialog.kt
index 4f2355162ab208fc60a3429b0973e49f19a5dccb..91a7d5fcdc0e73b85541a541c2581c20099eedfc 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutDialog.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/AboutDialog.kt
@@ -30,6 +30,7 @@ import java.time.Instant
 import java.time.ZoneId
 import java.time.format.DateTimeFormatter
 
+@Suppress("HardCodedStringLiteral")
 fun main() = preview(
     "visible" to true,
 ) {
@@ -52,14 +53,14 @@ fun AboutDialog(
 
     // rows displayed in table
     val lines = listOf(
-        i18n("about.copyright") to "The Briar Project",
-        i18n("about.license") to "GNU Affero General Public License v3",
+        i18n("about.copyright") to "The Briar Project", // NON-NLS
+        i18n("about.license") to "GNU Affero General Public License v3", // NON-NLS
         i18n("about.version") to BuildData.VERSION,
-        "Git branch" to BuildData.GIT_BRANCH,
-        "Git hash" to BuildData.GIT_HASH,
-        "Commit time" to DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(buildTime),
+        "Git branch" to BuildData.GIT_BRANCH, // NON-NLS
+        "Git hash" to BuildData.GIT_HASH, // NON-NLS
+        "Commit time" to DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(buildTime), // NON-NLS
         i18n("about.website") to "https://briarproject.org",
-        i18n("about.contact") to "desktop@briarproject.org",
+        i18n("about.contact") to "desktop@briarproject.org", // NON-NLS
     )
 
     BriarDialog(onClose = onClose) {
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarLogo.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarLogo.kt
index c2420a45e6ed27ccf90fd1eb280729416471b321..9b860366c692587ca0278ebed13917510ef86302 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarLogo.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarLogo.kt
@@ -27,4 +27,7 @@ import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
 
 @Composable
 fun BriarLogo(modifier: Modifier = Modifier.fillMaxWidth()) =
-    Image(painterResource("images/logo_circle.svg"), i18n("access.logo"), modifier)
+    Image(
+        painterResource("images/logo_circle.svg"), // NON-NLS
+        i18n("access.logo"), modifier
+    )
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
index 2cb889f21b53d0e2c3ea413ef64bf6f51da64355..6236de2c62dc04aadb8bda7c2dff067dc5b0cd7e 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
@@ -111,7 +111,7 @@ constructor(
         Window(
             title = title,
             onCloseRequest = onClose,
-            icon = painterResource("images/logo_circle.svg")
+            icon = painterResource("images/logo_circle.svg") // NON-NLS
         ) {
             window.minimumSize = Dimension(800, 600)
             CompositionLocalProvider(
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/FeatureFlagUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/FeatureFlagUtils.kt
index 69a2c5363b6a156d4665e5086344a9edd4d391bb..fafde86be2153b515347264fa185ddc58dc6fd66 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/FeatureFlagUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/FeatureFlagUtils.kt
@@ -24,10 +24,10 @@ import org.briarproject.briar.desktop.ui.LocalDesktopFeatureFlags
 
 @Composable
 fun getCoreFeatureFlags() = checkNotNull(LocalCoreFeatureFlags.current) {
-    "No FeatureFlags was provided via LocalCoreFeatureFlags"
+    "No FeatureFlags was provided via LocalCoreFeatureFlags" // NON-NLS
 }
 
 @Composable
 fun getDesktopFeatureFlags() = checkNotNull(LocalDesktopFeatureFlags.current) {
-    "No DesktopFeatureFlags was provided via LocalDesktopFeatureFlags"
+    "No DesktopFeatureFlags was provided via LocalDesktopFeatureFlags" // NON-NLS
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/ImagePicker.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/ImagePicker.kt
index 2104fe661ffb3b086dc326fb860bbc87881a8302..33f2d820a91194f19c4f05e3faa3005761810dc3 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/ImagePicker.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/ImagePicker.kt
@@ -22,6 +22,8 @@ import androidx.compose.ui.awt.ComposeWindow
 import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.res.loadImageBitmap
 import mu.KotlinLogging
+import org.briarproject.briar.desktop.utils.KLoggerUtils.d
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import java.io.FileInputStream
 
 object ImagePicker {
@@ -45,7 +47,7 @@ object ImagePicker {
         dialog.isVisible = true
         val files = dialog.files
         val file = if (files == null || files.isEmpty()) null else files[0]
-        LOG.debug { "Loading image from file '$file'" }
+        LOG.d { "Loading image from file '$file'" }
         if (file == null) {
             updateImage(null)
         } else {
@@ -54,7 +56,7 @@ object ImagePicker {
                     loadImageBitmap(it)
                 }
             } catch (e: Throwable) {
-                LOG.warn(e) { "Error while loading image" }
+                LOG.w(e) { "Error while loading image" }
                 null
             }
             updateImage(image)
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/InternationalizationUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/InternationalizationUtils.kt
index 6cc198d4f402a91c549df54b77a3991a937cd8db..0ac3804fb73d673fd6df5b910dcb7c73c57bbc5e 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/InternationalizationUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/InternationalizationUtils.kt
@@ -20,6 +20,7 @@ package org.briarproject.briar.desktop.utils
 
 import com.ibm.icu.text.MessageFormat
 import mu.KotlinLogging
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import java.util.Locale
 import java.util.MissingResourceException
 import java.util.ResourceBundle
@@ -42,7 +43,7 @@ object InternationalizationUtils {
             val resourceBundle = createResourceBundle()
             resourceBundle.getString(key)
         } catch (e: MissingResourceException) {
-            LOG.warn { "Missing string resource for key '$key'" }
+            LOG.w { "Missing string resource for key '$key'" }
             ""
         }
 
@@ -59,7 +60,7 @@ object InternationalizationUtils {
             val messageFormat = MessageFormat(pattern, Locale.getDefault())
             messageFormat.format(arrayOf(amount))
         } catch (e: IllegalArgumentException) {
-            LOG.warn { "Pattern does not match arguments for resource '$key' and locale '${Locale.getDefault()}" }
+            LOG.w { "Pattern does not match arguments for resource '$key' and locale '${Locale.getDefault()}" }
             ""
         }
 
@@ -71,7 +72,7 @@ object InternationalizationUtils {
             val pattern: String = i18n(key)
             java.text.MessageFormat.format(pattern, *params)
         } catch (e: IllegalArgumentException) {
-            LOG.warn { "Pattern does not match arguments for resource '$key'" }
+            LOG.w { "Pattern does not match arguments for resource '$key'" }
             ""
         }
 
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/KLoggerUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/KLoggerUtils.kt
index a201c1efdebe2395b2b4cf6244927999e44254c6..6fab94de0ff8d7fec5a1e15af2314abd43934fca 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/KLoggerUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/KLoggerUtils.kt
@@ -20,11 +20,53 @@ package org.briarproject.briar.desktop.utils
 
 import mu.KLogger
 import org.briarproject.bramble.util.LogUtils
+import org.jetbrains.annotations.NonNls
 
 object KLoggerUtils {
 
+    @NonNls
     fun KLogger.logDuration(task: String, start: Long) {
         val duration = LogUtils.now() - start
-        debug { "$task took $duration ms" }
+        d { "$task took $duration ms" }
+    }
+
+    fun KLogger.t(@NonNls msg: () -> Any?) {
+        trace(msg)
+    }
+
+    fun KLogger.d(@NonNls msg: () -> Any?) {
+        debug(msg)
+    }
+
+    fun KLogger.i(@NonNls msg: () -> Any?) {
+        info(msg)
+    }
+
+    fun KLogger.w(@NonNls msg: () -> Any?) {
+        warn(msg)
+    }
+
+    fun KLogger.e(@NonNls msg: () -> Any?) {
+        error(msg)
+    }
+
+    fun KLogger.t(t: Throwable?, @NonNls msg: () -> Any?) {
+        trace(t, msg)
+    }
+
+    fun KLogger.d(t: Throwable?, @NonNls msg: () -> Any?) {
+        trace(t, msg)
+    }
+
+    fun KLogger.i(t: Throwable?, @NonNls msg: () -> Any?) {
+        trace(t, msg)
+    }
+
+    fun KLogger.w(t: Throwable?, @NonNls msg: () -> Any?) {
+        trace(t, msg)
+    }
+
+    fun KLogger.e(t: Throwable?, @NonNls msg: () -> Any?) {
+        trace(t, msg)
     }
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
index 6e5bc55029bbf847d37683e64f283e69b256bd6f..42fe97ee3d6115e8235b514f164c3edad4dfddab 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
@@ -201,6 +201,7 @@ object PreviewUtils {
      * They can be retrieved as [State] using [PreviewScope.getStringParameter] or similar functions
      * and used inside the composable [content].
      */
+    @Suppress("HardCodedStringLiteral")
     fun preview(
         vararg parameters: Pair<String, Any>,
         content: @Composable PreviewScope.() -> Unit
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ComposeUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ComposeUtils.kt
index 71dee41785978693f6515a5a4c1ea762308e9ebf..aab516b5f773b7fc1f2b4604be5fc17044ced4ea 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ComposeUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ComposeUtils.kt
@@ -47,7 +47,7 @@ import kotlin.reflect.KClass
 inline fun <reified VM : ViewModel> viewModel(
     key: String? = null,
     viewModelProvider: ViewModelProvider = checkNotNull(LocalViewModelProvider.current) {
-        "No ViewModelProvider was provided via LocalViewModelProvider"
+        "No ViewModelProvider was provided via LocalViewModelProvider" // NON-NLS
     }
 ): VM = viewModel(VM::class, key, viewModelProvider)
 
@@ -70,7 +70,7 @@ fun <VM : ViewModel> viewModel(
     modelClass: KClass<VM>,
     key: String? = null,
     viewModelProvider: ViewModelProvider = checkNotNull(LocalViewModelProvider.current) {
-        "No ViewModelProvider was provided via LocalViewModelProvider"
+        "No ViewModelProvider was provided via LocalViewModelProvider" // NON-NLS
     }
 ): VM {
     val viewModel = viewModelProvider.get(modelClass, key)
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/DbViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/DbViewModel.kt
index ea470598f491548889c4606d446165ecf73af314..1a09ad893ce4fb31ecc4c57bc98c027a9a0a34d3 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/DbViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/DbViewModel.kt
@@ -24,6 +24,7 @@ import org.briarproject.bramble.api.db.Transaction
 import org.briarproject.bramble.api.db.TransactionManager
 import org.briarproject.bramble.api.lifecycle.LifecycleManager
 import org.briarproject.briar.desktop.threading.BriarExecutors
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 
 abstract class DbViewModel(
     private val briarExecutors: BriarExecutors,
@@ -46,10 +47,10 @@ abstract class DbViewModel(
             lifecycleManager.waitForDatabase()
             task()
         } catch (e: InterruptedException) {
-            LOG.warn("Interrupted while waiting for database")
+            LOG.w { "Interrupted while waiting for database" }
             Thread.currentThread().interrupt()
         } catch (e: Exception) {
-            LOG.warn(e) { "Unhandled exception in database executor" }
+            LOG.w(e) { "Unhandled exception in database executor" }
         }
     }
 
@@ -73,10 +74,10 @@ abstract class DbViewModel(
                 db.endTransaction(txn)
             }
         } catch (e: InterruptedException) {
-            LOG.warn("Interrupted while waiting for database")
+            LOG.w { "Interrupted while waiting for database" }
             Thread.currentThread().interrupt()
         } catch (e: Exception) {
-            LOG.warn(e) { "Unhandled exception in database executor" }
+            LOG.w(e) { "Unhandled exception in database executor" }
         }
     }
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelFactory.kt b/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelFactory.kt
index 30627865e6b96699a37132ca0d85ae10de48f115..1174d9942277dccd7bec6ba2cc911fcb6b116ede 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelFactory.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/viewmodel/ViewModelFactory.kt
@@ -44,7 +44,7 @@ constructor(
                 }
             }
         }
-        requireNotNull(creator) { "unknown model class $modelClass" }
+        requireNotNull(creator) { "unknown model class $modelClass" } // NON-NLS
         return creator.get() as VM
     }
 }
diff --git a/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt b/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt
index 37d34567d00c846b63003e8e271c674b05aae0cc..d02435170631eeb81ef7709d9c1090ae8ac8a85c 100644
--- a/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt
+++ b/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt
@@ -28,7 +28,9 @@ import org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_CONTROL_PORT
 import org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_SOCKS_PORT
 import org.briarproject.briar.BriarCoreEagerSingletons
 import org.briarproject.briar.desktop.TestUtils.getDataDir
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
 import org.briarproject.briar.desktop.utils.LogUtils
+import org.jetbrains.annotations.NonNls
 import java.util.logging.Level.ALL
 
 internal class RunWithMultipleTemporaryAccounts(
@@ -63,7 +65,7 @@ internal class RunWithMultipleTemporaryAccounts(
 
     private fun app(name: String, socksPort: Int, controlPort: Int): BriarDesktopTestApp {
         val dataDir = getDataDir()
-        LOG.info("Using data directory '$dataDir'")
+        LOG.i { "Using data directory '$dataDir'" }
 
         val app =
             DaggerBriarDesktopTestApp.builder().desktopTestModule(
@@ -71,7 +73,7 @@ internal class RunWithMultipleTemporaryAccounts(
             ).build()
 
         app.getShutdownManager().addShutdownHook {
-            LOG.info("deleting temporary account at $dataDir")
+            LOG.i { "deleting temporary account at $dataDir" }
             org.apache.commons.io.FileUtils.deleteDirectory(dataDir.toFile())
         }
 
@@ -83,6 +85,7 @@ internal class RunWithMultipleTemporaryAccounts(
         val lifecycleManager = app.getLifecycleManager()
         val accountManager = app.getAccountManager()
 
+        @NonNls
         val password = "verySecret123!"
         accountManager.createAccount(name, password)
 
diff --git a/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt b/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt
index 3966a3d10789ceb23f00e2c2452c24f96ad251c4..1b745e495e589ec0775988e4067b0b7bba9cad19 100644
--- a/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt
+++ b/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt
@@ -24,7 +24,9 @@ import mu.KotlinLogging
 import org.briarproject.bramble.BrambleCoreEagerSingletons
 import org.briarproject.briar.BriarCoreEagerSingletons
 import org.briarproject.briar.desktop.TestUtils.getDataDir
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
 import org.briarproject.briar.desktop.utils.LogUtils
+import org.jetbrains.annotations.NonNls
 import java.nio.file.Files
 import java.nio.file.attribute.PosixFilePermissions
 import java.util.logging.Level.ALL
@@ -45,9 +47,10 @@ internal class RunWithTemporaryAccount(
         LogUtils.setupLogging(ALL)
 
         val dataDir = getDataDir()
-        LOG.info { "Using data directory '$dataDir'" }
+        LOG.i { "Using data directory '$dataDir'" }
 
         if (makeDirUnwritable) {
+            @NonNls
             val permissions = PosixFilePermissions.fromString("r--r--r--")
             Files.setPosixFilePermissions(dataDir, permissions)
         }
@@ -58,7 +61,7 @@ internal class RunWithTemporaryAccount(
             ).build()
 
         app.getShutdownManager().addShutdownHook {
-            LOG.info { "deleting temporary account at $dataDir" }
+            LOG.i { "deleting temporary account at $dataDir" }
             org.apache.commons.io.FileUtils.deleteDirectory(dataDir.toFile())
         }
 
@@ -71,6 +74,7 @@ internal class RunWithTemporaryAccount(
         val accountManager = app.getAccountManager()
 
         if (createAccount) {
+            @NonNls
             val password = "verySecret123!"
             accountManager.createAccount("alice", password)
 
diff --git a/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt b/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt
index 4a7a2fd3981abdafb1895105ced773bdb98d62d9..698a59fbba215eecaa68ba7d6710697ee76708cf 100644
--- a/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt
+++ b/src/test/kotlin/org/briarproject/briar/desktop/testdata/DeterministicTestDataCreatorImpl.kt
@@ -58,6 +58,8 @@ import org.briarproject.briar.api.privategroup.PrivateGroupManager
 import org.briarproject.briar.api.test.TestAvatarCreator
 import org.briarproject.briar.desktop.GroupCountHelper
 import org.briarproject.briar.desktop.attachment.media.ImageCompressor
+import org.briarproject.briar.desktop.utils.KLoggerUtils.i
+import org.briarproject.briar.desktop.utils.KLoggerUtils.w
 import java.io.IOException
 import java.io.InputStream
 import java.time.LocalDateTime
@@ -118,7 +120,7 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
                     numPrivateGroupPosts
                 )
             } catch (e: DbException) {
-                LOG.warn(e) { }
+                LOG.w(e) { }
             }
         }
     }
@@ -185,7 +187,7 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
             contactId
         }
         if (random.nextInt(100) + 1 <= avatarPercent) addAvatar(contactId)
-        LOG.info { "Added contact ${remote.name} with transport properties: $props" }
+        LOG.i { "Added contact ${remote.name} with transport properties: $props" }
         localAuthors[contactId] = remote
         return contactId
     }
@@ -292,7 +294,7 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
         val `is`: InputStream = try {
             testAvatarCreator.avatarInputStream
         } catch (e: IOException) {
-            LOG.warn(e) {}
+            LOG.w(e) {}
             return
         } ?: return
         val m: Message = try {
@@ -332,7 +334,7 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
                 createPrivateMessage(contactId, groupId, person.messages[k])
             }
         }
-        LOG.info { "Created $numPrivateMsgs private messages per contact." }
+        LOG.i { "Created $numPrivateMsgs private messages per contact." }
     }
 
     @Throws(DbException::class)
@@ -413,7 +415,7 @@ class DeterministicTestDataCreatorImpl @Inject internal constructor(
             }
             privateGroups.add(privateGroup)
         }
-        LOG.info { "Created ${min(numPrivateGroups, GROUP_NAMES.size)} private groups." }
+        LOG.i { "Created ${min(numPrivateGroups, GROUP_NAMES.size)} private groups." }
         return privateGroups
     }