package net.bjoernpetersen.musicbot.api.config

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.DynamicTest
import org.junit.jupiter.api.DynamicTest.dynamicTest
import org.junit.jupiter.api.TestFactory
import org.junit.jupiter.api.assertThrows
import java.io.File
import java.nio.file.Paths

private val path = "example${File.separator}file${File.separator}path"

class ConfigSerializerTest {
    @TestFactory
    fun serialization(): List<DynamicTest> {
        return listOf(
            (42 to "42") with IntSerializer,
            (File(path) to path) with FileSerializer,
            (Paths.get(path) to path) with PathSerializer
        ).map { pair ->
            dynamicTest("to ${pair.serializedValue}") {
                assertEquals(pair.serializedValue, pair.serialize())
            }
        }
    }

    @TestFactory
    fun `invalid int deserialization`(): List<DynamicTest> {
        return listOf("", " ", "abc", "1a", "1,2", "1.2", "1.2.3", "1a2")
            .map {
                dynamicTest("for value $it") {
                    assertThrows<SerializationException> {
                        IntSerializer.deserialize("abc")
                    }
                }
            }
    }

    @TestFactory
    fun deserialization(): List<DynamicTest> {
        return listOf(
            (42 to "42") with IntSerializer,
            (File(path) to path) with FileSerializer,
            (Paths.get(path) to path) with PathSerializer
        ).map { pair ->
            dynamicTest("of ${pair.serializedValue}") {
                assertEquals(pair.value, pair.deserialize())
            }
        }
    }
}

private infix fun <T> Pair<T, String>.with(other: ConfigSerializer<T>): SerializationPair<T> =
    SerializationPair(first, second, other)

private data class SerializationPair<T>(
    val value: T,
    val serializedValue: String,
    val serializer: ConfigSerializer<T>
) {
    fun serialize(): String {
        return serializer.serialize(value)
    }

    fun deserialize(): T {
        return serializer.deserialize(serializedValue)
    }
}


/*
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.script.lang.kotlin.support

import org.gradle.configuration.ImportsReader

/**
 * Holds the list of imports implicitly added to every Kotlin build script.
 */
class ImplicitImports(private val importsReader: ImportsReader) {

    val list by lazy {
        gradleImports() + gradleScriptKotlinImports()
    }

    private
    fun gradleImports() = importsReader.importPackages.map { "$it.*" }

    private
    fun gradleScriptKotlinImports() =
        listOf(
            "org.gradle.script.lang.kotlin.*",
            // TODO: infer list of types below at build time by inspecting the Gradle API
            "java.util.concurrent.TimeUnit",
            "java.math.BigDecimal",
            "java.io.File")
}

Add org.gradle.kotlin.dsl.* to implicit imports

/*
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.script.lang.kotlin.support

import org.gradle.configuration.ImportsReader

/**
 * Holds the list of imports implicitly added to every Kotlin build script.
 */
class ImplicitImports(private val importsReader: ImportsReader) {

    val list by lazy {
        gradleImports() + gradleScriptKotlinImports()
    }

    private
    fun gradleImports() = importsReader.importPackages.map { "$it.*" }

    private
    fun gradleScriptKotlinImports() =
        listOf(
            "org.gradle.kotlin.dsl.*",
            "org.gradle.script.lang.kotlin.*", // TODO:pm REMOVE ME
            // TODO: infer list of types below at build time by inspecting the Gradle API
            "java.util.concurrent.TimeUnit",
            "java.math.BigDecimal",
            "java.io.File")
}


/*
 * Copyright 2017 Peter Kenji Yamanaka
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.pyamsoft.pydroid.about

import com.pyamsoft.pydroid.presenter.SchedulerPresenter
import io.reactivex.Scheduler
import timber.log.Timber

class AboutLibrariesPresenter(private val interactor: AboutLibrariesInteractor,
    observeScheduler: Scheduler, subscribeScheduler: Scheduler) : SchedulerPresenter(
    observeScheduler, subscribeScheduler) {

  fun loadLicenses(onLicenseLoaded: (AboutLibrariesModel) -> Unit, onAllLoaded: () -> Unit) {
    disposeOnDestroy(interactor.loadLicenses().subscribeOn(subscribeScheduler).observeOn(
        observeScheduler).doAfterTerminate { onAllLoaded() }.subscribe({ onLicenseLoaded(it) },
        { Timber.e(it, "onError loading licenses") }))
  }
}

Change presenter method to inline

/*
 * Copyright 2017 Peter Kenji Yamanaka
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.pyamsoft.pydroid.about

import com.pyamsoft.pydroid.presenter.SchedulerPresenter
import io.reactivex.Scheduler
import timber.log.Timber

class AboutLibrariesPresenter(private val interactor: AboutLibrariesInteractor,
    observeScheduler: Scheduler, subscribeScheduler: Scheduler) : SchedulerPresenter(
    observeScheduler, subscribeScheduler) {

  fun loadLicenses(onLicenseLoaded: (AboutLibrariesModel) -> Unit, onAllLoaded: () -> Unit) {
    disposeOnDestroy {
      interactor.loadLicenses().subscribeOn(subscribeScheduler).observeOn(
          observeScheduler).doAfterTerminate { onAllLoaded() }.subscribe({ onLicenseLoaded(it) },
          { Timber.e(it, "onError loading licenses") })
    }
  }
}


Implement node selection dsl for test usage

package org.jetbrains.dokka.tests

import org.jetbrains.dokka.DocumentationNode
import org.jetbrains.dokka.NodeKind
import org.jetbrains.dokka.RefKind

class SelectBuilder {
    private val root = ChainFilterNode(SubgraphTraverseFilter(), null)
    private var activeNode = root
    private val chainEnds = mutableListOf<SelectFilter>()

    fun withName(name: String) = matching { it.name == name }

    fun withKind(kind: NodeKind) = matching{ it.kind == kind }

    fun matching(block: (DocumentationNode) -> Boolean) {
        attachFilterAndMakeActive(PredicateFilter(block))
    }

    fun subgraph() {
        attachFilterAndMakeActive(SubgraphTraverseFilter())
    }

    fun subgraphOf(kind: RefKind) {
        attachFilterAndMakeActive(DirectEdgeFilter(kind))
    }

    private fun attachFilterAndMakeActive(next: SelectFilter) {
        activeNode = ChainFilterNode(next, activeNode)
    }

    private fun endChain() {
        chainEnds += activeNode
    }

    fun build(): SelectFilter {
        endChain()
        return CombineFilterNode(chainEnds)
    }
}

private class ChainFilterNode(val filter: SelectFilter, val previous: SelectFilter?): SelectFilter() {
    override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
        return filter.select(previous?.select(roots) ?: roots)
    }
}

private class CombineFilterNode(val previous: List<SelectFilter>): SelectFilter() {
    override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
        return previous.asSequence().flatMap { it.select(roots) }
    }
}

abstract class SelectFilter {
    abstract fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode>
}

private class SubgraphTraverseFilter: SelectFilter() {
    override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
        val visited = mutableSetOf<DocumentationNode>()
        return roots.flatMap {
            generateSequence(listOf(it)) { nodes ->
                nodes.flatMap { it.allReferences() }
                    .map { it.to }
                    .filter { visited.add(it) }
                    .takeUnless { it.isEmpty() }
            }
        }.flatten()
    }

}

private class PredicateFilter(val condition: (DocumentationNode) -> Boolean): SelectFilter() {
    override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
        return roots.filter(condition)
    }
}

private class DirectEdgeFilter(val kind: RefKind): SelectFilter() {
    override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
        return roots.flatMap { it.references(kind).asSequence() }.map { it.to }
    }
}

fun selectNodes(root: DocumentationNode, block: SelectBuilder.() -> Unit): List<DocumentationNode> {
    val builder = SelectBuilder()
    builder.apply(block)
    return builder.build().select(sequenceOf(root)).toMutableSet().toList()
}


package com.seventh_root.guildfordgamejam.desktop

import com.badlogic.gdx.backends.lwjgl.LwjglApplication
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
import com.seventh_root.guildfordgamejam.GuildfordGameJam

fun main(arg: Array<String>) {
    val config = LwjglApplicationConfiguration()
    config.width = 1280
    config.height = 720
    config.fullscreen = false
    LwjglApplication(GuildfordGameJam(), config)
}

Make game start in full screen mode

package com.seventh_root.guildfordgamejam.desktop

import com.badlogic.gdx.backends.lwjgl.LwjglApplication
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
import com.seventh_root.guildfordgamejam.GuildfordGameJam
import java.awt.GraphicsEnvironment

fun main(arg: Array<String>) {
    val config = LwjglApplicationConfiguration()
    val graphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice
    config.width = graphicsDevice.displayMode.width
    config.height = graphicsDevice.displayMode.height
    config.fullscreen = true
    LwjglApplication(GuildfordGameJam(), config)
}


/*
 * Copyright (C) 2021 Reece H. Dunn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.co.reecedunn.intellij.plugin.xpath.lang.refactoring

import com.intellij.lang.refactoring.RefactoringSupportProvider
import com.intellij.psi.PsiElement

class XPathRefactoringSupportProvider : RefactoringSupportProvider() {
    /**
     * Determines whether VariableInplaceRenameHandler should be used.
     */
    override fun isInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean {
        return false
    }

    /**
     * Determines whether MemberInplaceRenameHandler should be used.
     */
    override fun isMemberInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean {
        return false
    }

    /**
     * Determines whether SafeDeleteProcessor should be used.
     */
    override fun isSafeDeleteAvailable(element: PsiElement): Boolean {
        return false
    }
}

Use VariableInplaceRenameHandler for XpmVariableDefinition elements.

/*
 * Copyright (C) 2021 Reece H. Dunn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.co.reecedunn.intellij.plugin.xpath.lang.refactoring

import com.intellij.lang.refactoring.RefactoringSupportProvider
import com.intellij.psi.PsiElement
import uk.co.reecedunn.intellij.plugin.xpm.optree.variable.XpmVariableDefinition

class XPathRefactoringSupportProvider : RefactoringSupportProvider() {
    /**
     * Determines whether VariableInplaceRenameHandler should be used.
     */
    override fun isInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean {
        return element.parent is XpmVariableDefinition
    }

    /**
     * Determines whether MemberInplaceRenameHandler should be used.
     */
    override fun isMemberInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean {
        return false
    }

    /**
     * Determines whether SafeDeleteProcessor should be used.
     */
    override fun isSafeDeleteAvailable(element: PsiElement): Boolean {
        return false
    }
}


