diff --git a/.editorconfig b/.editorconfig index f76d5403c0a..d92fbddd420 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,15 +2,25 @@ root = true [*] charset = utf-8 -indent_size = 4 indent_style = space +indent_size = 4 +ij_continuation_indent_size = 4 +tab_width = 4 insert_final_newline = true +trim_trailing_whitespace = true end_of_line = lf +max_line_length = 120 [*.{kt,kts}] ij_kotlin_imports_layout = *,^ ij_kotlin_allow_trailing_comma = true ij_kotlin_allow_trailing_comma_on_call_site = true +ktlint_ignore_back_ticked_identifier = true -[*.{yml,yaml,json,toml}] +[*.{yml,yaml,json,toml,md}] indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml index b39c0171f05..0296d668a52 100644 --- a/.github/workflows/markdown.yml +++ b/.github/workflows/markdown.yml @@ -7,20 +7,20 @@ on: - '.github/workflows/markdown.yml' jobs: - markdown_quality: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + markdown_quality: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 - - name: Copy CI gradle.properties - run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties + - name: Copy CI gradle.properties + run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties - - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 17 + - uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 - - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v2 - - name: Quality - Spotless Markdown Check - run: ./gradlew spotlessMarkdownCheck + - name: Quality - Spotless Markdown Check + run: ./gradlew spotlessMarkdownCheck diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt index a6075a51c1a..70791e32638 100644 --- a/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt +++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt @@ -38,10 +38,11 @@ class NotificationHelper( try { notificationManager.notify(notificationId, notification) } catch (e: SecurityException) { - // When importing settings from another device, we could end up with a NotificationChannel that references a - // non-existing notification sound. In that case, we end up with a SecurityException with a message similar - // to this: - // UID 123 does not have permission to content://media/external_primary/audio/media/42?title=Coins&canonical=1 [user 0] + // When importing settings from another device, we could end up with a NotificationChannel that references + // a non-existing notification sound. In that case, we end up with a SecurityException with a message + // similar to this: + // UID 123 does not have permission to + // content://media/external_primary/audio/media/42?title=Coins&canonical=1 [user 0] if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && e.message?.contains("does not have permission to") == true ) { diff --git a/app/core/src/test/java/com/fsck/k9/message/html/GenericUriParserTest.kt b/app/core/src/test/java/com/fsck/k9/message/html/GenericUriParserTest.kt index 9787809c5fe..046c0fb84c1 100644 --- a/app/core/src/test/java/com/fsck/k9/message/html/GenericUriParserTest.kt +++ b/app/core/src/test/java/com/fsck/k9/message/html/GenericUriParserTest.kt @@ -46,7 +46,10 @@ class GenericUriParserTest { assertUriValid("xmpp:example-node@example.com?message") assertUriValid("xmpp:example-node@example.com?message;subject=Hello%20World") assertUriValid("xmpp:nasty!%23\$%25()*+,-.;=%3F%5B%5C%5D%5E_%60%7B%7C%7D~node@example.com") - assertUriValid("xmpp:node@example.com/repulsive%20!%23%22\$%25&'()*+,-.%2F:;%3C=%3E%3F%40%5B%5C%5D%5E_%60%7B%7C%7D~resource") + assertUriValid( + "xmpp:node@example.com/repulsive" + + "%20!%23%22\$%25&'()*+,-.%2F:;%3C=%3E%3F%40%5B%5C%5D%5E_%60%7B%7C%7D~resource", + ) assertUriValid("xmpp:ji%C5%99i@%C4%8Dechy.example/v%20Praze") } diff --git a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo70.kt b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo70.kt index 4fbb0074e02..b149fca7619 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo70.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo70.kt @@ -79,7 +79,13 @@ internal class MigrationTo70(private val db: SQLiteDatabase) { private fun recreateFoldersTriggers() { db.execSQL("DROP TRIGGER IF EXISTS delete_folder") - db.execSQL("CREATE TRIGGER delete_folder BEFORE DELETE ON folders BEGIN DELETE FROM messages WHERE old.id = folder_id; END;") + db.execSQL( + "CREATE TRIGGER delete_folder " + + "BEFORE DELETE ON folders " + + "BEGIN " + + "DELETE FROM messages WHERE old.id = folder_id; " + + "END;", + ) db.execSQL("DROP TRIGGER IF EXISTS delete_folder_extra_values") db.execSQL( diff --git a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt index fdf1623aabe..f3f76661b8e 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt @@ -13,7 +13,8 @@ internal class MigrationTo84(private val db: SQLiteDatabase) { fun rewriteAddresses() { val addressSets = db.rawQuery( - "SELECT id, to_list, cc_list, bcc_list, reply_to_list, sender_list FROM messages WHERE empty = 0 AND deleted = 0", + "SELECT id, to_list, cc_list, bcc_list, reply_to_list, sender_list " + + "FROM messages WHERE empty = 0 AND deleted = 0", null, ).use { cursor -> cursor.map { diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ComposeCryptoStatus.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ComposeCryptoStatus.kt index d2814639ef7..31ae562f5cb 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ComposeCryptoStatus.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ComposeCryptoStatus.kt @@ -7,7 +7,6 @@ import com.fsck.k9.message.AutocryptStatusInteractor import com.fsck.k9.message.AutocryptStatusInteractor.RecipientAutocryptStatus import com.fsck.k9.message.CryptoStatus import com.fsck.k9.view.RecipientSelectView.Recipient -import org.openintents.openpgp.OpenPgpApiManager import org.openintents.openpgp.OpenPgpApiManager.OpenPgpProviderState /** This is an immutable object which contains all relevant metadata entered @@ -76,10 +75,10 @@ data class ComposeCryptoStatus( val recipientAddressesAsArray = recipientAddresses.toTypedArray() private val displayTypeFromProviderError = when (openPgpProviderState) { - OpenPgpApiManager.OpenPgpProviderState.OK -> null - OpenPgpApiManager.OpenPgpProviderState.UNCONFIGURED -> CryptoStatusDisplayType.UNCONFIGURED - OpenPgpApiManager.OpenPgpProviderState.UNINITIALIZED -> CryptoStatusDisplayType.UNINITIALIZED - OpenPgpApiManager.OpenPgpProviderState.ERROR, OpenPgpApiManager.OpenPgpProviderState.UI_REQUIRED -> CryptoStatusDisplayType.ERROR + OpenPgpProviderState.OK -> null + OpenPgpProviderState.UNCONFIGURED -> CryptoStatusDisplayType.UNCONFIGURED + OpenPgpProviderState.UNINITIALIZED -> CryptoStatusDisplayType.UNINITIALIZED + OpenPgpProviderState.ERROR, OpenPgpProviderState.UI_REQUIRED -> CryptoStatusDisplayType.ERROR } private val displayTypeFromAutocryptError = when (recipientAutocryptStatusType) { diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt index efc2931ebea..b7af7ac50fd 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt @@ -198,8 +198,8 @@ class MessageViewFragment : if (menuVisible) { messageLoaderHelper.resumeCryptoOperationIfNecessary() } else { - // When the menu is hidden, the message associated with this fragment is no longer active. If the user returns - // to it, we want to mark the message as opened again. + // When the menu is hidden, the message associated with this fragment is no longer active. If the user + // returns to it, we want to mark the message as opened again. wasMessageMarkedAsOpened = false } } diff --git a/backend/jmap/src/main/java/com/fsck/k9/backend/jmap/JmapBackend.kt b/backend/jmap/src/main/java/com/fsck/k9/backend/jmap/JmapBackend.kt index 8a18c3dce81..e4108c1e197 100644 --- a/backend/jmap/src/main/java/com/fsck/k9/backend/jmap/JmapBackend.kt +++ b/backend/jmap/src/main/java/com/fsck/k9/backend/jmap/JmapBackend.kt @@ -94,7 +94,11 @@ class JmapBackend( return messageServerIds.associateWith { it } } - override fun moveMessagesAndMarkAsRead(sourceFolderServerId: String, targetFolderServerId: String, messageServerIds: List): Map? { + override fun moveMessagesAndMarkAsRead( + sourceFolderServerId: String, + targetFolderServerId: String, + messageServerIds: List, + ): Map? { commandMove.moveMessagesAndMarkAsRead(targetFolderServerId, messageServerIds) return messageServerIds.associateWith { it } } diff --git a/config/detekt/detekt-baseline-app-core.xml b/config/detekt/detekt-baseline-app-core.xml index 3c270a4d5da..5aeacc0b941 100644 --- a/config/detekt/detekt-baseline-app-core.xml +++ b/config/detekt/detekt-baseline-app-core.xml @@ -84,8 +84,6 @@ MagicNumber:ServerSettingsSerializer.kt$ServerSettingsAdapter$7 MagicNumber:SettingsExporter.kt$SettingsExporter$3 MagicNumber:TimberLogger.kt$TimberLogger$26 - MaxLineLength:GenericUriParserTest.kt$GenericUriParserTest$assertUriValid("xmpp:node@example.com/repulsive%20!%23%22\$%25&'()*+,-.%2F:;%3C=%3E%3F%40%5B%5C%5D%5E_%60%7B%7C%7D~resource") - MaxLineLength:NotificationHelper.kt$NotificationHelper$// UID 123 does not have permission to content://media/external_primary/audio/media/42?title=Coins&canonical=1 [user 0] MayBeConst:SummaryNotificationDataCreatorTest.kt$private val TIMESTAMP = 0L MemberNameEqualsClassName:HtmlModification.kt$HtmlModification.Replace$abstract fun replace(textToHtml: TextToHtml) NestedBlockDepth:HttpUriParser.kt$HttpUriParser$private fun tryMatchIpv6Address(text: CharSequence, startPos: Int): Int diff --git a/config/detekt/detekt-baseline-app-storage.xml b/config/detekt/detekt-baseline-app-storage.xml index 5f5116ac091..66da340b59d 100644 --- a/config/detekt/detekt-baseline-app-storage.xml +++ b/config/detekt/detekt-baseline-app-storage.xml @@ -103,8 +103,6 @@ MagicNumber:StorageMigrationTo17.kt$StorageMigrationTo17$0xFFFF00 MagicNumber:StorageMigrationTo17.kt$StorageMigrationTo17$0xFFFFFF MagicNumber:ThreadMessageOperations.kt$ThreadMessageOperations$3 - MaxLineLength:MigrationTo70.kt$MigrationTo70$db.execSQL("CREATE TRIGGER delete_folder BEFORE DELETE ON folders BEGIN DELETE FROM messages WHERE old.id = folder_id; END;") - MaxLineLength:MigrationTo84.kt$MigrationTo84$"SELECT id, to_list, cc_list, bcc_list, reply_to_list, sender_list FROM messages WHERE empty = 0 AND deleted = 0" MaxLineLength:RetrieveMessageListOperationsTest.kt$RetrieveMessageListOperationsTest$fun ReturnCount:SaveMessageOperationsTest.kt$SaveMessageOperationsTest$private fun Message.getDownloadState(): MessageDownloadState ReturnCount:StorageMigrationTo19.kt$StorageMigrationTo19$private fun markIfGmailAccount(accountUuid: String) diff --git a/config/detekt/detekt-baseline-app-ui-legacy.xml b/config/detekt/detekt-baseline-app-ui-legacy.xml index e474d742a4b..731859edb3b 100644 --- a/config/detekt/detekt-baseline-app-ui-legacy.xml +++ b/config/detekt/detekt-baseline-app-ui-legacy.xml @@ -82,14 +82,10 @@ MagicNumber:SizeFormatter.kt$SizeFormatter$1_000_000L MagicNumber:SizeFormatter.kt$SizeFormatter$999_950L MagicNumber:SizeFormatter.kt$SizeFormatter$999_950_000L - MaxLineLength:ComposeCryptoStatus.kt$ComposeCryptoStatus$OpenPgpApiManager.OpenPgpProviderState.ERROR, OpenPgpApiManager.OpenPgpProviderState.UI_REQUIRED -> CryptoStatusDisplayType.ERROR - MaxLineLength:MessageViewFragment.kt$MessageViewFragment$// When the menu is hidden, the message associated with this fragment is no longer active. If the user returns MemberNameEqualsClassName:ReplyToView.kt$ReplyToView$private val replyToView: RecipientSelectView = activity.findViewById(R.id.reply_to) NestedBlockDepth:MessageList.kt$MessageList$override fun onBackPressed() NestedBlockDepth:MessageList.kt$MessageList$override fun onOptionsItemSelected(item: MenuItem): Boolean NestedBlockDepth:MessageList.kt$MessageList$private fun decodeExtrasToLaunchData(intent: Intent): LaunchData - ReturnCount:AccountSetupBasics.kt$AccountSetupBasics$private fun providersXmlDiscoveryDiscover(email: String): ConnectionSettings? - ReturnCount:AccountSetupBasics.kt$private fun DiscoveredServerSettings.toServerSettings(): ServerSettings? ReturnCount:AccountSetupCheckSettings.kt$AccountSetupCheckSettings.CheckAccountTask$private fun isCanceled(): Boolean ReturnCount:ChooseFolderActivity.kt$ChooseFolderActivity$private fun decodeArguments(savedInstanceState: Bundle?): Boolean ReturnCount:EditIdentity.kt$EditIdentity$override fun onOptionsItemSelected(item: MenuItem): Boolean @@ -162,7 +158,6 @@ TooGenericExceptionThrown:MessageViewFragment.kt$MessageViewFragment$throw RuntimeException("Called showDialog(int) with unknown dialog id.") TooManyFunctions:AccountSettingsDataStore.kt$AccountSettingsDataStore : PreferenceDataStore TooManyFunctions:AccountSettingsFragment.kt$AccountSettingsFragment : PreferenceFragmentCompatConfirmationDialogFragmentListener - TooManyFunctions:AccountSetupBasics.kt$AccountSetupBasics : K9Activity TooManyFunctions:AccountSetupCheckSettings.kt$AccountSetupCheckSettings : K9ActivityConfirmationDialogFragmentListener TooManyFunctions:AuthViewModel.kt$AuthViewModel : AndroidViewModel TooManyFunctions:AutocryptKeyTransferActivity.kt$AutocryptKeyTransferActivity : K9Activity diff --git a/config/detekt/detekt-baseline-backend-jmap.xml b/config/detekt/detekt-baseline-backend-jmap.xml index f18f71ace92..d346c12bd16 100644 --- a/config/detekt/detekt-baseline-backend-jmap.xml +++ b/config/detekt/detekt-baseline-backend-jmap.xml @@ -3,7 +3,6 @@ ForbiddenComment:CommandSync.kt$CommandSync$// FIXME: Add sort parameter - MaxLineLength:JmapBackend.kt$JmapBackend$override ReturnCount:JmapAccountDiscovery.kt$JmapAccountDiscovery$fun discover(emailAddress: String, password: String): JmapDiscoveryResult SwallowedException:JmapAccountDiscovery.kt$JmapAccountDiscovery$e: EndpointNotFoundException SwallowedException:JmapAccountDiscovery.kt$JmapAccountDiscovery$e: UnauthorizedException diff --git a/config/detekt/detekt-baseline-mail-common.xml b/config/detekt/detekt-baseline-mail-common.xml index 5a365642a5c..2f5d4fe9bb2 100644 --- a/config/detekt/detekt-baseline-mail-common.xml +++ b/config/detekt/detekt-baseline-mail-common.xml @@ -51,7 +51,6 @@ MagicNumber:Utf8.kt$3 MagicNumber:Utf8.kt$4 MagicNumber:Utf8.kt$6 - MaxLineLength:BoundaryGeneratorTest.kt$BoundaryGeneratorTest$0 ReturnCount:DecoderUtil.kt$DecoderUtil$@JvmStatic fun decodeEncodedWords(body: String, message: Message?): String ReturnCount:DecoderUtil.kt$DecoderUtil$private fun extractEncodedWord(body: String, begin: Int, end: Int, message: Message?): EncodedWord? ReturnCount:FormatFlowedHelper.kt$FormatFlowedHelper$@JvmStatic fun checkFormatFlowed(contentTypeHeaderValue: String?): FormatFlowedResult diff --git a/config/detekt/detekt-baseline-mail-protocols-imap.xml b/config/detekt/detekt-baseline-mail-protocols-imap.xml index 3c75575048a..ac9ca7582da 100644 --- a/config/detekt/detekt-baseline-mail-protocols-imap.xml +++ b/config/detekt/detekt-baseline-mail-protocols-imap.xml @@ -39,7 +39,6 @@ MagicNumber:RealImapFolder.kt$RealImapFolder$9 MagicNumber:UidValidityResponse.kt$UidValidityResponse.Companion$0xFFFFFFFFL MaxLineLength:RealImapFolder.kt$RealImapFolder$// [MESSAGE, RFC822, [NAME, Fwd: [#HTR-517941]: update plans at 1am Friday - Memory allocation - displayware.eml], NIL, NIL, 7BIT, 5974, NIL, [INLINE, [FILENAME*0, Fwd: [#HTR-517941]: update plans at 1am Friday - Memory all, FILENAME*1, ocation - displayware.eml]], NIL] - MaxLineLength:RealImapFolder.kt$RealImapFolder$val canCreateForwardedFlag = canCreateKeywords || internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED) MaxLineLength:RealImapStoreTest.kt$RealImapStoreTest$fun NestedBlockDepth:RealImapFolder.kt$RealImapFolder$@Throws(MessagingException::class) override fun appendMessages(messages: List<Message>): Map<String, String>? NestedBlockDepth:RealImapFolder.kt$RealImapFolder$@Throws(MessagingException::class) override fun fetch( messages: List<ImapMessage>, fetchProfile: FetchProfile, listener: FetchListener?, maxDownloadSize: Int, ) diff --git a/core/ui/compose/common/src/main/kotlin/app/k9mail/core/ui/compose/common/mvi/UnidirectionalViewModel.kt b/core/ui/compose/common/src/main/kotlin/app/k9mail/core/ui/compose/common/mvi/UnidirectionalViewModel.kt index fb8f9685adf..5384671276d 100644 --- a/core/ui/compose/common/src/main/kotlin/app/k9mail/core/ui/compose/common/mvi/UnidirectionalViewModel.kt +++ b/core/ui/compose/common/src/main/kotlin/app/k9mail/core/ui/compose/common/mvi/UnidirectionalViewModel.kt @@ -135,7 +135,9 @@ inline fun UnidirectionalViewModel UnidirectionalViewModel.observeWithoutEffect(): StateDispatch { +inline fun UnidirectionalViewModel.observeWithoutEffect( + // no effect handler +): StateDispatch { val collectedState = state.collectAsStateWithLifecycle() val dispatch: (EVENT) -> Unit = { event(it) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e599691663f..82512ae56fe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -48,7 +48,7 @@ ksp = "com.google.devtools.ksp:1.9.10-1.0.13" kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -spotless = "com.diffplug.spotless:6.21.0" +spotless = "com.diffplug.spotless:6.22.0" detekt = "io.gitlab.arturbosch.detekt:1.23.0" dependency-check = "com.github.ben-manes.versions:0.48.0" diff --git a/mail/common/src/test/java/com/fsck/k9/mail/BoundaryGeneratorTest.kt b/mail/common/src/test/java/com/fsck/k9/mail/BoundaryGeneratorTest.kt index 8b8731555c9..663586351c5 100644 --- a/mail/common/src/test/java/com/fsck/k9/mail/BoundaryGeneratorTest.kt +++ b/mail/common/src/test/java/com/fsck/k9/mail/BoundaryGeneratorTest.kt @@ -19,9 +19,10 @@ class BoundaryGeneratorTest { @Test fun generateBoundary() { - val random = createRandom( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 35, - ) + val seed = IntRange(0, 28).toList().toIntArray() + + val random = createRandom(*seed, 35) + val boundaryGenerator = BoundaryGenerator(random) val result = boundaryGenerator.generateBoundary() diff --git a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt index a80d0ec3fec..4007b644e4d 100644 --- a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt +++ b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt @@ -970,9 +970,12 @@ internal class RealImapFolder( val encodeFolderName = folderNameCodec.encode(prefixedName) val escapedFolderName = ImapUtility.encodeString(encodeFolderName) + val canCreateForwardedFlag = canCreateKeywords || + internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED) + val combinedFlags = ImapUtility.combineFlags( message.flags, - canCreateKeywords || internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED), + canCreateForwardedFlag, ) val command = String.format( Locale.US, @@ -1101,7 +1104,9 @@ internal class RealImapFolder( open(OpenMode.READ_WRITE) checkOpen() - val canCreateForwardedFlag = canCreateKeywords || internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED) + val canCreateForwardedFlag = canCreateKeywords || + internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED) + try { val combinedFlags = ImapUtility.combineFlags(flags, canCreateForwardedFlag) val command = String.format( @@ -1123,7 +1128,8 @@ internal class RealImapFolder( checkOpen() val uids = messages.map { it.uid.toLong() }.toSet() - val canCreateForwardedFlag = canCreateKeywords || internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED) + val canCreateForwardedFlag = canCreateKeywords || + internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED) val combinedFlags = ImapUtility.combineFlags(flags, canCreateForwardedFlag) val commandSuffix = String.format("%sFLAGS.SILENT (%s)", if (value) "+" else "-", combinedFlags) try {