package com.livefront.bridgesample.app

import android.app.Application
import android.os.Bundle
import com.evernote.android.state.StateSaver
import com.livefront.bridge.Bridge
import com.livefront.bridge.SavedStateHandler

class BridgeSampleApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Bridge.initialize(
                this,
                object : SavedStateHandler {
                    override fun saveInstanceState(target: Any, state: Bundle) {
                        StateSaver.saveInstanceState(target, state)
                    }

                    override fun restoreInstanceState(target: Any, state: Bundle?) {
                        StateSaver.restoreInstanceState(target, state)
                    }
                }
        )
    }
}

Allow the sample app to save the state of Views

package com.livefront.bridgesample.app

import android.app.Application
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import com.evernote.android.state.StateSaver
import com.livefront.bridge.Bridge
import com.livefront.bridge.SavedStateHandler
import com.livefront.bridge.ViewSavedStateHandler

class BridgeSampleApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Bridge.initialize(
                this,
                object : SavedStateHandler {
                    override fun saveInstanceState(target: Any, state: Bundle) {
                        StateSaver.saveInstanceState(target, state)
                    }

                    override fun restoreInstanceState(target: Any, state: Bundle?) {
                        StateSaver.restoreInstanceState(target, state)
                    }
                },
                object : ViewSavedStateHandler {
                    override fun <T : View> saveInstanceState(
                        target: T,
                        parentState: Parcelable?
                    ): Parcelable = StateSaver.saveInstanceState(target, parentState)

                    override fun <T : View> restoreInstanceState(
                        target: T,
                        state: Parcelable?
                    ): Parcelable? = StateSaver.restoreInstanceState(target, state)
                }
        )
    }
}


pluginManagement {
    repositories {
        gradlePluginPortal()
    }
    plugins {
        id("com.diffplug.eclipse.apt") version "3.36.1"
        id("com.diffplug.spotless") version "6.4.2"
        id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
        id("net.researchgate.release") version "2.8.1"
        id("org.seasar.doma.compile") version "1.1.0"
        kotlin("jvm") version "1.6.21"
        kotlin("kapt") version "1.6.21"
    }
}

rootProject.name = "doma"

include("doma-core")
include("doma-kotlin")
include("doma-mock")
include("doma-processor")
include("doma-slf4j")

include("integration-test-common")
include("integration-test-java")
include("integration-test-java-latest")
include("integration-test-kotlin")

Update plugin com.diffplug.eclipse.apt to v3.36.2

pluginManagement {
    repositories {
        gradlePluginPortal()
    }
    plugins {
        id("com.diffplug.eclipse.apt") version "3.36.2"
        id("com.diffplug.spotless") version "6.4.2"
        id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
        id("net.researchgate.release") version "2.8.1"
        id("org.seasar.doma.compile") version "1.1.0"
        kotlin("jvm") version "1.6.21"
        kotlin("kapt") version "1.6.21"
    }
}

rootProject.name = "doma"

include("doma-core")
include("doma-kotlin")
include("doma-mock")
include("doma-processor")
include("doma-slf4j")

include("integration-test-common")
include("integration-test-java")
include("integration-test-java-latest")
include("integration-test-kotlin")


pluginManagement {
    repositories {
        gradlePluginPortal()
    }
    plugins {
        id("com.diffplug.eclipse.apt") version "3.36.0"
        id("com.diffplug.spotless") version "6.4.1"
        id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
        id("net.researchgate.release") version "2.8.1"
        id("org.seasar.doma.compile") version "1.1.0"
        kotlin("jvm") version "1.6.20"
        kotlin("kapt") version "1.6.20"
    }
}

rootProject.name = "doma"

include("doma-core")
include("doma-kotlin")
include("doma-mock")
include("doma-processor")
include("doma-slf4j")

include("integration-test-common")
include("integration-test-java")
include("integration-test-java-latest")
include("integration-test-kotlin")

Update plugin com.diffplug.spotless to v6.4.2

pluginManagement {
    repositories {
        gradlePluginPortal()
    }
    plugins {
        id("com.diffplug.eclipse.apt") version "3.36.0"
        id("com.diffplug.spotless") version "6.4.2"
        id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
        id("net.researchgate.release") version "2.8.1"
        id("org.seasar.doma.compile") version "1.1.0"
        kotlin("jvm") version "1.6.20"
        kotlin("kapt") version "1.6.20"
    }
}

rootProject.name = "doma"

include("doma-core")
include("doma-kotlin")
include("doma-mock")
include("doma-processor")
include("doma-slf4j")

include("integration-test-common")
include("integration-test-java")
include("integration-test-java-latest")
include("integration-test-kotlin")


Add coroutines friendly LazyRoom class + extension

package com.louiscad.splittiessample.extensions.room

import android.arch.persistence.room.RoomDatabase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import splitties.arch.room.DbConfig
import splitties.arch.room.roomDb

inline fun <reified DB : RoomDatabase> roomDataBase(
    name: String,
    crossinline config: DbConfig<DB> = {}
): LazyRoom<DB> = LazyRoom(lazy { roomDb(name, config) })

class LazyRoom<T : RoomDatabase> @PublishedApi internal constructor(private val lazyDb: Lazy<T>) {
    suspend operator fun invoke(): T = with(lazyDb) {
        if (isInitialized()) value else withContext(Dispatchers.IO) { value }
    }
}


Add init script to be used on CI to enable build scans

/*
 * This is an init script for internal usage at Gradle Inc.
 */
if (!gradle.startParameter.systemPropertiesArgs.containsKey("disableScanPlugin")) {
    rootProject {
        pluginManager.withPlugin("com.gradle.build-scan") {
            extensions["buildScan"].withGroovyBuilder {
                "publishAlways"()
                setProperty("server", "https://e.grdev.net")
            }
        }
    }
}


package com.eden.orchid.writersblocks.tags

import com.eden.orchid.impl.generators.HomepageGenerator
import com.eden.orchid.strikt.asHtml
import com.eden.orchid.strikt.innerHtmlMatches
import com.eden.orchid.strikt.pageWasRendered
import com.eden.orchid.strikt.select
import com.eden.orchid.testhelpers.OrchidIntegrationTest
import com.eden.orchid.testhelpers.withGenerator
import com.eden.orchid.writersblocks.WritersBlocksModule
import kotlinx.html.div
import kotlinx.html.iframe
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import strikt.api.expectThat

class SpotifyTagTest : OrchidIntegrationTest(withGenerator<HomepageGenerator>(), WritersBlocksModule()) {

    @Test
    @DisplayName("Test Spotify tag as track embed")
    fun test01() {

        resource(
            "homepage.md",
            """
            |---
            |---
            |{% spotify type='track' id='0Vkk4vLcrUTYODEiuV9ECP' %}
            """.trimMargin()
        )

        expectThat(execute())
            .pageWasRendered("/index.html") {
                get { content }
                    .toString()
                    .contains("<div class=\"spotify-embed\">")
/*
                    .asHtml()
                    .select("div") { // HOW TO select on div with "spotify-embed" class attribute?
                        innerHtmlMatches() {
                            div {
                                // This doesn't compile - how do you specify multiple attributes on a HTML tag?
                                // iframe(src = "https://open.spotify.com/embed/track/0Vkk4vLcrUTYODEiuV9ECP", allow = "encrypted-media") {}
                                iframe {}
                            }
                        }
                    }
*/
            }
    }
}

Update PR to be based off master

package com.eden.orchid.writersblocks.tags

import com.eden.orchid.impl.generators.HomepageGenerator
import com.eden.orchid.testhelpers.OrchidIntegrationTest
import com.eden.orchid.testhelpers.TestGeneratorModule
import com.eden.orchid.testhelpers.pageWasRendered
import com.eden.orchid.writersblocks.WritersBlocksModule
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import strikt.api.expectThat

class SpotifyTagTest : OrchidIntegrationTest(
    TestGeneratorModule(HomepageGenerator::class.java),
    WritersBlocksModule()
) {

    @Test
    @DisplayName("Test Spotify tag as track embed")
    fun test01() {
        resource(
            "homepage.md",
            """
            |---
            |---
            |{% spotify type='track' id='0Vkk4vLcrUTYODEiuV9ECP' %}
            """.trimMargin()
        )

        expectThat(execute())
            .pageWasRendered("//index.html")
            .get { content }
            .toString()
            .contains("<div class=\"spotify-embed\">")
    }
}


import org.apollo.cache.def.ItemDefinition
import org.apollo.cache.def.NpcDefinition
import org.apollo.cache.def.ObjectDefinition
import org.apollo.game.model.entity.setting.PrivilegeLevel

on_command("iteminfo", PrivilegeLevel.ADMINISTRATOR)
        .then { player ->
            if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::npcinfo [npc id]")) {
                return@then
            }

            val id = arguments[0].toInt()
            val definition = ItemDefinition.lookup(id)
            val members = if (definition.isMembersOnly) "members" else "not members"

            player.sendMessage("Item $id is called ${definition.name}, is $members only, and has a " +
                    "team of ${definition.team}.")
            player.sendMessage("Its description is \"${definition.description}\".")
        }

on_command("npcinfo", PrivilegeLevel.ADMINISTRATOR)
        .then { player ->
            if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::npcinfo [npc id]")) {
                return@then
            }

            val id = arguments[0].toInt()
            val definition = NpcDefinition.lookup(id)
            val isCombative = if (definition.hasCombatLevel()) "has a combat level of ${definition.combatLevel}" else
                "does not have a combat level"

            player.sendMessage("Npc $id is called ${definition.name} and $isCombative.")
            player.sendMessage("Its description is \"${definition.description}\".")
        }

on_command("objectinfo", PrivilegeLevel.ADMINISTRATOR)
        .then { player ->
            if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::objectinfo [object id]")) {
                return@then
            }

            val id = arguments[0].toInt()
            val definition = ObjectDefinition.lookup(id)
            player.sendMessage("Object $id is called ${definition.name} and its description is " +
                    "\"${definition.description}\".")
            player.sendMessage("Its width is ${definition.width} and its length is ${definition.length}.")
        }


package com.edreams.android.workshops.kotlin.data.venues.remote

import com.edreams.android.workshops.kotlin.data.common.remote.FoursquareService
import com.edreams.android.workshops.kotlin.data.venues.remote.response.VenueResponse
import javax.inject.Inject
import javax.inject.Singleton

private const val RESULTS_LIMIT = 50
private const val PHOTOS_COUNT = 1

@Singleton
class ExploreVenuesNetController @Inject constructor(
    private val service: FoursquareService) : ExploreVenuesController {

  suspend override fun exploreVenues(near: String): List<VenueResponse> =
      service.exploreVenues(near, RESULTS_LIMIT, venuePhotos = PHOTOS_COUNT)
          .await().response.groups[0].items.map { it.venue }
}

Handle exception on net controller when api request fails

package com.edreams.android.workshops.kotlin.data.venues.remote

import com.edreams.android.workshops.kotlin.data.common.remote.FoursquareService
import com.edreams.android.workshops.kotlin.data.venues.remote.response.VenueResponse
import retrofit2.HttpException
import java.io.IOException
import javax.inject.Inject
import javax.inject.Singleton

private const val RESULTS_LIMIT = 50
private const val PHOTOS_COUNT = 1

@Singleton
class ExploreVenuesNetController @Inject constructor(
    private val service: FoursquareService) : ExploreVenuesController {

  suspend override fun exploreVenues(near: String): List<VenueResponse> = try {
    service.exploreVenues(near, RESULTS_LIMIT, venuePhotos = PHOTOS_COUNT)
        .await().response.groups[0].items.map { it.venue }
  } catch (http: HttpException) {
    emptyList()
  } catch (network: IOException) {
    emptyList()
  }
}


package iii_conventions.multiAssignemnt

import util.TODO
import util.doc30

fun todoTask30(): Nothing = TODO(
    """
        Task 30.
        Read about destructuring declarations and make the following code compile by adding one word (after uncommenting it).
    """,
    documentation = doc30()
)

class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

fun isLeapDay(date: MyDate): Boolean {
    todoTask30()
//    val (year, month, dayOfMonth) = date
//
//    // 29 February of a leap year
//    return year % 4 == 0 && month == 2 && dayOfMonth == 29
}

Complete koan 30 (Destructuring Declarations)

package iii_conventions.multiAssignemnt

import util.TODO
import util.doc30

fun todoTask30(): Nothing = TODO(
    """
        Task 30.
        Read about destructuring declarations and make the following code compile by adding one word (after uncommenting it).
    """,
    documentation = doc30()
)

class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

operator fun MyDate.component1() = year
operator fun MyDate.component2() = month
operator fun MyDate.component3() = dayOfMonth

fun isLeapDay(date: MyDate): Boolean {
    val (year, month, dayOfMonth) = date

    // 29 February of a leap year
    return year % 4 == 0 && month == 2 && dayOfMonth == 29
}


package com.s13g.aoc.aoc2020

import com.s13g.aoc.Result
import com.s13g.aoc.Solver

/**
 * --- Day 15: Rambunctious Recitation ---
 * https://adventofcode.com/2020/day/15
 */
class Day15 : Solver {

  override fun solve(lines: List<String>): Result {
    val input = lines[0].split(',').map { it.toInt() }
    return Result("${solveUntil(2020, input)}", "${solveUntil(30000000, input)}")
  }

  private fun solveUntil(limit: Int, input: List<Int>): Int {
    val positions = input
        .withIndex()
        .associate { Pair(it.value, mutableListOf(it.index)) }
        .toMutableMap()

    var lastNum = input.last()
    var chainSize = input.size
    while (chainSize < limit) {
      var age = 0
      if (lastNum in positions && positions[lastNum]!!.size > 1) {
        val l = positions[lastNum]!!.size - 1
        age = positions[lastNum]!![l] - positions[lastNum]!![l - 1]
      }
      // If diff was found, age is > 0, else 0. Add it to the list of positions.
      if (age !in positions) positions[age] = mutableListOf()
      positions[age]!!.add(chainSize)
      lastNum = age
      chainSize++
    }
    // Return the last number found.
    return lastNum
  }
}

Speed up AoC 2020.15 further. Not keeping a list, just the prev found index.

package com.s13g.aoc.aoc2020

import com.s13g.aoc.Result
import com.s13g.aoc.Solver

/**
 * --- Day 15: Rambunctious Recitation ---
 * https://adventofcode.com/2020/day/15
 */
class Day15 : Solver {

  override fun solve(lines: List<String>): Result {
    val input = lines[0].split(',').map { it.toInt() }
    return Result("${solveUntil(2020, input)}", "${solveUntil(30000000, input)}")
  }

  private fun solveUntil(limit: Int, input: List<Int>): Int {
    val lastPositions = input
        .withIndex()
        .filter { it.index < input.size - 1 }
        .associate { Pair(it.value, it.index) }
        .toMutableMap()

    var lastNum = input.last()
    var chainSize = input.size - 1
    while (chainSize < limit - 1) {
      var age = 0
      if (lastNum in lastPositions) {
        age = chainSize - lastPositions[lastNum]!!
      }
      lastPositions[lastNum] = chainSize
      lastNum = age
      chainSize++
    }
    return lastNum
  }
}


import com.elpassion.intelijidea.configuration.RemoteToLocalFileTranslator
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
import org.junit.Assert

class RemoteToLocalFileTranslatorTest : LightPlatformCodeInsightFixtureTestCase() {

    fun testShouldTranslateRemoteFileNameToLocal() {
        val remotePathName = "/home/kasper/mainframer/light_temp/src/test/java/BB.java"
        val result = RemoteToLocalFileTranslator.translate(project, remotePathName)
        Assert.assertEquals("${project.basePath}/src/test/java/BB.java", result)
    }

    fun testReallyShouldTranslateRemoteFileNameToLocal() {
        val remotePathName = "/home/kasper/mainframer/light_temp/src/test/java/CC.java"
        val result = RemoteToLocalFileTranslator.translate(project, remotePathName)
        Assert.assertEquals("${project.basePath}/src/test/java/CC.java", result)
    }
}

Rewrite test to pure junit

import com.elpassion.intelijidea.configuration.RemoteToLocalFileTranslator
import com.intellij.openapi.project.Project
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.mock
import org.junit.Assert.assertEquals
import org.junit.Test

class RemoteToLocalFileTranslatorTest {

    private val project = mock<Project> {
        on { basePath } doReturn "/local/path/to/$PROJECT_NAME"
        on { name } doReturn PROJECT_NAME
    }

    @Test
    fun testShouldTranslateRemoteFileNameToLocal() {
        val remotePathName = "/home/kasper/mainframer/$PROJECT_NAME/src/test/java/BB.java"
        val result = RemoteToLocalFileTranslator.translate(project, remotePathName)
        assertEquals("${project.basePath}/src/test/java/BB.java", result)
    }

    @Test
    fun testReallyShouldTranslateRemoteFileNameToLocal() {
        val remotePathName = "/home/kasper/mainframer/$PROJECT_NAME/src/test/java/CC.java"
        val result = RemoteToLocalFileTranslator.translate(project, remotePathName)
        assertEquals("${project.basePath}/src/test/java/CC.java", result)
    }

    companion object {
        private val PROJECT_NAME = "testProject"
    }
}


Add a block handler for Gutenberg comment spans

package org.wordpress.aztec.plugins.wpcomments.handlers

import org.wordpress.aztec.handlers.GenericBlockHandler
import org.wordpress.aztec.plugins.wpcomments.spans.GutenbergCommentSpan

class GutenbergCommentHandler : GenericBlockHandler<GutenbergCommentSpan>(GutenbergCommentSpan::class.java)


dependencies {
    api("io.github.manamiproject:modb-core:7.0.0")
    api("io.github.manamiproject:modb-db-parser:3.1.0")
    api("org.slf4j:slf4j-api:1.7.32")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
    implementation("io.github.manamiproject:modb-anidb:3.0.5")
    implementation("io.github.manamiproject:modb-anilist:4.0.4")
    implementation("io.github.manamiproject:modb-anime-planet:3.1.5")
    implementation("io.github.manamiproject:modb-anisearch:1.0.5")
    implementation("io.github.manamiproject:modb-kitsu:3.0.4")
    implementation("io.github.manamiproject:modb-livechart:1.0.4")
    implementation("io.github.manamiproject:modb-mal:3.0.4")
    implementation("io.github.manamiproject:modb-notify:3.0.4")
    implementation("ch.qos.logback:logback-classic:1.2.6")
    implementation("org.apache.commons:commons-lang3:3.12.0")
    implementation("org.apache.commons:commons-text:1.9")

    testImplementation("io.github.manamiproject:modb-test:1.2.9")
}

Bump modb-anidb from 3.0.5 to 3.0.6

dependencies {
    api("io.github.manamiproject:modb-core:7.0.0")
    api("io.github.manamiproject:modb-db-parser:3.1.0")
    api("org.slf4j:slf4j-api:1.7.32")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
    implementation("io.github.manamiproject:modb-anidb:3.0.6")
    implementation("io.github.manamiproject:modb-anilist:4.0.4")
    implementation("io.github.manamiproject:modb-anime-planet:3.1.5")
    implementation("io.github.manamiproject:modb-anisearch:1.0.5")
    implementation("io.github.manamiproject:modb-kitsu:3.0.4")
    implementation("io.github.manamiproject:modb-livechart:1.0.4")
    implementation("io.github.manamiproject:modb-mal:3.0.4")
    implementation("io.github.manamiproject:modb-notify:3.0.4")
    implementation("ch.qos.logback:logback-classic:1.2.6")
    implementation("org.apache.commons:commons-lang3:3.12.0")
    implementation("org.apache.commons:commons-text:1.9")

    testImplementation("io.github.manamiproject:modb-test:1.2.9")
}


object PluginVersions {
    val kotlin = "1.3.60"
    val ktlintPlugin = "9.1.1"
    val gradlePublishPlugin = "0.10.1"
    val androidPlugin = "3.5.0"
    val semver = "1.1.1"
    val gradleWrapper = "6.0.1"
    val junit5 = "5.4.0"
    val assertJ = "3.11.1"
}

Update JUnit5 to 5.5.2 version.

object PluginVersions {
    val kotlin = "1.3.60"
    val ktlintPlugin = "9.1.1"
    val gradlePublishPlugin = "0.10.1"
    val androidPlugin = "3.5.0"
    val semver = "1.1.1"
    val gradleWrapper = "6.0.1"
    val junit5 = "5.5.2"
    val assertJ = "3.11.1"
}


package coil.size

import android.os.Parcelable
import androidx.annotation.Px
import coil.request.ImageRequest
import kotlinx.android.parcel.Parcelize

/**
 * Represents the target size of an image request.
 *
 * @see ImageRequest.Builder.size
 * @see SizeResolver.size
 */
sealed class Size : Parcelable

/** Represents the width and height of the source image. */
@Parcelize
object OriginalSize : Size() {
    override fun toString() = "coil.size.OriginalSize"
}

/** A positive width and height in pixels. */
@Parcelize
data class PixelSize(
    @Px val width: Int,
    @Px val height: Int
) : Size() {

    init {
        require(width > 0 && height > 0) { "Width and height must be > 0." }
    }
}

Make error message consistent with other messages.

package coil.size

import android.os.Parcelable
import androidx.annotation.Px
import coil.request.ImageRequest
import kotlinx.android.parcel.Parcelize

/**
 * Represents the target size of an image request.
 *
 * @see ImageRequest.Builder.size
 * @see SizeResolver.size
 */
sealed class Size : Parcelable

/** Represents the width and height of the source image. */
@Parcelize
object OriginalSize : Size() {
    override fun toString() = "coil.size.OriginalSize"
}

/** A positive width and height in pixels. */
@Parcelize
data class PixelSize(
    @Px val width: Int,
    @Px val height: Int
) : Size() {

    init {
        require(width > 0 && height > 0) { "width and height must be > 0." }
    }
}


package com.felipecosta.kotlinrxjavasample.di

import android.content.Context
import android.support.test.InstrumentationRegistry
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

@Module
class TestApplicationModule {

    @Singleton
    @Provides
    fun providesApplicationContext(): Context = InstrumentationRegistry.getContext().applicationContext
}

Use the target context in the instrumentation test module

package com.felipecosta.kotlinrxjavasample.di

import android.content.Context
import android.support.test.InstrumentationRegistry
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

@Module
class TestApplicationModule {

    @Singleton
    @Provides
    fun providesApplicationContext(): Context = InstrumentationRegistry.getTargetContext()
}


package views

/**
 * Created by allen on 3/31/17.
 */
abstract class BaseView {
    fun uriEncode(s: String): String{
        return s.replace("%", "%25").replace(" ", "%20")
    }
}

Add more characters to be escaped by uriencode

package views

/**
 * Created by allen on 3/31/17.
 */
abstract class BaseView {
    //based on: https://en.wikipedia.org/wiki/Percent-encoding
    fun uriEncode(s: String): String{
        return s
                .replace("%", "%25")
                .replace(" ", "%20")
                .replace("!", "%21")
                .replace("#", "%23")
                .replace("$", "%24")
                .replace("&", "%26")
                .replace("'", "%27")
                .replace("(", "%28")
                .replace(")", "%29")
                .replace("*", "%2A")
                .replace("+", "%2B")
                .replace(",", "%2C")
                .replace(":", "%3A")
                .replace(";", "%3B")
                .replace("=", "%3D")
                .replace("?", "%3F")
                .replace("@", "%40")
                .replace("[", "%5B")
                .replace("]", "%5D")
    }
}


package me.mrkirby153.KirBot.command.args.elements

import me.mrkirby153.KirBot.command.args.ArgumentList
import me.mrkirby153.KirBot.command.args.ArgumentParseException
import me.mrkirby153.KirBot.command.args.CommandElement

class NumberElement(private val min: Double, private val max: Double) : CommandElement<Double> {

    override fun parse(list: ArgumentList): Double {
        val num = list.popFirst()
        try {
            val number = num.toDouble()

            if (number < min) {
                throw ArgumentParseException(String.format("The number you specified (%.2f) must be greater than %.2f", number, min))
            }
            if (number > max) {
                throw ArgumentParseException(String.format("The number you specified (%.2f) must be less than %.2f", number, max))
            }
            return number
        } catch (e: Exception) {
            throw ArgumentParseException("$num is not a number!")
        }
    }
}

Fix try/catch block when parsing numbers

package me.mrkirby153.KirBot.command.args.elements

import me.mrkirby153.KirBot.command.args.ArgumentList
import me.mrkirby153.KirBot.command.args.ArgumentParseException
import me.mrkirby153.KirBot.command.args.CommandElement

class NumberElement(private val min: Double, private val max: Double) : CommandElement<Double> {

    override fun parse(list: ArgumentList): Double {
        val num = list.popFirst()
        try {
            val number = num.toDouble()

            if (number < min) {
                throw ArgumentParseException(String.format("The number you specified (%.2f) must be greater than %.1f", number, min))
            }
            if (number > max) {
                throw ArgumentParseException(String.format("The number you specified (%.2f) must be less than %.1f", number, max))
            }
            return number
        } catch (e: NumberFormatException) {
            throw ArgumentParseException("$num is not a number!")
        }
    }
}


package org.jetbrains.kotlinx.jupyter.api

import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.KType
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.full.starProjectedType

typealias VariableDeclarationCallback<T> = KotlinKernelHost.(T, KProperty<*>) -> Unit

typealias FieldName = String

typealias VariableUpdateCallback<T> = KotlinKernelHost.(T, KProperty<*>) -> FieldName?

fun interface FieldHandlerExecution<T> {

    fun execute(host: KotlinKernelHost, value: T, property: KProperty<*>)
}

interface FieldHandler {
    /**
     * Returns true if this converter accepts [type], false otherwise
     */
    fun acceptsType(type: KType): Boolean

    /**
     * Execution to handle conversion.
     * Should not throw if [acceptsType] returns true
     */
    val execution: FieldHandlerExecution<*>
}

class FieldHandlerByClass(
    private val kClass: KClass<out Any>,
    override val execution: FieldHandlerExecution<*>,
) : FieldHandler {
    override fun acceptsType(type: KType) = type.isSubtypeOf(kClass.starProjectedType)
}

Rename 'FieldName' to 'VariableName' type alias

package org.jetbrains.kotlinx.jupyter.api

import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.KType
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.full.starProjectedType

typealias VariableDeclarationCallback<T> = KotlinKernelHost.(T, KProperty<*>) -> Unit

typealias VariableName = String

typealias VariableUpdateCallback<T> = KotlinKernelHost.(T, KProperty<*>) -> VariableName?

fun interface FieldHandlerExecution<T> {

    fun execute(host: KotlinKernelHost, value: T, property: KProperty<*>)
}

interface FieldHandler {
    /**
     * Returns true if this converter accepts [type], false otherwise
     */
    fun acceptsType(type: KType): Boolean

    /**
     * Execution to handle conversion.
     * Should not throw if [acceptsType] returns true
     */
    val execution: FieldHandlerExecution<*>
}

class FieldHandlerByClass(
    private val kClass: KClass<out Any>,
    override val execution: FieldHandlerExecution<*>,
) : FieldHandler {
    override fun acceptsType(type: KType) = type.isSubtypeOf(kClass.starProjectedType)
}


Add a new type of plugin that can process the entire content of an element

package org.wordpress.aztec.plugins.html2visual

import android.text.Editable

/**
 * An interface for HTML content processing plugins. Plugin implementing this interface will be responsible for handling
 * the entire content of an element, as it will not be parsed.
 */
interface IHtmlContentHandler {
    fun canHandleTag(tag: String): Boolean
    fun handleContent(content: String, output: Editable, nestingLevel: Int)
}


/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.support

import org.gradle.api.Project
import org.gradle.api.plugins.ExtraPropertiesExtension
import java.io.File

object SupportConfig {
    const val DEFAULT_MIN_SDK_VERSION = 14
    const val INSTRUMENTATION_RUNNER = "android.support.test.runner.AndroidJUnitRunner"
    const val BUILD_TOOLS_VERSION = "27.0.1"
    const val CURRENT_SDK_VERSION = 28

    fun getKeystore(project: Project): File {
        val supportRoot = (project.rootProject.property("ext") as ExtraPropertiesExtension)
                .get("supportRootFolder") as File
        return File(supportRoot, "development/keystore/debug.keystore")
    }

    fun getLintBaseline(project: Project): File {
        return File(project.projectDir, "/lint-baseline.xml")
    }
}

Update to build tools 27.0.3

/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.support

import org.gradle.api.Project
import org.gradle.api.plugins.ExtraPropertiesExtension
import java.io.File

object SupportConfig {
    const val DEFAULT_MIN_SDK_VERSION = 14
    const val INSTRUMENTATION_RUNNER = "android.support.test.runner.AndroidJUnitRunner"
    const val BUILD_TOOLS_VERSION = "27.0.3"
    const val CURRENT_SDK_VERSION = 28

    fun getKeystore(project: Project): File {
        val supportRoot = (project.rootProject.property("ext") as ExtraPropertiesExtension)
                .get("supportRootFolder") as File
        return File(supportRoot, "development/keystore/debug.keystore")
    }

    fun getLintBaseline(project: Project): File {
        return File(project.projectDir, "/lint-baseline.xml")
    }
}


/*
 * Copyright 2000-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.debugger.streams.trace.dsl.impl

import com.intellij.debugger.streams.trace.dsl.*

/**
 * TODO: Add ability to add braces at the beginning and at the end
 *
 * @author Vitaliy.Bibaev
 */
abstract class LineSeparatedCodeBlock(statementFactory: StatementFactory, private val endLine: String = "")
  : CodeBlockBase(statementFactory) {
  override fun toCode(): String {
    val body = statements
    return body.joinToString("$endLine\n") { it.toCode() }
  }
}

Fix error in code block format

/*
 * Copyright 2000-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.debugger.streams.trace.dsl.impl

import com.intellij.debugger.streams.trace.dsl.*

/**
 * TODO: Add ability to add braces at the beginning and at the end
 *
 * @author Vitaliy.Bibaev
 */
abstract class LineSeparatedCodeBlock(statementFactory: StatementFactory, private val endLine: String = "")
  : CodeBlockBase(statementFactory) {
  override fun toCode(): String {
    val body = statements
    if (statements.isEmpty()) {
      return ""
    }

    return body.joinToString("$endLine\n", postfix = "$endLine\n") { it.toCode() }
  }
}


pluginManagement {
    plugins {
        id("org.jetbrains.kotlin.jvm") version "1.5.21"
        id("com.gradle.plugin-publish") version "0.15.0"
        `java-gradle-plugin`
        `maven-publish`
        id("org.jlleitschuh.gradle.ktlint") version "10.1.0"
        id("com.github.johnrengelman.shadow") version "7.0.0"
        id("com.github.breadmoirai.github-release") version "2.2.10"
    }
}

enableFeaturePreview("VERSION_CATALOGS")

plugins {
    `gradle-enterprise`
}

gradleEnterprise {
    buildScan {
        termsOfServiceUrl = "https://gradle.com/terms-of-service"
        termsOfServiceAgree = "yes"

        publishAlways()
    }
}

rootProject.name = "ktlint-gradle"
rootProject.buildFileName = "build.gradle.kts"

Use latest released version of plugin on itself.

pluginManagement {
    plugins {
        id("org.jetbrains.kotlin.jvm") version "1.5.21"
        id("com.gradle.plugin-publish") version "0.15.0"
        `java-gradle-plugin`
        `maven-publish`
        id("org.jlleitschuh.gradle.ktlint") version "10.2.0"
        id("com.github.johnrengelman.shadow") version "7.0.0"
        id("com.github.breadmoirai.github-release") version "2.2.10"
    }
}

enableFeaturePreview("VERSION_CATALOGS")

plugins {
    `gradle-enterprise`
}

gradleEnterprise {
    buildScan {
        termsOfServiceUrl = "https://gradle.com/terms-of-service"
        termsOfServiceAgree = "yes"

        publishAlways()
    }
}

rootProject.name = "ktlint-gradle"
rootProject.buildFileName = "build.gradle.kts"


package com.livinglifetechway.k4kotlin

import android.util.Log

/**
 * Returns class name. Useful for Log Tags
 */
val Any.TAG: String
    get() = this::class.java.simpleName

/**
 * Logs current object as Debug
 */
fun Any.logD(tag: String = TAG) = Log.d(tag, toString())

/**
 * Logs current object as Information
 */
fun Any.logI(tag: String = TAG) = Log.i(tag, toString())

/**
 * Logs current object as Verbose
 */
fun Any.logV(tag: String = TAG) = Log.v(tag, toString())

/**
 * Logs current object as Warning
 */
fun Any.logW(tag: String = TAG) = Log.w(tag, toString())

/**
 * Logs current object as Error
 */
fun Any.logE(tag: String = TAG) = Log.e(tag, toString())

/**
 * Logs current object as Wtf (What a Terrible Failure)
 */
fun Any.logWtf(tag: String = TAG) = Log.wtf(tag, toString())

Make logs extension functions inline to reduce method call overheads

package com.livinglifetechway.k4kotlin

import android.util.Log

/**
 * Returns class name. Useful for Log Tags
 */
val Any.TAG: String
    get() = this::class.java.simpleName

/**
 * Logs current object as Debug
 */
inline fun Any.logD(tag: String = TAG) = Log.d(tag, toString())

/**
 * Logs current object as Information
 */
inline fun Any.logI(tag: String = TAG) = Log.i(tag, toString())

/**
 * Logs current object as Verbose
 */
inline fun Any.logV(tag: String = TAG) = Log.v(tag, toString())

/**
 * Logs current object as Warning
 */
inline fun Any.logW(tag: String = TAG) = Log.w(tag, toString())

/**
 * Logs current object as Error
 */
inline fun Any.logE(tag: String = TAG) = Log.e(tag, toString())

/**
 * Logs current object as Wtf (What a Terrible Failure)
 */
inline fun Any.logWtf(tag: String = TAG) = Log.wtf(tag, toString())


package io.rover.sdk.ui.blocks.web

import android.annotation.SuppressLint
import android.webkit.WebView
import android.webkit.WebViewClient
import io.rover.sdk.ui.concerns.MeasuredBindableView
import io.rover.sdk.ui.concerns.ViewModelBinding

@SuppressLint("SetJavaScriptEnabled")
internal class ViewWeb(
    private val webView: WebView
) : ViewWebInterface {

    init {
        WebView.setWebContentsDebuggingEnabled(true)
        // Setting an otherwise unconfigured WebViewClient will have the webview navigate (follow
        // links) internally.
        webView.webViewClient = WebViewClient()
        webView.settings.domStorageEnabled = true

        // Suppressed SetJavaScriptEnabled, because we do not expose any custom native APIs to
        // Javascript, and thus no extra security surface beyond that of a standard web browser are
        // introduced.
        webView.settings.javaScriptEnabled = true

        // TODO disable the scroll bars if scrolling is disabled, because otherwise they'll appear
        // when you scroll by
    }

    override var viewModelBinding: MeasuredBindableView.Binding<WebViewModelInterface>? by ViewModelBinding { binding, _ ->
        webView.loadUrl(
            binding?.viewModel?.url?.toString() ?: "about://blank"
        )
    }
}

Allow for media playback without user gesture

package io.rover.sdk.ui.blocks.web

import android.annotation.SuppressLint
import android.webkit.WebView
import android.webkit.WebViewClient
import io.rover.sdk.ui.concerns.MeasuredBindableView
import io.rover.sdk.ui.concerns.ViewModelBinding

@SuppressLint("SetJavaScriptEnabled")
internal class ViewWeb(
    private val webView: WebView
) : ViewWebInterface {

    init {
        WebView.setWebContentsDebuggingEnabled(true)
        // Setting an otherwise unconfigured WebViewClient will have the webview navigate (follow
        // links) internally.
        webView.webViewClient = WebViewClient()
        webView.settings.domStorageEnabled = true

        // Suppressed SetJavaScriptEnabled, because we do not expose any custom native APIs to
        // Javascript, and thus no extra security surface beyond that of a standard web browser are
        // introduced.
        webView.settings.javaScriptEnabled = true

        // Allow for media to auto play
        webView.settings.mediaPlaybackRequiresUserGesture = false

        // TODO disable the scroll bars if scrolling is disabled, because otherwise they'll appear
        // when you scroll by
    }

    override var viewModelBinding: MeasuredBindableView.Binding<WebViewModelInterface>? by ViewModelBinding { binding, _ ->
        webView.loadUrl(
            binding?.viewModel?.url?.toString() ?: "about://blank"
        )
    }
}


plugins {
    id("gradlebuild.distribution.api-java")
}

description = "Infrastructure for running worker processes"

dependencies {
    implementation(project(":base-services"))
    implementation(project(":messaging"))
    implementation(project(":logging"))
    implementation(project(":process-services"))
    implementation(project(":worker-processes"))
    implementation(project(":persistent-cache"))
    implementation(project(":core-api"))
    implementation(project(":model-core"))
    implementation(project(":core"))
    implementation(project(":snapshots"))
    implementation(project(":file-collections"))
    implementation(project(":files"))
    implementation(project(":native"))
    implementation(project(":resources"))

    implementation(libs.slf4jApi)
    implementation(libs.guava)
    implementation(libs.inject)

    testImplementation(project(":native"))
    testImplementation(project(":file-collections"))
    testImplementation(project(":resources"))
    testImplementation(project(":snapshots"))
    testImplementation(testFixtures(project(":core")))
    testImplementation(testFixtures(project(":logging")))

    integTestRuntimeOnly(project(":kotlin-dsl"))
    integTestRuntimeOnly(project(":kotlin-dsl-provider-plugins"))
    integTestRuntimeOnly(project(":api-metadata"))
    integTestRuntimeOnly(project(":test-kit"))

    integTestImplementation(project(":jvm-services"))

    testFixturesImplementation(libs.inject)
    testFixturesImplementation(libs.groovyJson)
    testFixturesImplementation(project(":base-services"))

    testRuntimeOnly(project(":distributions-core")) {
        because("Tests instantiate DefaultClassLoaderRegistry which requires a 'gradle-plugins.properties' through DefaultPluginModuleRegistry")
    }
    integTestDistributionRuntimeOnly(project(":distributions-core"))
}

Clarify description of workers project

plugins {
    id("gradlebuild.distribution.api-java")
}

description = "Infrastructure for starting and managing worker processes"

dependencies {
    implementation(project(":base-services"))
    implementation(project(":messaging"))
    implementation(project(":logging"))
    implementation(project(":process-services"))
    implementation(project(":worker-processes"))
    implementation(project(":persistent-cache"))
    implementation(project(":core-api"))
    implementation(project(":model-core"))
    implementation(project(":core"))
    implementation(project(":snapshots"))
    implementation(project(":file-collections"))
    implementation(project(":files"))
    implementation(project(":native"))
    implementation(project(":resources"))

    implementation(libs.slf4jApi)
    implementation(libs.guava)
    implementation(libs.inject)

    testImplementation(project(":native"))
    testImplementation(project(":file-collections"))
    testImplementation(project(":resources"))
    testImplementation(project(":snapshots"))
    testImplementation(testFixtures(project(":core")))
    testImplementation(testFixtures(project(":logging")))

    integTestRuntimeOnly(project(":kotlin-dsl"))
    integTestRuntimeOnly(project(":kotlin-dsl-provider-plugins"))
    integTestRuntimeOnly(project(":api-metadata"))
    integTestRuntimeOnly(project(":test-kit"))

    integTestImplementation(project(":jvm-services"))

    testFixturesImplementation(libs.inject)
    testFixturesImplementation(libs.groovyJson)
    testFixturesImplementation(project(":base-services"))

    testRuntimeOnly(project(":distributions-core")) {
        because("Tests instantiate DefaultClassLoaderRegistry which requires a 'gradle-plugins.properties' through DefaultPluginModuleRegistry")
    }
    integTestDistributionRuntimeOnly(project(":distributions-core"))
}


package com.agoda.sample

Add test for picker dialogs

package com.agoda.sample

import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import androidx.test.rule.ActivityTestRule
import com.agoda.kakao.screen.Screen
import com.agoda.sample.screen.PickersActivityScreen
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4ClassRunner::class)
class PickersTest {
    @Rule
    @JvmField
    val rule = ActivityTestRule(PickersActivity::class.java)

    @Test
    fun testTextInputLayout() {
        Screen.onScreen<PickersActivityScreen> {
            selectTimeButton {
                click()
            }

            timePicker {
                setTime(22, 4)
            }

            timeText {
                hasText("22:4")
            }

            selectDateButton {
                click()
            }

            datePicker {
                setDate(1955, 11, 12)
            }

            dateText {
                hasText("12 11 1955")
            }
        }
    }
}


subprojects {
    apply {
        plugin("maven-publish")
        plugin("com.jfrog.bintray")
    }

    dependencies {
        compileOnly(project(":core"))
        implementation(kotlin("stdlib-jdk8"))
        implementation(kotlin("stdlib"))
        implementation(kotlin("reflect"))

        testImplementation(project(":testApi"))
        testImplementation("org.junit.jupiter:junit-jupiter:5.6.0")
    }

    tasks.test {
        useJUnitPlatform()
        testLogging {
            events("passed", "skipped", "failed")
        }
    }
}

Change test logging to show only skipped and failed ones, show full stacktraces

import org.gradle.api.tasks.testing.logging.TestExceptionFormat

subprojects {
    apply {
        plugin("maven-publish")
        plugin("com.jfrog.bintray")
    }

    dependencies {
        compileOnly(project(":core"))
        implementation(kotlin("stdlib-jdk8"))
        implementation(kotlin("stdlib"))
        implementation(kotlin("reflect"))

        testImplementation(project(":testApi"))
        testImplementation("org.junit.jupiter:junit-jupiter:5.6.0")
    }

    tasks.test {
        useJUnitPlatform()
        testLogging {
            exceptionFormat = TestExceptionFormat.FULL
            events( "skipped", "failed")
        }
    }
}


import org.gradle.kotlin.dsl.plugins.precompiled.PrecompiledScriptPlugins
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

buildscript {

    val pluginsExperiments = "gradle.plugin.org.gradle.kotlin:gradle-kotlin-dsl-plugins-experiments:0.1.10"

    dependencies {
        classpath(pluginsExperiments)
    }

    project.dependencies {
        "compile"(pluginsExperiments)
    }

    configure(listOf(repositories, project.repositories)) {
        gradlePluginPortal()
    }
}

plugins {
    `java-gradle-plugin`
    `kotlin-dsl`
}

apply(plugin = "org.gradle.kotlin.ktlint-convention")

apply<PrecompiledScriptPlugins>()

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs += listOf(
            "-Xjsr305=strict",
            "-Xskip-runtime-version-check",
            "-Xskip-metadata-version-check"
        )
    }
}

dependencies {
    compileOnly(gradleKotlinDsl())

    compile(kotlin("gradle-plugin"))
    compile(kotlin("stdlib-jdk8"))
    compile(kotlin("reflect"))

    compile("com.gradle.publish:plugin-publish-plugin:0.9.10")
    compile("org.ow2.asm:asm-all:5.1")

    testCompile("junit:junit:4.12")
    testCompile(gradleTestKit())
}

Enable progressive kotlin-dsl on buildSrc

import org.gradle.kotlin.dsl.plugins.dsl.ProgressiveModeState
import org.gradle.kotlin.dsl.plugins.precompiled.PrecompiledScriptPlugins
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

buildscript {

    val pluginsExperiments = "gradle.plugin.org.gradle.kotlin:gradle-kotlin-dsl-plugins-experiments:0.1.10"

    dependencies {
        classpath(pluginsExperiments)
    }

    project.dependencies {
        "compile"(pluginsExperiments)
    }

    configure(listOf(repositories, project.repositories)) {
        gradlePluginPortal()
    }
}

plugins {
    `java-gradle-plugin`
    `kotlin-dsl`
}

kotlinDslPluginOptions {
    progressive.set(ProgressiveModeState.ENABLED)
}

apply(plugin = "org.gradle.kotlin.ktlint-convention")

apply<PrecompiledScriptPlugins>()

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs += listOf(
            "-Xjsr305=strict",
            "-Xskip-runtime-version-check",
            "-Xskip-metadata-version-check"
        )
    }
}

dependencies {
    compileOnly(gradleKotlinDsl())

    compile(kotlin("gradle-plugin"))
    compile(kotlin("stdlib-jdk8"))
    compile(kotlin("reflect"))

    compile("com.gradle.publish:plugin-publish-plugin:0.9.10")
    compile("org.ow2.asm:asm-all:5.1")

    testCompile("junit:junit:4.12")
    testCompile(gradleTestKit())
}


/*
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 * Copyright (C) 2003-2020 The IdeaVim authors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */

package org.jetbrains.plugins.ideavim.action.change.change.number

import com.maddyhome.idea.vim.command.CommandState
import com.maddyhome.idea.vim.helper.VimBehaviorDiffers
import org.jetbrains.plugins.ideavim.VimTestCase

class ChangeNumberIncActionTest : VimTestCase() {
  @VimBehaviorDiffers(originalVimAfter = "11X0")
  fun `test inc fancy number`() {
    doTest("<C-A>", "1${c}0X0", "10X1", CommandState.Mode.COMMAND, CommandState.SubMode.NONE)
  }
}

Add new line at the end of test


// See https://blog.gradle.org/mrjars and https://github.com/melix/mrjar-gradle for more on multi release jars

sourceSets {
    create("java11") {
        java {
            srcDir("src/java11/main")
        }
    }
}

tasks.named<JavaCompile>("compileJava11Java") {
    // Arrays.equals exists since JDK9, but the intent is to only use it on Java 11+, it seems.
    sourceCompatibility = "9"
    targetCompatibility = "9"
}

tasks.named<Jar>("jar") {
    into("META-INF/versions/11") {
        from(sourceSets.named("java11").get().output)
    }
    manifest.attributes(
            Pair("Multi-Release", "true")
    )
}

Tweak shims build to include shims in all cases

// See https://blog.gradle.org/mrjars and https://github.com/melix/mrjar-gradle for more on multi release jars

sourceSets {
    create("java11") {
        java {
            srcDir("src/java11/main")
        }
    }
}

tasks.named<JavaCompile>("compileJava11Java") {
    // Arrays.equals exists since JDK9, but we make it available for 11+ so we can test the shim by using Java 11
    // and the old way by using Java 10, which will compile the new code but not use it..
    sourceCompatibility = "9"
    targetCompatibility = "9"
}

tasks.named<Jar>("jar") {
    into("META-INF/versions/11") {
        from(sourceSets.named("java11").get().output)
    }
    manifest.attributes(
            Pair("Multi-Release", "true")
    )

    // normally jar is just main classes but we also have another sourceset
    dependsOn(tasks.named("compileJava11Java"))
}


import machine.learning.ARL
import java.io.File
import java.util.*

fun main(args : Array<String>) {

    // we open the .dat file located in data
    val myFile =  File("data/EURUSD.dat").inputStream()
    val array2 : ArrayList<Double> = arrayListOf()

    myFile.bufferedReader().useLines { lines -> lines.forEach {
        array2.add( it.split("/")[0].split(" ").last().toDouble())
    } }

    val time = System.currentTimeMillis()
    val arl = ARL(array2.toDoubleArray().slice(0..20000), 5)

    arl.trainingLoop()
    println("${(System.currentTimeMillis() - time) / 1000} secondes" )

//    println(arl.toString())
}

Add a test loop in the main

import machine.learning.ARL
import java.io.File
import java.util.*

fun main(args : Array<String>) {

    // we open the .dat file located in data
    val myFile =  File("data/EURUSD.dat").inputStream()
    val array2 : ArrayList<Double> = arrayListOf()

    myFile.bufferedReader().useLines { lines -> lines.forEach {
        array2.add( it.split("/")[0].split(" ").last().toDouble())
    } }

    val time = System.currentTimeMillis()
    val arl = ARL(array2.toDoubleArray().slice(0..100000), 5)

    arl.trainingLoop()
    arl.testLoop(prices=array2.toDoubleArray().slice(50000..60000).toDoubleArray())

//    println(arl.toString())
}


package org.wordpress.aztec.spans

import android.content.Context
import android.graphics.drawable.Drawable
import android.support.v4.content.ContextCompat
import android.view.Gravity
import org.wordpress.aztec.AztecAttributes
import org.wordpress.aztec.AztecText

class AztecVideoSpan(context: Context, drawable: Drawable?, override var nestingLevel: Int,
                     attributes: AztecAttributes = AztecAttributes(),
                     var onVideoTappedListener: AztecText.OnVideoTappedListener? = null,
                     editor: AztecText? = null) :
        AztecMediaSpan(context, drawable, attributes, editor), IAztecFullWidthImageSpan, IAztecSpan {

    override val TAG: String = "link"

    init {
        setOverlay(0, ContextCompat.getDrawable(context, android.R.drawable.ic_media_play), Gravity.CENTER)
    }

    override fun onClick() {
        onVideoTappedListener?.onVideoTapped(attributes)
    }
}

Revert "Dummy commit to restart Jitpack.io"


Add facade for non-interactive preview for desktop

/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.compose.desktop.ui.tooling.preview.runtime

import androidx.compose.runtime.Composable
import androidx.compose.runtime.currentComposer
import androidx.compose.ui.platform.TestComposeWindow
import androidx.compose.ui.tooling.CommonPreviewUtils
import androidx.compose.ui.unit.Density

/**
 * This class is used by Compose Desktop Intellij plugin
 * for the non-interactive preview functionality.
 *
 * The class is used via reflection.
 *
 * The non-interactive preview for desktop works in the following way:
 * 1. A user annotates a composable function with the @Preview annotation;
 * 2. A user is able to request an IDE preview by clicking a gutter icon in the editor;
 * 3. When an updated preview is requested, the Intellij plugin requests a fresh build from Gradle
 *    and pulls an updated preview configuration from the build;
 * 4. The IDE plugin manages a separate preview host process;
 * 5. The IDE plugin requests a new frame from the preview host process, when needed (either when
 *    a user requests it explicitly or by resizing the preview tool window);
 * 6. When the preview process receives a preview request, it renders a new frame using this
 *    facade in an isolated classloader via reflection. The classloader is persisted between
 *    requests to minimize render time. Currently it is reused only if there are no changes in a
 *    preview classpath (a requested preview function or a requested frame size may differ).
 * 7. A rendered frame is sent back to the IDE plugin and is shown in the IDE as an image.
 */
@Suppress("unused")
internal class NonInteractivePreviewFacade {
    companion object {
        @JvmStatic
        fun render(fqName: String, width: Int, height: Int, scale: Double?): ByteArray {
            val className = fqName.substringBeforeLast(".")
            val methodName = fqName.substringAfterLast(".")
            val density = scale?.let { Density(it.toFloat()) } ?: Density(1f)
            val window = TestComposeWindow(width = width, height = height, density = density)
            window.setContent @Composable {
                // We need to delay the reflection instantiation of the class until we are in the
                // composable to ensure all the right initialization has happened and the Composable
                // class loads correctly.
                CommonPreviewUtils.invokeComposableViaReflection(
                    className,
                    methodName,
                    currentComposer
                )
            }
            return window.surface.makeImageSnapshot().encodeToData()!!.bytes
        }
    }
}


package cn.qiuxiang.react.amap3d

import android.content.Context
import com.facebook.react.views.view.ReactViewGroup

class AMapOverlay(context: Context) : ReactViewGroup(context) {
    private var updateHandler: (() -> Unit)? = null

    fun onUpdate(handler: () -> Unit) {
        updateHandler = handler
    }

    fun update() {
        updateHandler?.invoke()
    }
}

Fix android InfoWindow layout bug

package cn.qiuxiang.react.amap3d

import android.content.Context
import com.facebook.react.views.view.ReactViewGroup

class AMapOverlay(context: Context) : ReactViewGroup(context) {
    private var updateHandler: (() -> Unit)? = null

    fun onUpdate(handler: () -> Unit) {
        updateHandler = handler
    }

    fun update() {
        val layoutParams = this.layoutParams
        if (layoutParams == null || layoutParams.width != this.width || layoutParams.height != this.height) {
            this.layoutParams = LayoutParams(this.width, this.height)
        }
        updateHandler?.invoke()
    }
}


package org.jetbrains.ktor.content

import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.routing.*
import kotlin.reflect.*

interface TemplateEngine<C : Any, R> where R : StreamContent, R : HasContentType {
    val contentClass: KClass<C>
    fun process(content: C): R
}

inline fun <reified C : Any> Application.templating(engine: TemplateEngine<C, *>) {
    val javaType = engine.contentClass.java
    intercept { next ->
        response.interceptSend { obj, next ->
            if (javaType.isInstance(obj)) {
                response.send(engine.process(obj as C))
            } else {
                next(obj)
            }
        }
        next()
    }
}

inline fun <reified C : Any> RoutingEntry.templating(engine: TemplateEngine<C, *>) {
    val javaType = engine.contentClass.java
    intercept { next ->
        response.interceptSend { obj, next ->
            if (javaType.isInstance(obj)) {
                response.send(engine.process(obj as C))
            } else {
                next(obj)
            }
        }
        next()
    }
}

Unify interception using InterceptApplicationCall (former InterceptableWithContext)

package org.jetbrains.ktor.content

import org.jetbrains.ktor.application.*
import org.jetbrains.ktor.interception.*
import org.jetbrains.ktor.routing.*
import kotlin.reflect.*

interface TemplateEngine<C : Any, R> where R : StreamContent, R : HasContentType {
    val contentClass: KClass<C>
    fun process(content: C): R
}

inline fun <reified C : Any> InterceptApplicationCall<ApplicationCall>.templating(engine: TemplateEngine<C, *>) {
    val javaType = engine.contentClass.java
    intercept { next ->
        response.interceptSend { obj, next ->
            if (javaType.isInstance(obj)) {
                response.send(engine.process(obj as C))
            } else {
                next(obj)
            }
        }
        next()
    }
}


dependencies {
    api("io.github.manamiproject:modb-core:7.0.0")
    api("io.github.manamiproject:modb-db-parser:3.0.4")
    api("org.slf4j:slf4j-api:1.7.32")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
    implementation("io.github.manamiproject:modb-anidb:3.0.5")
    implementation("io.github.manamiproject:modb-anilist:4.0.4")
    implementation("io.github.manamiproject:modb-anime-planet:3.1.5")
    implementation("io.github.manamiproject:modb-anisearch:1.0.5")
    implementation("io.github.manamiproject:modb-kitsu:3.0.4")
    implementation("io.github.manamiproject:modb-livechart:1.0.4")
    implementation("io.github.manamiproject:modb-mal:3.0.4")
    implementation("io.github.manamiproject:modb-notify:3.0.4")
    implementation("ch.qos.logback:logback-classic:1.2.5")
    implementation("org.apache.commons:commons-lang3:3.12.0")
    implementation("org.apache.commons:commons-text:1.9")

    testImplementation("io.github.manamiproject:modb-test:1.2.8")
}

Bump logback-classic from 1.2.5 to 1.2.6

dependencies {
    api("io.github.manamiproject:modb-core:7.0.0")
    api("io.github.manamiproject:modb-db-parser:3.0.4")
    api("org.slf4j:slf4j-api:1.7.32")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
    implementation("io.github.manamiproject:modb-anidb:3.0.5")
    implementation("io.github.manamiproject:modb-anilist:4.0.4")
    implementation("io.github.manamiproject:modb-anime-planet:3.1.5")
    implementation("io.github.manamiproject:modb-anisearch:1.0.5")
    implementation("io.github.manamiproject:modb-kitsu:3.0.4")
    implementation("io.github.manamiproject:modb-livechart:1.0.4")
    implementation("io.github.manamiproject:modb-mal:3.0.4")
    implementation("io.github.manamiproject:modb-notify:3.0.4")
    implementation("ch.qos.logback:logback-classic:1.2.6")
    implementation("org.apache.commons:commons-lang3:3.12.0")
    implementation("org.apache.commons:commons-text:1.9")

    testImplementation("io.github.manamiproject:modb-test:1.2.8")
}


package Kotlin101.Functions.Cascades

fun main (Args : Array<String>){
    /* This call utilizes extension function and infix call */
    var superman = Superman() with {
        name = "Lux Luthor"
        punch()
        kick()
    }
}

public fun <T>T.with(operations : T.() -> Unit) : T {
    this.operations()
    return this
}

public class Superman() {
    var name : String = "Clark Kent"

    public fun punch() : Unit = println("$name punches")
    public fun fly() : Unit = println("$name flies")
    public fun kick() : Unit = println("$name kicks")
}


Add unit tests for EmailAddressValidator

package com.fsck.k9

import org.junit.Assert
import org.junit.Test

class EmailAddressValidatorTest {

    @Test
    fun testEmailValidation() {
        //Most of the tests based on https://en.wikipedia.org/wiki/Email_address#Examples
        val validator = EmailAddressValidator()
        Assert.assertTrue(validator.isValidAddressOnly("simple@example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("very.common@example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("disposable.style.email.with+symbol@example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("other.email-with-hyphen@example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("fully-qualified-domain@example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("user.name+tag+sorting@example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("example-indeed@strange-example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("example-indeed@strange_example.com"))
        Assert.assertTrue(validator.isValidAddressOnly("example@1.com"))
        Assert.assertTrue(validator.isValidAddressOnly("admin@mailserver1"))
        Assert.assertTrue(validator.isValidAddressOnly("user@localserver"))

        Assert.assertFalse(validator.isValidAddressOnly("Abc.example.com"))
        Assert.assertFalse(validator.isValidAddressOnly("\"not\"right@example.com"))
        Assert.assertFalse(validator.isValidAddressOnly("john.doe@example..com"))
        Assert.assertFalse(validator.isValidAddressOnly("example@c.2"))
    }
}


/*
 * Copyright 2014-2018 Julien Guerinet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.guerinet.mymartlet.util.prefs

import android.content.Context
import android.content.SharedPreferences
import com.guerinet.mymartlet.R
import com.guerinet.suitcase.prefs.NullStringPref

/**
 * Stores and loads the user's username (McGill email)
 * @author Julien Guerinet
 * @since 1.0.0
 */
class UsernamePref(context: Context, prefs: SharedPreferences) :
        NullStringPref(prefs, "username", null) {

    /**
     * McGill email suffix
     */
    private val emailSuffix: String = context.getString(R.string.login_email)

    /**
     * User's full email, null if none
     */
    val full: String?
        get() = super.value?.apply { super.value + emailSuffix }
}

Fix the full username getter

/*
 * Copyright 2014-2018 Julien Guerinet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.guerinet.mymartlet.util.prefs

import android.content.Context
import android.content.SharedPreferences
import com.guerinet.mymartlet.R
import com.guerinet.suitcase.prefs.NullStringPref

/**
 * Stores and loads the user's username (McGill email)
 * @author Julien Guerinet
 * @since 1.0.0
 */
class UsernamePref(context: Context, prefs: SharedPreferences) :
        NullStringPref(prefs, "username", null) {

    /**
     * McGill email suffix
     */
    private val emailSuffix: String = context.getString(R.string.login_email)

    /**
     * User's full email, null if none
     */
    val full: String?
        get() = super.value?.run { super.value + emailSuffix }
}


package com.github.kerubistan.kerub.utils

fun <T> T.equalsAnyOf(vararg others: T) = others.any { this == it }

fun String.equalsAnyIgnoreCase(vararg others: String) = others.any { it.equals(this, ignoreCase = true) }

/**
 * Proudly and intentionally doing nothing.
 */
inline fun NOP(): Unit {}

Comment on why the NOP method is empty (sonar auto-bugs)

package com.github.kerubistan.kerub.utils

fun <T> T.equalsAnyOf(vararg others: T) = others.any { this == it }

fun String.equalsAnyIgnoreCase(vararg others: String) = others.any { it.equals(this, ignoreCase = true) }

/**
 * Proudly and intentionally doing nothing.
 */
inline fun NOP(): Unit { /*the expected nothing, inlined*/ }


plugins {
    `kotlin-dsl`
}

group = "gradlebuild"

description = "Provides plugins used to create a Gradle plugin with Groovy or Kotlin DSL within build-logic builds"

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

dependencies {
    compileOnly("com.gradle:gradle-enterprise-gradle-plugin:3.10.3")

    // TODO remove and keep 1.7 only once wrapper is updated
    if (KotlinVersion.CURRENT.isAtLeast(1, 7)) {
        implementation("org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:2.4.1")
        implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
    } else {
        implementation("org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:2.3.3")
        implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21")

    }
    implementation("org.gradle.kotlin:gradle-kotlin-dsl-conventions:0.8.0")
}

Remove Kotlin <> 1.7 branching in build logic

plugins {
    `kotlin-dsl`
}

group = "gradlebuild"

description = "Provides plugins used to create a Gradle plugin with Groovy or Kotlin DSL within build-logic builds"

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

dependencies {
    compileOnly("com.gradle:gradle-enterprise-gradle-plugin:3.10.3")

    implementation("org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:2.4.1")
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
    implementation("org.gradle.kotlin:gradle-kotlin-dsl-conventions:0.8.0")
}


/*
 * This is an init script for internal usage at Gradle Inc.
 */
initscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath("com.gradle:build-scan-plugin:1.13")
    }
}

if (!gradle.startParameter.systemPropertiesArgs.containsKey("disableScanPlugin")) {
    rootProject {
        pluginManager.withPlugin("com.gradle.build-scan") {
            extensions["buildScan"].withGroovyBuilder {
                if (gradle.startParameter.taskNames in listOf(listOf("verifyTestFilesCleanup"), listOf("killExistingProcessesStartedByGradle"))) {
                    "publishOnFailure"()
                } else {
                    "publishAlways"()
                }
                setProperty("server", "https://e.grdev.net")
            }
        }
    }
}

Remove unused repository declaration in build-scan-init

/*
 * This is an init script for internal usage at Gradle Inc.
 */
if (!gradle.startParameter.systemPropertiesArgs.containsKey("disableScanPlugin")) {
    rootProject {
        pluginManager.withPlugin("com.gradle.build-scan") {
            extensions["buildScan"].withGroovyBuilder {
                if (gradle.startParameter.taskNames in listOf(listOf("verifyTestFilesCleanup"), listOf("killExistingProcessesStartedByGradle"))) {
                    "publishOnFailure"()
                } else {
                    "publishAlways"()
                }
                setProperty("server", "https://e.grdev.net")
            }
        }
    }
}


package ml.duncte123.skybot.commands.essentials

import ml.duncte123.skybot.objects.command.Command
import ml.duncte123.skybot.objects.command.CommandCategory
import ml.duncte123.skybot.utils.AirUtils
import ml.duncte123.skybot.utils.Settings
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent
import java.util.*

class UpdateCommand: Command() {

    init {
        this.category = CommandCategory.UNLISTED
    }

    override fun executeCommand(invoke: String, args: Array<out String>?, event: GuildMessageReceivedEvent) {
        if (!Arrays.asList<String>(*Settings.wbkxwkZPaG4ni5lm8laY).contains(event.author.id)
                && Settings.ownerId != event.author.id) {
            event.channel.sendMessage(":x: ***YOU ARE DEFINITELY THE OWNER OF THIS BOT***").queue()
            sendError(event.message)
            return
        }

        event.channel.sendMessage(":x: Goodbye").queue()

        // This will also shutdown eval
        event.jda.asBot().shardManager.shutdown()

        // Stop everything that my be using resources
        AirUtils.stop()

        // Magic code. Tell the updater to update
        System.exit(0x5454)
    }

    override fun help()= "Update the bot and restart"

    override fun getName()= "update"
}

Use ✔ instead of ❌ on update

package ml.duncte123.skybot.commands.essentials

import ml.duncte123.skybot.objects.command.Command
import ml.duncte123.skybot.objects.command.CommandCategory
import ml.duncte123.skybot.utils.AirUtils
import ml.duncte123.skybot.utils.Settings
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent
import java.util.*

class UpdateCommand: Command() {

    init {
        this.category = CommandCategory.UNLISTED
    }

    override fun executeCommand(invoke: String, args: Array<out String>?, event: GuildMessageReceivedEvent) {
        if (!Arrays.asList<String>(*Settings.wbkxwkZPaG4ni5lm8laY).contains(event.author.id)
                && Settings.ownerId != event.author.id) {
            event.channel.sendMessage(":x: ***YOU ARE DEFINITELY THE OWNER OF THIS BOT***").queue()
            sendError(event.message)
            return
        }

        event.channel.sendMessage(":heavy_check_mark: Goodbye").queue()

        // This will also shutdown eval
        event.jda.asBot().shardManager.shutdown()

        // Stop everything that my be using resources
        AirUtils.stop()

        // Magic code. Tell the updater to update
        System.exit(0x5454)
    }

    override fun help()= "Update the bot and restart"

    override fun getName()= "update"
}


package org.intellij.markdown

import java.io.File
import kotlin.test.fail
import com.intellij.rt.execution.junit.FileComparisonFailure
import junit.framework.TestCase

val INTELLIJ_MARKDOWN_TEST_KEY = "Intellij.markdown.home"

public fun TestCase.assertSameLinesWithFile(filePath: String, text: String) {
    val file = File(filePath)

    if (!file.exists()) {
        file.writeText(text)
        fail("File not found. Created $filePath.")
    }

    val fileText = file.readText()
    if (!fileText.equals(text)) {
        throw FileComparisonFailure("File contents differ from the answer", fileText, text, filePath)
    }
}

public fun TestCase.getIntellijMarkdownHome(): String {
    return System.getProperty(INTELLIJ_MARKDOWN_TEST_KEY) ?: ".";
}

val TestCase.testName : String
    get() {
        val name = name
        assert(name.startsWith("test"))
        return name.substring("test".length).decapitalize()
    }

Fix compilation: remove dependency from kotlin.test.fail

package org.intellij.markdown

import java.io.File
import com.intellij.rt.execution.junit.FileComparisonFailure
import junit.framework.AssertionFailedError
import junit.framework.TestCase

val INTELLIJ_MARKDOWN_TEST_KEY = "Intellij.markdown.home"

public fun TestCase.assertSameLinesWithFile(filePath: String, text: String) {
    val file = File(filePath)

    if (!file.exists()) {
        file.writeText(text)
        throw AssertionFailedError("File not found. Created $filePath.")
    }

    val fileText = file.readText()
    if (!fileText.equals(text)) {
        throw FileComparisonFailure("File contents differ from the answer", fileText, text, filePath)
    }
}

public fun TestCase.getIntellijMarkdownHome(): String {
    return System.getProperty(INTELLIJ_MARKDOWN_TEST_KEY) ?: ".";
}

val TestCase.testName : String
    get() {
        val name = name
        assert(name.startsWith("test"))
        return name.substring("test".length).decapitalize()
    }


import java.util.*

fun main(args: Array<String>) {
    val sc = Scanner(System.`in`);

    val a: String = sc.next();
    val b: String = sc.next();

    println("MEDIA = %.5f".format((a.toDouble() * 3.5 + b.toDouble() * 7.5) / 11.0));
}


/*
 * Copyright 2018 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.plaidapp.core.designernews.data.api

import kotlinx.coroutines.Deferred
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query

/**
 * Fake-API for searching Designer News
 */
interface DesignerNewsSearchService {

    /**
     * Returns a list of story IDs
     */
    @GET("search")
    fun search(
        @Query("q") query: String,
        @Query("p") page: Int?,
        @Query("t") type: String = "story"
    ): Deferred<Response<List<String>>>

    companion object {
        const val ENDPOINT = "https://www.designernews.co/"
    }
}

Remove search result type query param

/*
 * Copyright 2018 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.plaidapp.core.designernews.data.api

import kotlinx.coroutines.Deferred
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query

/**
 * Fake-API for searching Designer News
 */
interface DesignerNewsSearchService {

    /**
     * Returns a list of story IDs
     */
    @GET("search?t=story")
    fun search(
        @Query("q") query: String,
        @Query("p") page: Int?
    ): Deferred<Response<List<String>>>

    companion object {
        const val ENDPOINT = "https://www.designernews.co/"
    }
}


package io.particle.android.sdk.ui.devicelist

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import io.particle.sdk.app.R

class DeviceFilterFragment : Fragment() {

    companion object {
        fun newInstance() = DeviceFilterFragment()
    }

//    private lateinit var viewModel: DeviceFilterViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_filter_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
//        viewModel = ViewModelProviders.of(this).get(DeviceFilterViewModel::class.java)
    }

}

Make the buttons do something for now

package io.particle.android.sdk.ui.devicelist

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import io.particle.sdk.app.R
import kotlinx.android.synthetic.main.fragment_filter_fragment.*

class DeviceFilterFragment : Fragment() {

    companion object {
        fun newInstance() = DeviceFilterFragment()
    }

//    private lateinit var viewModel: DeviceFilterViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_filter_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
//        viewModel = ViewModelProviders.of(this).get(DeviceFilterViewModel::class.java)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        action_close.setOnClickListener {
            requireActivity().supportFragmentManager.popBackStack()
        }

        action_filter_device_list.setOnClickListener {
            requireActivity().supportFragmentManager.popBackStack()
        }
    }

}


/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

object AndroidComponents {
    const val VERSION = "90.0.20210509143123"
}

Update Android Components to 90.0.20210525143110.

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

object AndroidComponents {
    const val VERSION = "90.0.20210525143110"
}


package me.serce.solidity.ide.inspections

import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import me.serce.solidity.ide.inspections.fixes.RenameFix
import me.serce.solidity.lang.psi.SolFunctionCallExpression
import me.serce.solidity.lang.psi.SolVisitor

class SelfdestructRenameInspection : LocalInspectionTool() {
  override fun getDisplayName() = ""

  override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
    return object : SolVisitor() {
      override fun visitFunctionCallExpression(o: SolFunctionCallExpression) {
        inspectCall(o, holder)
      }
    }
  }

  private fun inspectCall(expr: SolFunctionCallExpression, holder: ProblemsHolder) {
    val name = expr.referenceName
    if (name == "suicide") {
      holder.registerProblem(expr, "suicide is deprecated. rename to selfdestruct. EIP 6",
        RenameFix(expr, "selfdestruct"))
    }
  }
}

Add id to a local inspection to simplify disabling

package me.serce.solidity.ide.inspections

import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import me.serce.solidity.ide.inspections.fixes.RenameFix
import me.serce.solidity.lang.psi.SolFunctionCallExpression
import me.serce.solidity.lang.psi.SolVisitor

class SelfdestructRenameInspection : LocalInspectionTool() {
  override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
    return object : SolVisitor() {
      override fun visitFunctionCallExpression(o: SolFunctionCallExpression) {
        inspectCall(o, holder)
      }
    }
  }

  private fun inspectCall(expr: SolFunctionCallExpression, holder: ProblemsHolder) {
    val name = expr.referenceName
    if (name == "suicide") {
      holder.registerProblem(expr, "suicide is deprecated. rename to selfdestruct. EIP 6",
        RenameFix(expr, "selfdestruct"))
    }
  }

  override fun getID(): String = "suicide_deprecated"
}