package by.dev.madhead.doktor.pipeline

import by.dev.madhead.doktor.Messages
import by.dev.madhead.doktor.model.DoktorConfig
import by.dev.madhead.doktor.util.diagnose
import hudson.AbortException
import hudson.FilePath
import hudson.model.TaskListener
import org.jenkinsci.plugins.workflow.steps.StepContext
import org.jenkinsci.plugins.workflow.steps.StepExecution
import java.io.Serializable

class DoktorStepExecution(context: StepContext, val doktorConfig: DoktorConfig) : StepExecution(context), Serializable {
	companion object {
		private val serialVersionUID = 1L
	}

	override fun start(): Boolean {
		diagnose(
			doktorConfig,
			context.get(FilePath::class.java) ?: throw AbortException(Messages.doktor_hudson_AbortException_AbortException_workspaceRequired()),
			context.get(TaskListener::class.java) ?: throw AbortException(Messages.doktor_hudson_AbortException_AbortException_taskListenerRequired())
		)
			.subscribe(
				{},
				{ context.onFailure(it) },
				{ context.onSuccess(null) }
			)

		return false
	}

	override fun stop(cause: Throwable) {
		TODO("not implemented")
	}
}

Switch to synchronous pipeline steps

package by.dev.madhead.doktor.pipeline

import by.dev.madhead.doktor.Messages
import by.dev.madhead.doktor.model.DoktorConfig
import by.dev.madhead.doktor.util.diagnose
import hudson.AbortException
import hudson.FilePath
import hudson.model.TaskListener
import org.jenkinsci.plugins.workflow.steps.StepContext
import org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution

class DoktorStepExecution(context: StepContext, val doktorConfig: DoktorConfig) : SynchronousNonBlockingStepExecution<Void>(context) {
	override fun run(): Void? {
		try {
			diagnose(
				doktorConfig,
				context.get(FilePath::class.java) ?: throw AbortException(Messages.doktor_hudson_AbortException_AbortException_workspaceRequired()),
				context.get(TaskListener::class.java) ?: throw AbortException(Messages.doktor_hudson_AbortException_AbortException_taskListenerRequired())
			).blockingSubscribe()

			return null
		} catch (exception: Throwable) {
			throw AbortException(exception.message)
		}
	}
}


/*
 * Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.android.tv.reference

import android.app.Application
import timber.log.Timber

/**
 * Initializes libraries, such as Timber, and sets up application wide settings.
 */
class TvReferenceApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // TODO(b/162013888): Plant a timber tree for non-debug builds.
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        }
    }
}

Enable StrictMode for debug builds

/*
 * Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.android.tv.reference

import android.app.Application
import android.os.StrictMode
import timber.log.Timber

/**
 * Initializes libraries, such as Timber, and sets up application wide settings.
 */
class TvReferenceApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        if (BuildConfig.DEBUG) {
            enableStrictMode()
        }

        // TODO(b/162013888): Plant a timber tree for non-debug builds.
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        }
    }

    private fun enableStrictMode() {
        StrictMode.setThreadPolicy(
            StrictMode.ThreadPolicy.Builder()
                .detectDiskReads()
                .detectDiskWrites()
                .detectNetwork()
                .penaltyLog()
                .build()
        )
    }
}


package de.markusfisch.android.binaryeye.app

import android.app.Application
import android.support.v8.renderscript.RenderScript
import de.markusfisch.android.binaryeye.data.Database
import de.markusfisch.android.binaryeye.preference.Preferences

val db = Database()
val prefs = Preferences()

class BinaryEyeApp : Application() {
	override fun onCreate() {
		super.onCreate()
		prefs.init(this)

		if (prefs.forceCompat ||
			System.getProperty("os.version")?.contains(
				"lineageos", true
			) == true
		) {
			// required to make RenderScript work on Lineage 16.0
			RenderScript.forceCompat()
		}

		db.open(this)
	}
}

Remove special RenderScript handling for LineageOS

package de.markusfisch.android.binaryeye.app

import android.app.Application
import android.support.v8.renderscript.RenderScript
import de.markusfisch.android.binaryeye.data.Database
import de.markusfisch.android.binaryeye.preference.Preferences

val db = Database()
val prefs = Preferences()

class BinaryEyeApp : Application() {
	override fun onCreate() {
		super.onCreate()
		prefs.init(this)

		if (prefs.forceCompat) {
			RenderScript.forceCompat()
		}

		db.open(this)
	}
}


package io.gitlab.arturbosch.detekt.cli.console

import io.gitlab.arturbosch.detekt.api.ConsoleReport
import io.gitlab.arturbosch.detekt.api.Detektion
import io.gitlab.arturbosch.detekt.api.PREFIX
import io.gitlab.arturbosch.detekt.api.format

/**
 * @author Artur Bosch
 */
class ProjectStatisticsReport : ConsoleReport() {

	override val priority: Int = 10

	override fun render(detektion: Detektion): String? {
		val metrics = detektion.metrics
		if (metrics.isEmpty()) return null
		return with(StringBuilder()) {
			append("Project Statistics:".format())
			metrics.forEach { append(it.toString().format(PREFIX)) }
			toString()
		}
	}
}

Sort project metrics by priority

package io.gitlab.arturbosch.detekt.cli.console

import io.gitlab.arturbosch.detekt.api.ConsoleReport
import io.gitlab.arturbosch.detekt.api.Detektion
import io.gitlab.arturbosch.detekt.api.PREFIX
import io.gitlab.arturbosch.detekt.api.format

/**
 * @author Artur Bosch
 */
class ProjectStatisticsReport : ConsoleReport() {

	override val priority: Int = 10

	override fun render(detektion: Detektion): String? {
		val metrics = detektion.metrics
		if (metrics.isEmpty()) return null
		return with(StringBuilder()) {
			append("Project Statistics:".format())
			metrics.sortedBy { it.priority }
					.reversed()
					.forEach { append(it.toString().format(PREFIX)) }
			toString()
		}
	}
}


package locationProvider

import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.base.resolvers.local.DefaultLocationProvider
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
import org.junit.Assert.assertNotEquals
import org.junit.Test

class DefaultLocationProviderTest: AbstractCoreTest() {
    @Test
    fun `#644 same directory for module and package`() {
        val configuration = dokkaConfiguration {
            passes {
                pass {
                    sourceRoots = listOf("src/")
                }
            }
        }

        testInline(
            """
            |/src/main/kotlin/basic/Test.kt
            |
            |class Test {
            |   val x = 1
            |}
        """.trimMargin(),
            configuration
        ) {
            var context: DokkaContext? = null
            pluginsSetupStage = {
                context = it
            }

            pagesGenerationStage = { module ->
                val lp = DefaultLocationProvider(module, context!!)
                assertNotEquals(lp.resolve(module.children.single()).removePrefix("/"), lp.resolve(module))
            }
        }
    }
}

Fix junit imports in tests

package locationProvider

import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.base.resolvers.local.DefaultLocationProvider
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
import org.junit.jupiter.api.Assertions.assertNotEquals
import org.junit.jupiter.api.Test

class DefaultLocationProviderTest: AbstractCoreTest() {
    @Test
    fun `#644 same directory for module and package`() {
        val configuration = dokkaConfiguration {
            passes {
                pass {
                    sourceRoots = listOf("src/")
                }
            }
        }

        testInline(
            """
            |/src/main/kotlin/basic/Test.kt
            |
            |class Test {
            |   val x = 1
            |}
        """.trimMargin(),
            configuration
        ) {
            var context: DokkaContext? = null
            pluginsSetupStage = {
                context = it
            }

            pagesGenerationStage = { module ->
                val lp = DefaultLocationProvider(module, context!!)
                assertNotEquals(lp.resolve(module.children.single()).removePrefix("/"), lp.resolve(module))
            }
        }
    }
}


package io.mironov.smuggler.sample

import java.util.Random

class SmugglerGenerator(private val seed: Long) {
  private val random = Random(seed)

  fun nextBoolean(): Boolean {
    return random.nextBoolean()
  }

  fun nextInt(): Int {
    return random.nextInt()
  }

  fun nextLong(): Long {
    return random.nextLong()
  }

  fun nextFloat(): Float {
    return random.nextFloat()
  }

  fun nextDouble(): Double {
    return random.nextDouble()
  }

  fun nextShort(): Short {
    return random.nextInt().toShort()
  }

  fun nextByte(): Byte {
    return random.nextInt().toByte()
  }

  fun nextChar(): Char {
    return random.nextInt().toChar()
  }

  fun nextString(): String {
    val length = random.nextInt(25)
    val builder = StringBuilder(length)

    for (i in 0..length - 1) {
      builder.append(nextChar())
    }

    return builder.toString()
  }
}

Introduce generator methods for arrays

package io.mironov.smuggler.sample

import java.util.Random

class SmugglerGenerator(private val seed: Long) {
  private val random = Random(seed)

  fun nextBoolean(): Boolean {
    return random.nextBoolean()
  }

  fun nextInt(): Int {
    return random.nextInt()
  }

  fun nextLong(): Long {
    return random.nextLong()
  }

  fun nextFloat(): Float {
    return random.nextFloat()
  }

  fun nextDouble(): Double {
    return random.nextDouble()
  }

  fun nextShort(): Short {
    return random.nextInt().toShort()
  }

  fun nextByte(): Byte {
    return random.nextInt().toByte()
  }

  fun nextChar(): Char {
    return random.nextInt().toChar()
  }

  fun nextString(): String {
    val length = random.nextInt(25)
    val builder = StringBuilder(length)

    for (i in 0..length - 1) {
      builder.append(nextChar())
    }

    String

    return builder.toString()
  }

  fun nextBooleanArray(): BooleanArray {
    return BooleanArray(random.nextInt(25)) { nextBoolean() }
  }

  fun nextIntArray(): IntArray {
    return IntArray(random.nextInt(25)) { nextInt() }
  }

  fun nextLongArray(): LongArray {
    return LongArray(random.nextInt(25)) { nextLong() }
  }

  fun nextFloatArray(): FloatArray {
    return FloatArray(random.nextInt(25)) { nextFloat() }
  }

  fun nextDoubleArray(): DoubleArray {
    return DoubleArray(random.nextInt(25)) { nextDouble() }
  }

  fun nextShortArray(): ShortArray {
    return ShortArray(random.nextInt(25)) { nextShort() }
  }

  fun nextByteArray(): ByteArray {
    return ByteArray(random.nextInt(25)) { nextByte() }
  }

  fun nextCharArray(): CharArray {
    return CharArray(random.nextInt(25)) { nextChar() }
  }
}


// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.filePrediction.history

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.project.ProjectManagerListener

class FilePredictionHistory(val project: Project) {
  companion object {
    private const val RECENT_FILES_LIMIT = 50

    fun getInstance(project: Project): FilePredictionHistory {
      return ServiceManager.getService(project, FilePredictionHistory::class.java)
    }
  }

  private var manager: FileHistoryManager

  init {
    manager = FileHistoryManager(FileHistoryPersistence.loadFileHistory(project), RECENT_FILES_LIMIT)

    project.messageBus.connect().subscribe(ProjectManager.TOPIC, object : ProjectManagerListener {
      override fun projectClosing(project: Project) {
        ApplicationManager.getApplication().executeOnPooledThread {
          FileHistoryPersistence.saveFileHistory(project, manager.getState())
        }
      }
    })
  }

  fun onFileOpened(fileUrl: String) = manager.onFileOpened(fileUrl)

  fun calcHistoryFeatures(fileUrl: String): FileHistoryFeatures = manager.calcHistoryFeatures(fileUrl)

  fun size(): Int = manager.size()

  fun cleanup() = manager.cleanup()
}

Use correct disposable for message bus subscription (fixes NextFilePrediction case of IDEA-232470)

// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.filePrediction.history

import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.project.ProjectManagerListener

class FilePredictionHistory(val project: Project) : Disposable {
  companion object {
    private const val RECENT_FILES_LIMIT = 50

    fun getInstance(project: Project): FilePredictionHistory {
      return ServiceManager.getService(project, FilePredictionHistory::class.java)
    }
  }

  private var manager: FileHistoryManager

  init {
    manager = FileHistoryManager(FileHistoryPersistence.loadFileHistory(project), RECENT_FILES_LIMIT)

    project.messageBus.connect(this).subscribe(ProjectManager.TOPIC, object : ProjectManagerListener {
      override fun projectClosing(project: Project) {
        ApplicationManager.getApplication().executeOnPooledThread {
          FileHistoryPersistence.saveFileHistory(project, manager.getState())
        }
      }
    })
  }

  fun onFileOpened(fileUrl: String) = manager.onFileOpened(fileUrl)

  fun calcHistoryFeatures(fileUrl: String): FileHistoryFeatures = manager.calcHistoryFeatures(fileUrl)

  fun size(): Int = manager.size()

  fun cleanup() = manager.cleanup()

  override fun dispose() {
  }
}


/*
 * 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.SharedPreferences
import com.guerinet.mymartlet.model.Term
import com.guerinet.suitcase.prefs.StringPref

/**
 * Stores and loads the list of [Term]s a user can currently register in
 * @author Julien Guerinet
 * @since 1.0.0
 */
class RegisterTermsPref(prefs: SharedPreferences) : StringPref(prefs, "register_terms", "") {

    var terms: List<Term> = value.split(",").map { Term.parseTerm(it) }
        set(value) {
            field = value
            super.value = value.joinToString(",") { term -> term.id }
        }

    override fun clear() {
        super.clear()
        terms = listOf()
    }
}

Fix parsing of empty register terms

/*
 * 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.SharedPreferences
import com.guerinet.mymartlet.model.Term
import com.guerinet.suitcase.prefs.StringPref

/**
 * Stores and loads the list of [Term]s a user can currently register in
 * @author Julien Guerinet
 * @since 1.0.0
 */
class RegisterTermsPref(prefs: SharedPreferences) : StringPref(prefs, "register_terms", "") {

    var terms: List<Term> = value.split(",").filter { it.isNotBlank() }.map { Term.parseTerm(it) }
        set(value) {
            field = value
            super.value = value.joinToString(",") { term -> term.id }
        }

    override fun clear() {
        super.clear()
        terms = listOf()
    }
}


package com.github.shiraji.permissionsdispatcherplugin.data

class AndroidGradleVersion(versionText: String) {
    private var major: Int
    private var minor: Int

    init {
        try {
            major = versionText.substringBefore(".").toInt()
            minor = versionText.substring(versionText.indexOf(".") + 1, versionText.lastIndexOf(".")).toInt()
        } catch (e: NumberFormatException) {
            major = -1
            minor = -1
        }
    }

    fun isHigherThan2_2() = major >= 2 && minor >= 2

    fun isValid() = major >= 0 && minor >= 0
}

Fix the problem with version check logic

package com.github.shiraji.permissionsdispatcherplugin.data

class AndroidGradleVersion(versionText: String) {
    private var major: Int
    private var minor: Int

    init {
        try {
            major = versionText.substringBefore(".").toInt()
            minor = versionText.substring(versionText.indexOf(".") + 1, versionText.lastIndexOf(".")).toInt()
        } catch (e: NumberFormatException) {
            major = -1
            minor = -1
        }
    }

    fun isHigherThan2_2() = major > 2 || major == 2 && minor >= 2

    fun isValid() = major >= 0 && minor >= 0
}


package configurations

import common.JvmCategory
import common.Os.LINUX
import model.CIBuildModel
import model.Stage

class SmokeTests(model: CIBuildModel, stage: Stage, testJava: JvmCategory, task: String = "smokeTest") : BaseGradleBuildType(model, stage = stage, init = {
    id("${model.projectId}_${task.capitalize()}s${testJava.version.name.capitalize()}")
    name = "Smoke Tests with 3rd Party Plugins ($task) - ${testJava.version.name.capitalize()}  Linux"
    description = "Smoke tests against third party plugins to see if they still work with the current Gradle version"

    params {
        param("env.ANDROID_HOME", LINUX.androidHome)
        param("env.ANDROID_SDK_ROOT", LINUX.androidHome)
        param("env.JAVA_HOME", LINUX.javaHomeForGradle())
    }

    features {
        publishBuildStatusToGithub(model)
    }

    applyTestDefaults(
        model,
        this,
        ":smoke-test:$task",
        timeout = 120,
        notQuick = true,
        extraParameters = buildScanTag("SmokeTests") +
            " -PtestJavaVersion=${testJava.version.major}" +
            " -PtestJavaVendor=${testJava.vendor.name}" +
            " -Porg.gradle.java.installations.auto-download=false"
    )
})

Remove extra space in configuration name


package com.jetbrains.rider.plugins.unity.asmdef

import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.jetbrains.jsonSchema.extension.JsonSchemaFileProvider
import com.jetbrains.jsonSchema.extension.JsonSchemaProviderFactory
import com.jetbrains.jsonSchema.extension.SchemaType
import com.jetbrains.rider.plugins.unity.ideaInterop.fileTypes.asmdef.AsmDefFileType

class AsmDefJsonSchemeProviderFactory : JsonSchemaProviderFactory {
    override fun getProviders(p0: Project): MutableList<JsonSchemaFileProvider> {
        return mutableListOf(
            object : JsonSchemaFileProvider {
                private val schemaFile = JsonSchemaProviderFactory.getResourceFile(this::class.java, "/schemas/unity/asmdef.json")
                override fun isAvailable(file: VirtualFile) = file.fileType == AsmDefFileType
                override fun getName() = "Unity Assembly Definition"
                override fun getSchemaFile() = schemaFile
                override fun getSchemaType() = SchemaType.embeddedSchema
            })
    }
}

Add link to asmdef schema on schemastore

package com.jetbrains.rider.plugins.unity.asmdef

import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.jetbrains.jsonSchema.extension.JsonSchemaFileProvider
import com.jetbrains.jsonSchema.extension.JsonSchemaProviderFactory
import com.jetbrains.jsonSchema.extension.SchemaType
import com.jetbrains.rider.plugins.unity.ideaInterop.fileTypes.asmdef.AsmDefFileType

class AsmDefJsonSchemeProviderFactory : JsonSchemaProviderFactory {
    override fun getProviders(p0: Project): MutableList<JsonSchemaFileProvider> {
        return mutableListOf(
            object : JsonSchemaFileProvider {
                private val schemaFile = JsonSchemaProviderFactory.getResourceFile(this::class.java, "/schemas/unity/asmdef.json")
                override fun isAvailable(file: VirtualFile) = file.fileType == AsmDefFileType
                override fun getName() = "Unity Assembly Definition"
                override fun getSchemaFile() = schemaFile
                override fun getSchemaType() = SchemaType.embeddedSchema
                override fun getRemoteSource() = "https://json.schemastore.org/asmdef.json"
            })
    }
}


import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.net.URL

plugins {
    `published-library`
}

dependencies {
    api(deps.moshi.oldestSupported)
    testImplementation(deps.junit)
    testImplementation(deps.truth)
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = freeCompilerArgs + listOf(
            "-opt-in=kotlin.RequiresOptIn"
        )
    }
}

tasks.compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = freeCompilerArgs + listOf(
            "-Xjvm-default=all"
        )
    }
}

tasks.withType<org.jetbrains.dokka.gradle.DokkaTask> {
    moduleName.set("kotshi")
    dokkaSourceSets {
        configureEach {
            sourceLink {
                localDirectory.set(file("src/main/kotlin"))
                remoteUrl.set(URL("https://github.com/ansman/kotshi/blob/master/src/main/kotlin"))
                remoteLineSuffix.set("#L")
            }
            externalDocumentationLink { url.set(URL("https://square.github.io/okio/2.x/okio/")) }
            externalDocumentationLink { url.set(URL("https://square.github.io/moshi/1.x/moshi/")) }
        }
    }
}

Fix the source link in dokka

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.net.URL

plugins {
    `published-library`
}

dependencies {
    api(deps.moshi.oldestSupported)
    testImplementation(deps.junit)
    testImplementation(deps.truth)
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = freeCompilerArgs + listOf(
            "-opt-in=kotlin.RequiresOptIn"
        )
    }
}

tasks.compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = freeCompilerArgs + listOf(
            "-Xjvm-default=all"
        )
    }
}

tasks.withType<org.jetbrains.dokka.gradle.DokkaTask> {
    moduleName.set("kotshi")
    dokkaSourceSets {
        configureEach {
            sourceLink {
                localDirectory.set(file("src/main/kotlin"))
                remoteUrl.set(URL("https://github.com/ansman/kotshi/blob/main/api/src/main/kotlin"))
                remoteLineSuffix.set("#L")
            }
            externalDocumentationLink { url.set(URL("https://square.github.io/okio/2.x/okio/")) }
            externalDocumentationLink { url.set(URL("https://square.github.io/moshi/1.x/moshi/")) }
        }
    }
}


/*
 * Copyright 2016 Sascha Peilicke
 *
 * 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.
 */

plugins {
    id("com.android.application")
}

android {
    compileSdkVersion(28)

    defaultConfig {
        applicationId = "com.example.versioninfo"
        minSdkVersion(14)
        targetSdkVersion(28)
        versionCode = 140201
        versionName = "2.1.0"
        base.archivesBaseName = "$applicationId-$versionName"
    }

    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug" // Allow installation in parallel to release builds
        }
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
            signingConfig = signingConfigs.getByName("debug")
        }
    }
}

dependencies {
    implementation(project(":versioninfo"))
    implementation("androidx.appcompat:appcompat:1.0.0")
}

Update appcompat androidx library to 1.0.2

/*
 * Copyright 2016 Sascha Peilicke
 *
 * 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.
 */

plugins {
    id("com.android.application")
}

android {
    compileSdkVersion(28)

    defaultConfig {
        applicationId = "com.example.versioninfo"
        minSdkVersion(14)
        targetSdkVersion(28)
        versionCode = 140201
        versionName = "2.1.0"
        base.archivesBaseName = "$applicationId-$versionName"
    }

    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug" // Allow installation in parallel to release builds
        }
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
            signingConfig = signingConfigs.getByName("debug")
        }
    }
}

dependencies {
    implementation(project(":versioninfo"))
    implementation("androidx.appcompat:appcompat:1.0.2")
}


/*
 * Copyright (C) 2018 Yaroslav Mytkalyk
 *
 * 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.doctoror.particleswallpaper.userprefs.multisampling

interface MultisamplingPreferenceView {

    fun setPreferenceSupported(supported: Boolean)

    fun setEntries(keys: Array<CharSequence>)

    fun setEntryValues(values: Array<CharSequence>)

    fun setValue(value: Int)

    fun showRestartDialog()
}

Adjust entries values to match platform signature

/*
 * Copyright (C) 2018 Yaroslav Mytkalyk
 *
 * 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.doctoror.particleswallpaper.userprefs.multisampling

interface MultisamplingPreferenceView {

    fun setPreferenceSupported(supported: Boolean)

    fun setEntries(entries: Array<CharSequence>?)

    fun setEntryValues(entryValues: Array<CharSequence>?)

    fun setValue(value: Int)

    fun showRestartDialog()
}


package v_builders.examples

fun todoTask38(): Nothing = TODO(
    """
        Task 38.
        The previous examples can be rewritten with the library function 'apply' (see examples below).
        Write your own implementation of the function 'apply' named 'myApply'.
    """
)

fun <T> T.myApply(f: T.() -> Unit): T {
    todoTask38()
}

fun buildString(): String {
    return StringBuilder().myApply {
        append("Numbers: ")
        for (i in 1..10) {
            append(i)
        }
    }.toString()
}

fun buildMap(): Map<Int, String> {
    return hashMapOf<Int, String>().myApply {
        put(0, "0")
        for (i in 1..10) {
            put(i, "$i")
        }
    }
}

Complete koan 38 (the 'apply' function)

package v_builders.examples

fun todoTask38(): Nothing = TODO(
    """
        Task 38.
        The previous examples can be rewritten with the library function 'apply' (see examples below).
        Write your own implementation of the function 'apply' named 'myApply'.
    """
)

fun <T> T.myApply(f: T.() -> Unit): T {
    f()
    return this
}

fun buildString(): String {
    return StringBuilder().myApply {
        append("Numbers: ")
        for (i in 1..10) {
            append(i)
        }
    }.toString()
}

fun buildMap(): Map<Int, String> {
    return hashMapOf<Int, String>().myApply {
        put(0, "0")
        for (i in 1..10) {
            put(i, "$i")
        }
    }
}


package cases

// both valid
val variable = 5
val _variable = 5
// invalid start with _ is optional, but then lowercase!
val V_riable = 5
val _Variable = 5

//valid
fun fileMethod() {
}
//invalid
fun FileMethod() {
}
fun _fileMethod() {
}

@Suppress("unused")
class NamingConventions {

	//invalid
	val C_lassVariable = 5
	//valid
	val _classVariable = 5
	val classVariable = 5
	fun classMethod(){
	}
	//invalid
	fun _classmethod(){
	}
	fun Classmethod(){
	}
}
//invalid
class _NamingConventions{}
class namingConventions{}

object Bla {
	val STUFF = "stuff"
}

Use file suppress in naming convention test case

@file:Suppress("unused")

package cases

// both valid
val variable = 5
val _variable = 5
// invalid start with _ is optional, but then lowercase!
val V_riable = 5
val _Variable = 5

//valid
fun fileMethod() {
}
//invalid
fun FileMethod() {
}
fun _fileMethod() {
}

class NamingConventions {

	//invalid
	val C_lassVariable = 5
	//valid
	val _classVariable = 5
	val classVariable = 5
	fun classMethod(){
	}
	//invalid
	fun _classmethod(){
	}
	fun Classmethod(){
	}
}
//invalid
class _NamingConventions{}
class namingConventions{}

object Bla {
	val STUFF = "stuff"
}


package com.github.shyiko.ktlint.ruleset.standard

import com.github.shyiko.ktlint.core.LintError
import com.github.shyiko.ktlint.test.format
import com.github.shyiko.ktlint.test.lint
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test

class NoConsecutiveBlankLinesRuleTest {

    @Test
    fun testLint() {
        assertThat(NoConsecutiveBlankLinesRule().lint("fun main() {\n\n\n}")).isEqualTo(listOf(
            LintError(3, 1, "no-consecutive-blank-lines", "Needless blank line(s)")
        ))
        assertThat(NoConsecutiveBlankLinesRule().lint("fun main() {println(\"\"\"\n\n\n\"\"\")}")).isEmpty()
    }

    @Test
    fun testFormat() {
        assertThat(NoConsecutiveBlankLinesRule().format(
            """
            fun main() {

            }

            """
        )).isEqualTo(
            """
            fun main() {

            }

            """
        )
    }

}

Add more unit test for NoConsecutiveBlankLinesRule

package com.github.shyiko.ktlint.ruleset.standard

import com.github.shyiko.ktlint.core.LintError
import com.github.shyiko.ktlint.test.format
import com.github.shyiko.ktlint.test.lint
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test

class NoConsecutiveBlankLinesRuleTest {
    @Test
    fun testLintInDeclarations() {
        assertThat(NoConsecutiveBlankLinesRule().lint(
            """fun a() {

            }

            fun b() {

            }"""
        )).isEqualTo(listOf(
            LintError(5, 1, "no-consecutive-blank-lines", "Needless blank line(s)")))
    }

    @Test
    fun testLintInCode() {
        assertThat(NoConsecutiveBlankLinesRule().lint(
            """fun main() {
                fun a()
                fun b()

                fun c()
            }"""
        )).isEqualTo(listOf(
            LintError(5, 1, "no-consecutive-blank-lines", "Needless blank line(s)")))
    }

    @Test
    fun testLintInString() {
        assertThat(NoConsecutiveBlankLinesRule().lint(
            "fun main() {println(\"\"\"\n\n\n\"\"\")}")).isEmpty()
    }

    @Test
    fun testFormatInDeclarations() {
        assertThat(NoConsecutiveBlankLinesRule().format(
            """
            fun a() {

            }

            fun b() {

            }
            """
        )).isEqualTo(
            """
            fun a() {

            }

            fun b() {

            }
            """
        )
    }

    @Test
    fun testFormatInCode() {
        assertThat(NoConsecutiveBlankLinesRule().format(
            """
            fun main() {
                fun a()
                fun b()

                fun c()

            }
            """
        )).isEqualTo(
            """
            fun main() {
                fun a()
                fun b()

                fun c()

            }
            """
        )
    }
}


package com.aerodeko.pfm.model

import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import java.util.*

/**
 * Created by rm on 10/12/2016.
 */

class EventManager(context: Context) {
    private val database: SQLiteDatabase

    init {
        val databaseHelper = EventDatabaseHelper(context)
        database = databaseHelper.writableDatabase
    }

    internal fun clearEvents() {
        database.delete(EventDatabaseHelper.Event.Table.NAME, null, null)
    }

    fun addEvent(value: Double, date: Calendar = Calendar.getInstance(), description: String? = null): Event? {
        val values = ContentValues()
        values.put(EventDatabaseHelper.Event.Columns.DATE, date.timeInMillis)
        values.put(EventDatabaseHelper.Event.Columns.VALUE, value)
        values.put(EventDatabaseHelper.Event.Columns.DESCRIPTION, description)

        val rowId = database.insert(EventDatabaseHelper.Event.Table.NAME, null, values)

        if (rowId != -1L) {
            return Event(date, value, description)
        } else {
            return null
        }
    }
}

Store event dates as days, not milliseconds.

package com.aerodeko.pfm.model

import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import com.aerodeko.pfm.extensions.timeInDays
import java.util.*

/**
 * Created by rm on 10/12/2016.
 */

class EventManager(context: Context) {
    private val database: SQLiteDatabase

    init {
        val databaseHelper = EventDatabaseHelper(context)
        database = databaseHelper.writableDatabase
    }

    internal fun clearEvents() {
        database.delete(EventDatabaseHelper.Event.Table.NAME, null, null)
    }

    fun addEvent(value: Double, date: Calendar = Calendar.getInstance(), description: String? = null): Event? {
        val values = ContentValues()
        values.put(EventDatabaseHelper.Event.Columns.DATE, date.timeInDays)
        values.put(EventDatabaseHelper.Event.Columns.VALUE, value)
        values.put(EventDatabaseHelper.Event.Columns.DESCRIPTION, description)

        val rowId = database.insert(EventDatabaseHelper.Event.Table.NAME, null, values)

        if (rowId != -1L) {
            return Event(date, value, description)
        } else {
            return null
        }
    }
}


val gitProps: Map<String, String> by extra

tasks {
  val collectFiles by creating(Copy::class) {
    dependsOn("jar", "generateGitProperties")
    from("$rootDir/etc/eb/.ebextensions") {
      into(".ebextensions")
    }
    from("$rootDir/etc/eb/Procfile")
    val jar = tasks.getByName<Jar>("jar")
    from(jar.outputs.files.singleFile) {
      rename { "application.jar" }
    }
    destinationDir = file("$buildDir/zip")
    doLast {
      copy {
        from("$rootDir/etc/eb/docker-compose.yml") {
          expand("hash" to gitProps["git.commit.id"])
        }
        into("$buildDir/zip")
      }
    }
  }

  val zipWithExtensions by creating(Zip::class) {
    dependsOn(collectFiles)
    from(collectFiles)
  }

  val unpack by creating(Copy::class) {
    dependsOn(named("bootJar"))
    from(zipTree(named("bootJar").get().outputs.files.singleFile)) {
      into("dependency")
    }
    from("$rootDir/etc/docker/entrypoint.sh") {
      into("dependency")
    }
    from("$rootDir/etc/docker/Dockerfile")
    from("$rootDir/etc/docker/rds-ca-2019-root.pem")
    into("build/docker")
  }

  named("assemble") {
    dependsOn(unpack, zipWithExtensions)
  }
}

Copy nginx config to .platform folder as well for amazon linux 2

val gitProps: Map<String, String> by extra

tasks {
  val collectFiles by creating(Copy::class) {
    dependsOn("jar", "generateGitProperties")
    from("$rootDir/etc/eb/.ebextensions") {
      into(".ebextensions")
    }
    from("$rootDir/etc/eb/.ebextensions/nginx") {
      into(".platform/nginx")
    }
    from("$rootDir/etc/eb/Procfile")
    val jar = tasks.getByName<Jar>("jar")
    from(jar.outputs.files.singleFile) {
      rename { "application.jar" }
    }
    destinationDir = file("$buildDir/zip")
    doLast {
      copy {
        from("$rootDir/etc/eb/docker-compose.yml") {
          expand("hash" to gitProps["git.commit.id"])
        }
        into("$buildDir/zip")
      }
    }
  }

  val zipWithExtensions by creating(Zip::class) {
    dependsOn(collectFiles)
    from(collectFiles)
  }

  val unpack by creating(Copy::class) {
    dependsOn(named("bootJar"))
    from(zipTree(named("bootJar").get().outputs.files.singleFile)) {
      into("dependency")
    }
    from("$rootDir/etc/docker/entrypoint.sh") {
      into("dependency")
    }
    from("$rootDir/etc/docker/Dockerfile")
    from("$rootDir/etc/docker/rds-ca-2019-root.pem")
    into("build/docker")
  }

  named("assemble") {
    dependsOn(unpack, zipWithExtensions)
  }
}


package de.axelrindle.broadcaster.model

import net.md_5.bungee.api.chat.BaseComponent
import net.md_5.bungee.chat.ComponentSerializer

/**
 * A `Message` describes a piece of information that will be broadcasted around the server.
 */
abstract class Message
/**
 * @param input The input text used for configuration.
 */
(protected val input: String)

/**
 * A `SimpleMessage` is just a container for holding a plain text message.
 */
class SimpleMessage(input: String) : Message(input) {

    /**
     * Returns just the input string to use as the message text.
     *
     * @return The [input].
     */
    fun getText(): String = input
}

/**
 * A `JsonMessage` is created from a json string and converted into an [Array] of [BaseComponent]s.
 *
 * @see ComponentSerializer.parse
 * @see BaseComponent
 */
class JsonMessage(input: String) : Message(input) {
    val components: Array<BaseComponent> = ComponentSerializer.parse(input)
}

Test whether required class exists

package de.axelrindle.broadcaster.model

import net.md_5.bungee.api.chat.BaseComponent
import net.md_5.bungee.chat.ComponentSerializer

/**
 * A `Message` describes a piece of information that will be broadcasted around the server.
 */
abstract class Message
/**
 * @param input The input text used for configuration.
 */
(protected val input: String)

/**
 * A `SimpleMessage` is just a container for holding a plain text message.
 */
class SimpleMessage(input: String) : Message(input) {

    /**
     * Returns just the input string to use as the message text.
     *
     * @return The [input].
     */
    fun getText(): String = input
}

/**
 * A `JsonMessage` is created from a json string and converted into an [Array] of [BaseComponent]s.
 *
 * @see ComponentSerializer.parse
 * @see BaseComponent
 */
class JsonMessage(input: String) : Message(input) {

    // test for class dependency
    init {
        Class.forName("net.md_5.bungee.chat.ComponentSerializer")
    }

    val components: Array<BaseComponent> = ComponentSerializer.parse(input)
}


package nl.rubensten.texifyidea.ui

import java.awt.image.BufferedImage
import javax.swing.*

/**
 * @author Sergei Izmailov
 */
class PreviewForm {

    var panel: JPanel? = null
    private var equationArea: JTextArea? = null
    private var outputArea: JTextArea? = null
    private var equationPanel: ImagePanel? = null
    private var latexOutputTab: JPanel? = null
    private var equationTab: JPanel? = null
    private var tabbedPane: JTabbedPane? = null

    fun setEquation(equation: String) {
        equationArea!!.text = equation
    }

    fun setPreview(image: BufferedImage, latexOutput: String) {
        equationPanel!!.setImage(image)
        outputArea!!.text = latexOutput
    }

    fun setLatexErrorMessage(errorMessage: String) {
        outputArea!!.text = errorMessage
        equationPanel!!.clearImage()
    }

    fun clear() {
        outputArea!!.text = ""
        equationArea!!.text = ""
        equationPanel!!.clearImage()
    }

}

Switch Preview Window to Equation tab on success and to Output on error

package nl.rubensten.texifyidea.ui

import java.awt.image.BufferedImage
import javax.swing.*

/**
 * @author Sergei Izmailov
 */
class PreviewForm {

    var panel: JPanel? = null
    private var equationArea: JTextArea? = null
    private var outputArea: JTextArea? = null
    private var equationPanel: ImagePanel? = null
    private var latexOutputTab: JPanel? = null
    private var equationTab: JPanel? = null
    private var tabbedPane: JTabbedPane? = null

    fun setEquation(equation: String) {
        equationArea!!.text = equation
    }

    fun setPreview(image: BufferedImage, latexOutput: String) {
        equationPanel!!.setImage(image)
        outputArea!!.text = latexOutput
        tabbedPane!!.selectedIndex = tabbedPane!!.indexOfComponent(equationTab)
    }

    fun setLatexErrorMessage(errorMessage: String) {
        outputArea!!.text = errorMessage
        equationPanel!!.clearImage()
        tabbedPane!!.selectedIndex = tabbedPane!!.indexOfComponent(latexOutputTab)
    }

    fun clear() {
        outputArea!!.text = ""
        equationArea!!.text = ""
        equationPanel!!.clearImage()
    }

}


package nl.hannahsten.texifyidea.util

import com.intellij.openapi.diagnostic.Logger

/**
 * Log messages to idea.log. During plugin development, it logs to build/idea-sandbox/system/log/idea.log.
 * @author Hannah Schellekens
 */
object Log {

    val logger: Logger by lazy { Logger.getInstance(Log::class.java) }

    /**
     * Sends a formatted info message to the IntelliJ logger.
     *
     * All messages start with the prefix `TEXIFY-IDEA - `.
     *
     * @param format
     *         How the log should be formatted, see also [String.format].
     * @param objects
     *         The objects to bind to the format.
     */
    @JvmStatic
    fun logf(format: String, vararg objects: Any?) = logger.info("TEXIFY-IDEA - " + format.format(*objects))
}

Fix formatting of log string

package nl.hannahsten.texifyidea.util

import com.intellij.openapi.diagnostic.Logger

/**
 * Log messages to idea.log. During plugin development, it logs to build/idea-sandbox/system/log/idea.log.
 * @author Hannah Schellekens
 */
object Log {

    private val logger: Logger by lazy { Logger.getInstance(Log::class.java) }

    /**
     * Sends an info message to the IntelliJ logger.
     *
     * All messages start with the prefix `TEXIFY-IDEA - `.
     */
    @JvmStatic
    fun logf(message: String) = logger.info("TEXIFY-IDEA - $message")
}


package io.datawire.boston.model

import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonProperty

data class ServicePort @JsonCreator constructor (
    @JsonProperty("port")
    val port: Int,

    @JsonProperty("secure")
    val secure: Boolean
)

Add a name to the port which indicates the purpose.

package io.datawire.boston.model

import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonProperty

/**
 *
 * @author Philip Lombardi <plombardi@datawire.iu
 */

data class ServicePort @JsonCreator constructor (

    /**
     * Indicates the named use for the port, for example, "http", "https", "ftp" or "gopher".
     */
    @JsonProperty("name")
    val name: String,

    /**
     * Indicates the port value.
     */
    @JsonProperty("port")
    val port: Int,

    /**
     * todo(plombardi): might remove this; not convinced it's useful beyond being metadata that is indicated by the name
     *
     * Indicates whether the port is secured. Security is an implementation detail of the named protocol, for example,
     * if the named protocol is HTTPS then clients will need to support HTTPS.
     */
    @JsonProperty("secure")
    val secure: Boolean
)


package me.devsaki.hentoid.database.domains

import io.objectbox.annotation.Entity
import io.objectbox.annotation.Id
import me.devsaki.hentoid.util.Helper

@Entity
data class DuplicateEntry(
        val referenceId: Long,
        val referenceSize: Long,
        var duplicateId: Long = -1,
        val titleScore: Float = 0f,
        val coverScore: Float = 0f,
        val artistScore: Float = 0f,
        @Id var id: Long = 0) { // ID is mandatory for ObjectBox to work

    @Transient
    private var totalScore = -1f

    @Transient
    var nbDuplicates = 1

    @Transient
    var referenceContent: Content? = null

    @Transient
    var duplicateContent: Content? = null

    @Transient
    var keep: Boolean? = null

    fun calcTotalScore(): Float {
        if (totalScore > -1) return totalScore
        // Calculate
        val operands = ArrayList<android.util.Pair<Float, Float>>()
        if (titleScore > -1) operands.add(android.util.Pair<Float, Float>(titleScore, 1f))
        if (coverScore > -1) operands.add(android.util.Pair<Float, Float>(coverScore, 1f))
        if (artistScore > -1) operands.add(android.util.Pair<Float, Float>(artistScore, 0.5f))
        return Helper.weigthedAverage(operands)
    }

    fun hash64(): Long {
        return Helper.hash64(("$referenceId.$duplicateId").toByteArray())
    }
}

Change role of artist score in the global scoring

package me.devsaki.hentoid.database.domains

import io.objectbox.annotation.Entity
import io.objectbox.annotation.Id
import me.devsaki.hentoid.util.Helper

@Entity
data class DuplicateEntry(
    val referenceId: Long,
    val referenceSize: Long,
    var duplicateId: Long = -1,
    val titleScore: Float = 0f,
    val coverScore: Float = 0f,
    val artistScore: Float = 0f,
    @Id var id: Long = 0
) { // ID is mandatory for ObjectBox to work

    @Transient
    private var totalScore = -1f

    @Transient
    var nbDuplicates = 1

    @Transient
    var referenceContent: Content? = null

    @Transient
    var duplicateContent: Content? = null

    @Transient
    var keep: Boolean? = null

    fun calcTotalScore(): Float {
        // Try to fetch pre-calculated score, if present
        if (totalScore > -1) return totalScore
        // Calculate
        val operands = ArrayList<android.util.Pair<Float, Float>>()
        if (titleScore > -1) operands.add(android.util.Pair<Float, Float>(titleScore, 1f))
        if (coverScore > -1) operands.add(android.util.Pair<Float, Float>(coverScore, 1f))
        return Helper.weigthedAverage(operands) * (if (artistScore > -1) artistScore else 1f)
    }

    fun hash64(): Long {
        return Helper.hash64(("$referenceId.$duplicateId").toByteArray())
    }
}


package backend.model.location

import backend.exceptions.DomainException
import backend.model.BasicEntity
import backend.model.event.Team
import backend.model.misc.Coord
import backend.model.posting.Posting
import backend.model.user.Participant
import backend.util.distanceCoordsKM
import java.time.LocalDateTime
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.ManyToOne
import javax.persistence.OneToOne

@Entity
class Location : BasicEntity {

    @Embedded
    lateinit var coord: Coord
        private set

    @ManyToOne
    var uploader: Participant? = null

    @OneToOne(mappedBy = "location")
    var posting: Posting? = null
        private set

    @ManyToOne
    var team: Team? = null

    lateinit var date: LocalDateTime

    var distance: Double? = null

    private constructor() : super()

    constructor(coord: Coord, uploader: Participant, date: LocalDateTime) {
        this.coord = coord
        this.team = uploader.currentTeam ?: throw DomainException("A user without a team can't upload locations")
        this.uploader = uploader
        this.date = date
        this.distance = distanceCoordsKM(from = team!!.event.startingLocation, to = coord)
    }
}

Make distance non nullable double

package backend.model.location

import backend.exceptions.DomainException
import backend.model.BasicEntity
import backend.model.event.Team
import backend.model.misc.Coord
import backend.model.posting.Posting
import backend.model.user.Participant
import backend.util.distanceCoordsKM
import java.time.LocalDateTime
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.ManyToOne
import javax.persistence.OneToOne

@Entity
class Location : BasicEntity {

    @Embedded
    lateinit var coord: Coord
        private set

    @ManyToOne
    var uploader: Participant? = null

    @OneToOne(mappedBy = "location")
    var posting: Posting? = null
        private set

    @ManyToOne
    var team: Team? = null

    lateinit var date: LocalDateTime

    var distance: Double = 0.0

    private constructor() : super()

    constructor(coord: Coord, uploader: Participant, date: LocalDateTime) {
        this.coord = coord
        this.team = uploader.currentTeam ?: throw DomainException("A user without a team can't upload locations")
        this.uploader = uploader
        this.date = date
        this.distance = distanceCoordsKM(from = team!!.event.startingLocation, to = coord)
    }
}


/*
 * Copyright 2018 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.activity

import android.app.Application
import leakcanary.LeakCanary
import shark.AndroidReferenceMatchers
import shark.ReferenceMatcher

class LeakCanaryApp : Application() {
    override fun onCreate() {
        super.onCreate()
        @Suppress("UNCHECKED_CAST")
        LeakCanary.config = LeakCanary.config.copy(
            referenceMatchers = (
                AndroidReferenceMatchers.appDefaults - AndroidReferenceMatchers
                    .INPUT_METHOD_MANAGER_IS_TERRIBLE
                ) as List<ReferenceMatcher>
        )
    }
}

Use MultiDexApplication for activity androidTest

/*
 * Copyright 2018 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.activity

import androidx.multidex.MultiDexApplication
import leakcanary.LeakCanary
import shark.AndroidReferenceMatchers
import shark.ReferenceMatcher

class LeakCanaryApp : MultiDexApplication() {
    override fun onCreate() {
        super.onCreate()
        @Suppress("UNCHECKED_CAST")
        LeakCanary.config = LeakCanary.config.copy(
            referenceMatchers = (
                AndroidReferenceMatchers.appDefaults - AndroidReferenceMatchers
                    .INPUT_METHOD_MANAGER_IS_TERRIBLE
                ) as List<ReferenceMatcher>
        )
    }
}


/*
 * Minecraft Dev for IntelliJ
 *
 * https://minecraftdev.org
 *
 * Copyright (c) 2019 minecraft-dev
 *
 * MIT License
 */

package com.demonwav.mcdev.update

import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.util.text.VersionComparatorUtil

sealed class PluginUpdateStatus : Comparable<PluginUpdateStatus> {

    fun mergeWith(other: PluginUpdateStatus): PluginUpdateStatus {
        return maxOf(this, other)
    }

    protected abstract fun getVersionString(): String?

    override fun compareTo(other: PluginUpdateStatus): Int {
        val thisVersion = other.getVersionString() ?: return 1
        val otherVersion = other.getVersionString() ?: return -1
        return VersionComparatorUtil.compare(thisVersion, otherVersion)
    }

    object LatestVersionInstalled : PluginUpdateStatus() {
        override fun getVersionString(): String? = PluginUtil.pluginVersion
    }

    class Update(val pluginDescriptor: IdeaPluginDescriptor, val hostToInstallFrom: String?) : PluginUpdateStatus() {
        override fun getVersionString(): String? = this.pluginDescriptor.version
    }

    class CheckFailed(val message: String) : PluginUpdateStatus() {
        override fun getVersionString(): String? = null
    }
}

Fix typo in version comparison which only compared a single version

/*
 * Minecraft Dev for IntelliJ
 *
 * https://minecraftdev.org
 *
 * Copyright (c) 2019 minecraft-dev
 *
 * MIT License
 */

package com.demonwav.mcdev.update

import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.util.text.VersionComparatorUtil

sealed class PluginUpdateStatus : Comparable<PluginUpdateStatus> {

    protected abstract fun getVersionString(): String?

    fun mergeWith(other: PluginUpdateStatus): PluginUpdateStatus = maxOf(this, other)

    override fun compareTo(other: PluginUpdateStatus): Int {
        val thisVersion = this.getVersionString() ?: return 1
        val otherVersion = other.getVersionString() ?: return -1
        return VersionComparatorUtil.compare(thisVersion, otherVersion)
    }

    object LatestVersionInstalled : PluginUpdateStatus() {
        override fun getVersionString(): String? = PluginUtil.pluginVersion
    }

    class Update(val pluginDescriptor: IdeaPluginDescriptor, val hostToInstallFrom: String?) : PluginUpdateStatus() {
        override fun getVersionString(): String? = this.pluginDescriptor.version
    }

    class CheckFailed(val message: String) : PluginUpdateStatus() {
        override fun getVersionString(): String? = null
    }
}


/*
 * Copyright 2019-2021 Louis Cognault Ayeva Derman. Use of this source code is governed by the Apache 2.0 license.
 */

plugins {
    id("com.android.library")
    kotlin("multiplatform")
    publish
}

android {
    setDefaults(generateBuildConfig = true)
}

kotlin {
    android()
    configure(targets) { configureMavenPublication(publishReleaseVariantOnly = false) }
    sourceSets {
        commonMain.dependencies {
            api(splitties("experimental"))
        }
        androidMain.dependencies {
            api(splitties("views"))
            api(AndroidX.annotation)
            implementation(splitties("collections"))
            implementation(splitties("exceptions"))
            implementation(splitties("appctx"))
        }
        all {
            languageSettings.apply {
                enableLanguageFeature("InlineClasses")
                useExperimentalAnnotation("kotlin.RequiresOptIn")
                useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
                useExperimentalAnnotation("splitties.experimental.InternalSplittiesApi")
            }
        }
    }
}

Use old Kotlin JVM compiler backend for views-dsl module

/*
 * Copyright 2019-2021 Louis Cognault Ayeva Derman. Use of this source code is governed by the Apache 2.0 license.
 */

plugins {
    id("com.android.library")
    kotlin("multiplatform")
    publish
}

android {
    setDefaults(generateBuildConfig = true)
}

kotlin {
    android()
    configure(targets) { configureMavenPublication(publishReleaseVariantOnly = false) }
    sourceSets {
        commonMain.dependencies {
            api(splitties("experimental"))
        }
        androidMain.dependencies {
            api(splitties("views"))
            api(AndroidX.annotation)
            implementation(splitties("collections"))
            implementation(splitties("exceptions"))
            implementation(splitties("appctx"))
        }
        all {
            languageSettings.apply {
                enableLanguageFeature("InlineClasses")
                useExperimentalAnnotation("kotlin.RequiresOptIn")
                useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
                useExperimentalAnnotation("splitties.experimental.InternalSplittiesApi")
            }
        }
    }
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions.useOldBackend = true //TODO: Remove when https://youtrack.jetbrains.com/issue/KT-44972 is addressed.
    // See this comment on why it's needed: https://youtrack.jetbrains.com/issue/KT-44972#focus=Comments-27-5014161.0-0
}


/*
 * Copyright (C) 2018 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.presenter

import io.reactivex.Scheduler

abstract class SchedulerPresenter<V : Any> protected constructor(
  protected val computationScheduler: Scheduler,
  protected val ioScheduler: Scheduler,
  protected val mainThreadScheduler: Scheduler
) : Presenter<V>()

Enforce scheduler at creation time

/*
 * Copyright (C) 2018 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.presenter

import com.pyamsoft.pydroid.data.enforceComputation
import com.pyamsoft.pydroid.data.enforceIo
import com.pyamsoft.pydroid.data.enforceMainThread
import io.reactivex.Scheduler

abstract class SchedulerPresenter<V : Any> protected constructor(
  protected val computationScheduler: Scheduler,
  protected val ioScheduler: Scheduler,
  protected val mainThreadScheduler: Scheduler,
  enforce: Boolean = true
) : Presenter<V>() {

  constructor(
    computationScheduler: Scheduler,
    ioScheduler: Scheduler,
    mainThreadScheduler: Scheduler
  ) : this(computationScheduler, ioScheduler, mainThreadScheduler, enforce = false)

  init {
    if (enforce) {
      computationScheduler.enforceComputation()
      ioScheduler.enforceIo()
      mainThreadScheduler.enforceMainThread()
    }
  }
}


import org.apollo.game.model.entity.setting.PrivilegeLevel

on_command("broadcast", PrivilegeLevel.ADMINISTRATOR)
        .then { player ->
            val message = arguments.joinToString(" ")
            val broadcast = "[Broadcast] ${player.username.capitalize()}: $message"

            player.world.playerRepository.forEach { other ->
                other.sendMessage(broadcast)
            }
        }


/*
 * 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.ui.helper

import android.content.Context
import android.support.annotation.StringRes
import android.widget.Toast
import com.pyamsoft.pydroid.ui.helper.Toasty.Duration.LENGTH_LONG
import com.pyamsoft.pydroid.ui.helper.Toasty.Duration.LENGTH_SHORT

/**
 * Toasty is a drop in replacement for native Android toasts.
 *
 * It explicitly uses the application context to create the toast. If this is not done it is possible
 * though very unlikely for the Toast to leak the Activity context if it is displayed and then
 * dismissed very quickly
 */
class Toasty {

  init {
    throw RuntimeException("No instances")
  }

  enum class Duration {
    LENGTH_SHORT, LENGTH_LONG
  }

  companion object {

    @JvmStatic fun makeText(c: Context, message: CharSequence, duration: Duration): Toast {
      return Toast.makeText(c.applicationContext, message, when (duration) {
        LENGTH_SHORT -> Toast.LENGTH_SHORT
        LENGTH_LONG -> Toast.LENGTH_LONG
      })
    }

    @JvmStatic fun makeText(c: Context, @StringRes resId: Int, duration: Duration): Toast {
      return makeText(c, c.applicationContext.getString(resId), duration)
    }
  }
}


package chat.rocket.android.util.extensions

import android.view.View
import android.view.ViewAnimationUtils
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator

fun View.rotateBy(value: Float, duration: Long = 200) {
    animate()
        .rotationBy(value)
        .setDuration(duration)
        .start()
}

fun View.fadeInOrOut(startValue: Float, finishValue: Float, duration: Long = 200) {
    animate()
        .alpha(startValue)
        .setDuration(duration)
        .setInterpolator(DecelerateInterpolator())
        .withEndAction({
            animate()
                .alpha(finishValue)
                .setDuration(duration)
                .setInterpolator(AccelerateInterpolator()).start()
        }).start()

    if (startValue > finishValue) {
        setVisible(false)
    } else {
        setVisible(true)
    }
}

fun View.circularRevealOrUnreveal(centerX: Int, centerY: Int, startRadius: Float, endRadius: Float, duration: Long = 600) {
    val anim = ViewAnimationUtils.createCircularReveal(this, centerX, centerY, startRadius, endRadius)
    anim.duration = duration

    if (startRadius < endRadius) {
        setVisible(true)
    } else {
        setVisible(false)
    }

    anim.start()
}

Add function fadeIn and fadeOut (instead of having fadeInOrOut(...))

package chat.rocket.android.util.extensions

import android.view.View
import android.view.ViewAnimationUtils
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator

fun View.rotateBy(value: Float, duration: Long = 200) {
    animate()
        .rotationBy(value)
        .setDuration(duration)
        .start()
}

fun View.fadeIn(startValue: Float, finishValue: Float, duration: Long = 200) {
    animate()
        .alpha(startValue)
        .setDuration(duration)
        .setInterpolator(DecelerateInterpolator())
        .withEndAction({
            animate()
                .alpha(finishValue)
                .setDuration(duration)
                .setInterpolator(AccelerateInterpolator()).start()
        }).start()

    setVisible(true)
}

fun View.fadeOut(startValue: Float, finishValue: Float, duration: Long = 200) {
    animate()
        .alpha(startValue)
        .setDuration(duration)
        .setInterpolator(DecelerateInterpolator())
        .withEndAction({
            animate()
                .alpha(finishValue)
                .setDuration(duration)
                .setInterpolator(AccelerateInterpolator()).start()
        }).start()

    setVisible(false)
}

fun View.circularRevealOrUnreveal(centerX: Int, centerY: Int, startRadius: Float, endRadius: Float, duration: Long = 600) {
    val anim = ViewAnimationUtils.createCircularReveal(this, centerX, centerY, startRadius, endRadius)
    anim.duration = duration

    if (startRadius < endRadius) {
        setVisible(true)
    } else {
        setVisible(false)
    }

    anim.start()
}


/*
 * Licensed under Apache-2.0
 *
 * Designed and developed by Aidan Follestad (@afollestad)
 */
package com.afollestad.photoaffix.dialogs

import android.app.Dialog
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.photoaffix.R

/** @author Aidan Follestad (afollestad) */
class AboutDialog : DialogFragment() {

  companion object {
    private const val TAG = "[ABOUT_DIALOG]"

    fun show(context: AppCompatActivity) {
      val dialog = AboutDialog()
      dialog.show(context.supportFragmentManager, TAG)
    }
  }

  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return MaterialDialog(activity!!)
        .title(R.string.about)
        .message(
            res = R.string.about_body,
            html = true,
            lineHeightMultiplier = 1.6f
        )
        .positiveButton(R.string.dismiss)
  }
}

Tweak about dialog line spacing

/*
 * Licensed under Apache-2.0
 *
 * Designed and developed by Aidan Follestad (@afollestad)
 */
package com.afollestad.photoaffix.dialogs

import android.app.Dialog
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.photoaffix.R

/** @author Aidan Follestad (afollestad) */
class AboutDialog : DialogFragment() {

  companion object {
    private const val TAG = "[ABOUT_DIALOG]"

    fun show(context: AppCompatActivity) {
      val dialog = AboutDialog()
      dialog.show(context.supportFragmentManager, TAG)
    }
  }

  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return MaterialDialog(activity!!)
        .title(R.string.about)
        .message(
            res = R.string.about_body,
            html = true,
            lineHeightMultiplier = 1.4f
        )
        .positiveButton(R.string.dismiss)
  }
}


Add recycler view decoration for list header

package com.nkming.utils.widget.decorator

import android.graphics.Canvas
import android.graphics.Rect
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import com.nkming.utils.type.ext.childIterator

/**
 * Add a header view to a RecyclerList. Horizontal list is unsupported. Grid
 * layout is unsupported
 */
class HeaderDecoration(view: View, orientation: Int)
		: RecyclerView.ItemDecoration()
{
	companion object
	{
		const val HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL
		const val VERTICAL_LIST = LinearLayoutManager.VERTICAL
	}

	override fun onDraw(c: Canvas, parent: RecyclerView,
			state: RecyclerView.State)
	{
		for (child in parent.childIterator())
		{
			if (parent.getChildAdapterPosition(child) == 0)
			{
				_view.layout(parent.left, parent.top, parent.right,
						parent.top + _view.measuredHeight)
				val scrollOffset = _view.measuredHeight - child.top
				c.save()
				c.translate(0f, -scrollOffset.toFloat())
				_view.draw(c)
				c.restore()
			}
		}
	}

	override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView,
			state: RecyclerView.State)
	{
		if (parent.getChildAdapterPosition(view) > 0)
		{
			outRect.setEmpty()
			return
		}

		if (_view.measuredHeight == 0)
		{
			val heightSpec = when (_view.layoutParams.height)
			{
				ViewGroup.LayoutParams.MATCH_PARENT ->
				{
					View.MeasureSpec.makeMeasureSpec(parent.height,
							View.MeasureSpec.EXACTLY)
				}

				ViewGroup.LayoutParams.WRAP_CONTENT ->
				{
					// FIXME This probably is broken
					View.MeasureSpec.makeMeasureSpec(parent.height,
							View.MeasureSpec.AT_MOST)
				}

				else ->
				{
					View.MeasureSpec.makeMeasureSpec(_view.layoutParams.height,
							View.MeasureSpec.EXACTLY)
				}
			}
			_view.measure(View.MeasureSpec.makeMeasureSpec(parent.measuredWidth,
					View.MeasureSpec.AT_MOST), heightSpec)
		}
		outRect.set(0, _view.measuredHeight, 0, 0)
	}

	private val _view = view
	private val _orientation = orientation

	init
	{
		if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST)
		{
			throw IllegalArgumentException("invalid orientation")
		}
		if (orientation == HORIZONTAL_LIST)
		{
			throw IllegalArgumentException("horizontal not yet supported")
		}
	}
}


plugins {
    id("com.gradle.build-scan") version "1.6"
}

buildScan {
    setLicenseAgreementUrl("https://gradle.com/terms-of-service")
    setLicenseAgree("yes")
}

Upgrade the Build Scan Plugin to 1.7.1 in the build-scan sample

plugins {
    id("com.gradle.build-scan") version "1.7.1"
}

buildScan {
    setLicenseAgreementUrl("https://gradle.com/terms-of-service")
    setLicenseAgree("yes")
}


/*
 * Copyright 2013-2013 Eugene Petrenko
 *
 * 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.jonnyzzz.teamcity.plugins.node.common

/**
 * @author Eugene Petrenko (eugene.petrenko@gmail.com)
 * Date: 16.08.13 21:42
 */
class NVMBean {
  val NVMUsed : String = "Use_NodeJS_Install_Runner"
  val NVMAvailable : String = "node.js.nvm"
  val NVMFeatureType: String = "jonnyzzz.nvm"
  val NVMVersion : String = "version"
  val NVMSource : String = "fromSource"
  val NVMURL : String = "fromURL"

  val NVM_ArchiveUrl : String = "https://github.com/nvm-sh/nvm/archive/v0.35.3.zip"
  //"https://github.com/nvm-sh/nvm/archive/master.zip"
}

Update NVM url to current release (v0.39.2)

/*
 * Copyright 2013-2013 Eugene Petrenko
 *
 * 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.jonnyzzz.teamcity.plugins.node.common

/**
 * @author Eugene Petrenko (eugene.petrenko@gmail.com)
 * Date: 16.08.13 21:42
 */
class NVMBean {
  val NVMUsed : String = "Use_NodeJS_Install_Runner"
  val NVMAvailable : String = "node.js.nvm"
  val NVMFeatureType: String = "jonnyzzz.nvm"
  val NVMVersion : String = "version"
  val NVMSource : String = "fromSource"
  val NVMURL : String = "fromURL"

  val NVM_ArchiveUrl : String = "https://github.com/nvm-sh/nvm/archive/v0.39.2.zip"
  //"https://github.com/nvm-sh/nvm/archive/master.zip"
}


package text

import utils.readResourceLines

fun levenshtein(lhs: String, rhs: String): Int {
    var cost = Array(lhs.length) { it }
    var newCost = Array(lhs.length) { 0 }

    for (i in 1 until rhs.length) {
        newCost[0] = i

        for (j in 1 until lhs.length) {
            val match = if (lhs[j - 1] == rhs[i - 1]) 0 else 1

            val costReplace = cost[j - 1] + match
            val costInsert = cost[j] + 1
            val costDelete = newCost[j - 1] + 1

            newCost[j] = minOf(costInsert, costDelete, costReplace)
        }

        val swap = cost
        cost = newCost
        newCost = swap
    }

    return cost[lhs.length - 1]
}

fun List<String>.categorize(distance: Int): Map<String, List<String>> {
    val unprocessed = toMutableList()

    val result = mutableMapOf<String, List<String>>()

    while (unprocessed.isNotEmpty()) {
        val first = unprocessed.removeAt(0).trim()

        if (first.length < 6) {
            result[first] = emptyList()
            continue
        }

        val aliases = unprocessed.drop(1).filter { levenshtein(first.trim(), it.trim()) <= distance }
//        if (aliases.isNotEmpty())
            result[first] = aliases

        unprocessed -= aliases
    }

    return result
}


package io.piano.android.composer.c1x

import android.annotation.SuppressLint
import android.webkit.WebView
import io.piano.android.composer.model.Event
import io.piano.android.composer.model.events.ShowRecommendations
import io.piano.android.showhelper.BaseShowController

class ShowRecommendationsController(event: Event<ShowRecommendations>) :
    BaseShowController<ShowRecommendations, WidgetJs>(
        event.eventData,
        with(event.eventData) { WidgetJs(widgetId, siteId) }
    ) {
    private val trackingId = event.eventExecutionContext.trackingId
    override val url = URL
    override val fragmentTag = FRAGMENT_TAG
    override val fragmentProvider = {
        with(eventData) { ShowRecommendationsDialogFragment(widgetId, siteId, trackingId) }
    }

    override fun close(data: String?) = jsInterface.close()

    override fun WebView.configure() = prepare(jsInterface)

    companion object {
        private const val FRAGMENT_TAG = "ShowRecommendationsDialogFragment"
        private const val JAVASCRIPT_INTERFACE = "cXNative"
        internal const val URL = "https://cdn.cxense.com/recommendations.html"

        @SuppressLint("SetJavaScriptEnabled")
        internal fun WebView.prepare(
            jsInterface: WidgetJs,
            dialogFragment: ShowRecommendationsDialogFragment? = null
        ) {
            settings.javaScriptEnabled = true
            jsInterface.init(dialogFragment, this)
            addJavascriptInterface(jsInterface, JAVASCRIPT_INTERFACE)
        }
    }
}

Fix access to local storage for cx.js

package io.piano.android.composer.c1x

import android.annotation.SuppressLint
import android.webkit.WebView
import io.piano.android.composer.model.Event
import io.piano.android.composer.model.events.ShowRecommendations
import io.piano.android.showhelper.BaseShowController

class ShowRecommendationsController(event: Event<ShowRecommendations>) :
    BaseShowController<ShowRecommendations, WidgetJs>(
        event.eventData,
        with(event.eventData) { WidgetJs(widgetId, siteId) }
    ) {
    private val trackingId = event.eventExecutionContext.trackingId
    override val url = URL
    override val fragmentTag = FRAGMENT_TAG
    override val fragmentProvider = {
        with(eventData) { ShowRecommendationsDialogFragment(widgetId, siteId, trackingId) }
    }

    override fun close(data: String?) = jsInterface.close()

    override fun WebView.configure() = prepare(jsInterface)

    companion object {
        private const val FRAGMENT_TAG = "ShowRecommendationsDialogFragment"
        private const val JAVASCRIPT_INTERFACE = "cXNative"
        internal const val URL = "https://cdn.cxense.com/recommendations.html"

        @SuppressLint("SetJavaScriptEnabled")
        internal fun WebView.prepare(
            jsInterface: WidgetJs,
            dialogFragment: ShowRecommendationsDialogFragment? = null
        ) {
            settings.domStorageEnabled = true
            settings.javaScriptEnabled = true
            jsInterface.init(dialogFragment, this)
            addJavascriptInterface(jsInterface, JAVASCRIPT_INTERFACE)
        }
    }
}


/*
 * Copyright 2016 Michael Rozumyanskiy
 *
 * 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.michaelrocks.lightsaber.processor.commons

import java.util.*

fun <T> Collection<T>.immutable(): Collection<T> = Collections.unmodifiableCollection(this)
fun <T> List<T>.immutable(): List<T> = Collections.unmodifiableList(this)
fun <K, V> Map<K, V>.immutable(): Map<K, V> = Collections.unmodifiableMap(this)
fun <T> Set<T>.immutable(): Set<T> = Collections.unmodifiableSet(this)
fun <K, V> SortedMap<K, V>.immutable(): SortedMap<K, V> = Collections.unmodifiableSortedMap(this)
fun <T> SortedSet<T>.immutable(): SortedSet<T> = Collections.unmodifiableSortedSet(this)


package com.github.kubode.rxproperty

import org.junit.Test
import kotlin.test.assertNull

class EmptyVariableKtTest {

    @Test(expected = NullPointerException::class) fun npeWhenAccessToDefaultValue() {
        val value = emptyVariable<String>().value
        value.length
    }

    @Test fun defaultValueIsNull() {
        val value = emptyVariable<String?>().value
        assertNull(value)
    }

    @Test(expected = Exception::class) fun failSetNullIfNotNullType() {
        emptyVariable<String>().value = Java.getNull()
    }
}

Add empty variable test case.

package com.github.kubode.rxproperty

import org.junit.Test
import kotlin.test.assertEquals

class EmptyVariableKtTest {

    @Test(expected = NullPointerException::class) fun npeWhenAccessToDefaultValue() {
        val value = emptyVariable<String>().value
        value.length
    }

    @Test fun setAndGet() {
        val variable = emptyVariable<String>()
        variable.value = ""
        assertEquals("", variable.value)
    }

    @Test(expected = Exception::class) fun failSetNullIfNotNullType() {
        emptyVariable<String>().value = Java.getNull()
    }
}


object PluginVersions {
    val kotlin = "1.3.60"
    val ktlintPlugin = "9.1.1"
    val gradlePublishPlugin = "0.10.1"
    val androidPlugin = "3.6.0"
    val semver = "1.1.1"
    val jgit = "5.6.0.201912101111-r"
    val gradleWrapper = "6.2.1"
    val junit5 = "5.5.2"
    val assertJ = "3.11.1"
    val shadow = "5.2.0"
    val githubRelease = "2.2.10"
}

Update Android Gradle plugin to 3.6.3

object PluginVersions {
    val kotlin = "1.3.72"
    val ktlintPlugin = "9.1.1"
    val gradlePublishPlugin = "0.10.1"
    val androidPlugin = "3.6.3"
    val semver = "1.1.1"
    val jgit = "5.6.0.201912101111-r"
    val gradleWrapper = "6.2.1"
    val junit5 = "5.5.2"
    val assertJ = "3.11.1"
    val shadow = "5.2.0"
    val githubRelease = "2.2.10"
}


package org.runestar.client.plugins.std.windowsize

import org.runestar.client.api.Application
import org.runestar.client.plugins.Plugin
import org.runestar.client.plugins.PluginSettings
import java.awt.Dimension

class WindowSize : Plugin<WindowSize.Settings>() {

    override val defaultSettings = Settings()

    override val name = "Window Size"

    override fun start() {
        super.start()
        Application.frame.size = settings.size
    }

    data class Settings(
            val size: Dimension = Application.frame.size
    ) : PluginSettings()
}

Set window size with or without frame

package org.runestar.client.plugins.std.windowsize

import org.kxtra.slf4j.logger.info
import org.kxtra.swing.dimension.minus
import org.kxtra.swing.dimension.plus
import org.runestar.client.api.Application
import org.runestar.client.game.raw.Client
import org.runestar.client.plugins.Plugin
import org.runestar.client.plugins.PluginSettings
import java.awt.Dimension

class WindowSize : Plugin<WindowSize.Settings>() {

    override val defaultSettings = Settings()

    override val name = "Window Size"

    override fun start() {
        super.start()
        if (settings.includeFrame) {
            Application.frame.size = settings.size
        } else {
            val frameSize = Application.frame.size - Application.frame.contentPane.size
            Application.frame.size = settings.size + frameSize
        }
        logger.info { "frame size: ${Application.frame.size}, game size: ${Application.frame.contentPane.size}" }
    }

    data class Settings(
            val size: Dimension = Client.accessor.canvas.preferredSize,
            val includeFrame: Boolean = false
    ) : PluginSettings()
}


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

import com.edreams.android.workshops.kotlin.data.venues.cache.entity.VenueEntity
import com.edreams.android.workshops.kotlin.data.venues.remote.response.PhotoResponse
import com.edreams.android.workshops.kotlin.data.venues.remote.response.VenueResponse
import com.edreams.android.workshops.kotlin.domain.mapper.Mapper
import javax.inject.Inject

class VenueMapper @Inject constructor() : Mapper<VenueResponse, VenueEntity> {

  override fun map(from: VenueResponse): VenueEntity = with(from) {
    return VenueEntity(id,
        name,
        rating,
        buildPhotoUrl(photos.groups[0].items[0]),
        contact.formattedPhone,
        location.distance,
        location.formattedAddress.joinToString(","),
        stats.checkinsCount,
        tips?.get(0)?.text
    )

  }

  private fun buildPhotoUrl(photo: PhotoResponse): String = with(photo) {
    "$prefix${width}x$height$suffix"
  }
}

Fix crash with emptu images lists

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

import com.edreams.android.workshops.kotlin.data.venues.cache.entity.VenueEntity
import com.edreams.android.workshops.kotlin.data.venues.remote.response.PhotoResponse
import com.edreams.android.workshops.kotlin.data.venues.remote.response.VenueResponse
import com.edreams.android.workshops.kotlin.domain.mapper.Mapper
import javax.inject.Inject

class VenueMapper @Inject constructor() : Mapper<VenueResponse, VenueEntity> {

  override fun map(from: VenueResponse): VenueEntity = with(from) {
    return VenueEntity(id,
        name,
        rating,
        if (photos.groups.isNotEmpty()) buildPhotoUrl(photos.groups[0].items[0]) else "",
        contact.formattedPhone,
        location.distance,
        location.formattedAddress.joinToString(","),
        stats.checkinsCount,
        tips?.get(0)?.text
    )

  }

  private fun buildPhotoUrl(photo: PhotoResponse): String = with(photo) {
    "$prefix${width}x$height$suffix"
  }
}


package org.purescript.psi

import com.intellij.testFramework.fixtures.BasePlatformTestCase
import junit.framework.TestCase
import org.purescript.file.PSFile

class PSExportedItemTest : BasePlatformTestCase() {

    fun `test parses exported class`() {
        val file = myFixture.addFileToProject(
            "Main.purs",
            """module Main (class Foo) where"""
        ) as PSFile
        TestCase.assertTrue(file.module.exportList!!.exportedItems.single() is PSExportedClass)
    }

    fun `test parses exported data`() {
        val file = myFixture.addFileToProject(
            "Main.purs",
            """module Main (Foo) where"""
        ) as PSFile
        TestCase.assertTrue(file.module.exportList!!.exportedItems.single() is PSExportedData)
    }

    fun `test parses exported kind`() {
        val file = myFixture.addFileToProject(
            "Main.purs",
            """module Main (kind Foo) where"""
        ) as PSFile
        TestCase.assertTrue(file.module.exportList!!.exportedItems.single() is PSExportedKind)
    }

    fun `test parses exported module`() {
        val file = myFixture.addFileToProject(
            "Main.purs",
            """module Main (module Foo) where"""
        ) as PSFile
        TestCase.assertTrue(file.module.exportList!!.exportedItems.single() is PSExportedModule)
    }

    fun `test parses exported operator`() {
        val file = myFixture.addFileToProject(
            "Main.purs",
            """module Main ((<~>)) where"""
        ) as PSFile
        TestCase.assertTrue(file.module.exportList!!.exportedItems.single() is PSExportedOperator)
    }

    fun `test parses exported type`() {
        val file = myFixture.addFileToProject(
            "Main.purs",
            """module Main (type (<<=>>)) where"""
        ) as PSFile
        TestCase.assertTrue(file.module.exportList!!.exportedItems.single() is PSExportedType)
    }

    fun `test parses exported value`() {
        val file = myFixture.addFileToProject(
            "Main.purs",
            """module Main (foo) where"""
        ) as PSFile
        TestCase.assertTrue(file.module.exportList!!.exportedItems.single() is PSExportedValue)
    }
}


package com.alexstyl.specialdates.upcoming.widget.list

import android.content.res.Resources
import android.support.annotation.Px
import android.widget.RemoteViews
import com.alexstyl.specialdates.R
import com.alexstyl.specialdates.upcoming.UpcomingContactEventViewModel

internal class ContactEventBinder(private val remoteViews: RemoteViews,
                                  private val resources: Resources,
                                  private val avatarFactory: CircularAvatarFactory)
    : UpcomingEventViewBinder<UpcomingContactEventViewModel> {

    override fun bind(viewModel: UpcomingContactEventViewModel) {
        remoteViews.setTextViewText(R.id.row_upcoming_event_contact_name, viewModel.contactName)
        remoteViews.setTextViewText(R.id.row_upcoming_event_contact_event, viewModel.eventLabel)
        @Px val targetSize = resources.getDimensionPixelSize(R.dimen.widget_upcoming_avatar_size)
        val avatar = avatarFactory.circularAvatarFor(viewModel.contact, targetSize)
        if (avatar.isPresent) {
            remoteViews.setImageViewBitmap(R.id.row_upcoming_event_contact_image, avatar.get())
        }
    }

    override fun getViews(): RemoteViews = remoteViews
}

Create a circle avatar if a contact has none

package com.alexstyl.specialdates.upcoming.widget.list

import android.content.res.Resources
import android.graphics.Bitmap
import android.support.annotation.Px
import android.widget.RemoteViews
import com.alexstyl.specialdates.R
import com.alexstyl.specialdates.contact.Contact
import com.alexstyl.specialdates.upcoming.UpcomingContactEventViewModel

internal class ContactEventBinder(private val remoteViews: RemoteViews,
                                  private val resources: Resources,
                                  private val avatarFactory: CircularAvatarFactory)
    : UpcomingEventViewBinder<UpcomingContactEventViewModel> {

    override fun bind(viewModel: UpcomingContactEventViewModel) {
        remoteViews.setTextViewText(R.id.row_upcoming_event_contact_name, viewModel.contactName)
        remoteViews.setTextViewText(R.id.row_upcoming_event_contact_event, viewModel.eventLabel)
        remoteViews.setTextColor(R.id.row_upcoming_event_contact_event, viewModel.eventColor)

        val avatar = createAvatarFor(viewModel.contact)
        remoteViews.setImageViewBitmap(R.id.row_upcoming_event_contact_image, avatar)
    }

    private fun createAvatarFor(contact: Contact): Bitmap {
        @Px val targetSize = resources.getDimensionPixelSize(R.dimen.widget_upcoming_avatar_size)
        val avatar = avatarFactory.circularAvatarFor(contact, targetSize)
        return if (avatar.isPresent) {
            avatar.get()
        } else {
            val textSize = resources.getDimensionPixelSize(R.dimen.widget_upcoming_avatar_text_size)
            avatarFactory.createLetterAvatarFor(contact.displayName, targetSize, textSize)
        }
    }

    override fun getViews(): RemoteViews = remoteViews
}


/*
 * Copyright 2015-2019 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v2.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v20.html
 */
@file:Suppress("unused")

package org.junit.jupiter.params.aggregator

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.TestInfo
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource

// https://github.com/junit-team/junit5/issues/1836
object DisplayNameTests {
    @JvmStatic
    fun data() = arrayOf(
            arrayOf("A", 1),
            arrayOf("B", 2),
            arrayOf("C", 3)
    )

    @ParameterizedTest
    @MethodSource("data")
    fun test(char: String, number: Int, info: TestInfo) {
        assertEquals("[$number] $char, $number", info.displayName)
    }
}


package venus.assembler

import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import venus.simulator.Simulator

class LinkerTest {
    @Test
    fun linkOneFile() {
        val prog = Assembler.assemble("""
        start:
        addi x8 x8 1
        addi x9 x0 2
        beq x8 x9 skip
        jal x0 start
        skip:
        """)
        val linked = Linker.link(listOf(prog))
        var sim = Simulator(linked.dump())
        sim.run()
        assertEquals(2, sim.state.getReg(8))
    }
}

Add linker test for two files

package venus.assembler

import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import venus.simulator.Simulator

class LinkerTest {
    @Test
    fun linkOneFile() {
        val prog = Assembler.assemble("""
        start:
        addi x8 x8 1
        addi x9 x0 2
        beq x8 x9 skip
        jal x0 start
        skip:
        """)
        val linked = Linker.link(listOf(prog))
        var sim = Simulator(linked.dump())
        sim.run()
        assertEquals(2, sim.state.getReg(8))
    }

    @Test
    fun linkTwoFiles() {
        val prog1 = Assembler.assemble("""
        foo:
            jal x0 bar
            addi x8 x0 8
        """)
        val prog2 = Assembler.assemble("""
        bar:
            addi x8 x8 1
        """)
        val linked = Linker.link(listOf(prog1, prog2))
        var sim = Simulator(linked.dump())
        sim.run()
        assertEquals(1, sim.state.getReg(8))
    }
}


package com.elpassion.intelijidea

import com.intellij.openapi.options.SettingsEditor
import com.intellij.openapi.project.Project
import javax.swing.JComponent

class MFSettingsEditor(project: Project) : SettingsEditor<MFRunnerConfiguration>() {

    private val mainEditorPanel = MFSettingsEditorPanel(project)

    override fun createEditor(): JComponent {
        return mainEditorPanel.panel
    }

    override fun applyEditorTo(configuration: MFRunnerConfiguration) {
        configuration.taskName = mainEditorPanel.taskName.text
    }

    override fun resetEditorFrom(configuration: MFRunnerConfiguration) {
        configuration.taskName = ""
    }
}

Apply mainframer configuration to MFRunConfiguration

package com.elpassion.intelijidea

import com.intellij.openapi.options.SettingsEditor
import com.intellij.openapi.project.Project
import javax.swing.JComponent

class MFSettingsEditor(project: Project) : SettingsEditor<MFRunnerConfiguration>() {

    private val mainEditorPanel = MFSettingsEditorPanel(project)

    override fun createEditor(): JComponent {
        return mainEditorPanel.panel
    }

    override fun applyEditorTo(configuration: MFRunnerConfiguration) {
        configuration.taskName = mainEditorPanel.taskName.text
        configuration.mainframerPath = mainEditorPanel.mainframerScript.text
    }

    override fun resetEditorFrom(configuration: MFRunnerConfiguration) {
        configuration.taskName = ""
        configuration.mainframerPath = ""
    }
}


package net.squanchy.support.graphics

import android.graphics.Color
import android.support.annotation.ColorInt

private const val MAX_COLOR_COMPONENT = 255.0
private const val GAMMA_FACTOR = 2.2
private const val MAX_LIGHTNESS_FOR_LIGHT_TEXT = .18
private const val FACTOR_RED = 0.2126
private const val FACTOR_GREEN = 0.7151
private const val FACTOR_BLUE = 0.0721

@ColorInt
internal fun Int.contrastingTextColor(@ColorInt darkTextColor: Int, @ColorInt lightTextColor: Int): Int {
    val r = Color.red(this)
    val g = Color.green(this)
    val b = Color.blue(this)
    val lightness = FACTOR_RED * gamaCorrectColorComponent(r) +
        FACTOR_GREEN * gamaCorrectColorComponent(g) +
        FACTOR_BLUE * gamaCorrectColorComponent(b)

    return if (lightness > MAX_LIGHTNESS_FOR_LIGHT_TEXT) {
        darkTextColor
    } else {
        lightTextColor
    }
}

private fun gamaCorrectColorComponent(r: Int) = Math.pow(r / MAX_COLOR_COMPONENT, GAMMA_FACTOR)

Improve contrasting text colour picking algorithm

package net.squanchy.support.graphics

import android.support.annotation.ColorInt
import android.support.v4.graphics.ColorUtils

@ColorInt
internal fun Int.pickBestTextColorByContrast(@ColorInt firstTextColor: Int, @ColorInt secondTextColor: Int): Int {
    val firstTextContrast = ColorUtils.calculateContrast(firstTextColor, this)
    val secondTextContrast = ColorUtils.calculateContrast(secondTextColor, this)

    return when {
        firstTextContrast > secondTextContrast -> firstTextColor
        else -> secondTextColor
    }
}


import java.util.stream.Stream

fun main(args: Array<String>) {
  // Breakpoint!
  val toArray = Stream.of(1, 2, 3, 4).map { it % 2 == 0 }.toArray()
}


package nl.hannahsten.texifyidea.index.file

import com.intellij.util.indexing.DataIndexer
import com.intellij.util.indexing.FileContent

/**
 * Get the content we need from LaTeX Package source files.
 */
class LatexPackageDataIndexer : DataIndexer<String, String, FileContent> {
    private val macroWithDocsRegex = """\\begin\{macro\}\{(?<command>\\.+)\}\s*(?:%\s*(?!.*(\\begin|\\end))(?<docs>.*)\s){0,4}""".toRegex()

    override fun map(inputData: FileContent): MutableMap<String, String> {
        val map = mutableMapOf<String, String>()
        macroWithDocsRegex.findAll(inputData.contentAsText).forEach {
            val command = it.groups["command"]?.value
            if (command != null) {
                map[command] = it.groups["docs"]?.value ?: ""
            }
        }
        return map
    }
}

Support macro documentation of multiple lines

package nl.hannahsten.texifyidea.index.file

import com.intellij.util.indexing.DataIndexer
import com.intellij.util.indexing.FileContent
import nl.hannahsten.texifyidea.util.containsAny

/**
 * Get the content we need from LaTeX Package source files.
 */
class LatexPackageDataIndexer : DataIndexer<String, String, FileContent> {
    /**
     * Capture the command being defined with the macro environment and the part directly after that that probably contains docs.
     * We limit to a certain length to avoid matching very large strings if the regex fails.
     * Then we use a separate regex to get the actual docs out of that string, matching lines until a certain stopping criterion.
     */
    private val macroWithDocsRegex = """\\begin\{macro\}\{(?<command>\\.+)\}\s*(?<docs>[\s\S]{0,100})""".toRegex()
    private val docsAfterMacroRegex = """(?:%\s*(?<line>.*))""".toRegex()

    override fun map(inputData: FileContent): MutableMap<String, String> {
        val map = mutableMapOf<String, String>()
        // Get the command and possible documentation
        macroWithDocsRegex.findAll(inputData.contentAsText).forEach loop@{
            val command = it.groups["command"]?.value ?: return@loop
            val containsDocs = it.groups["docs"]?.value ?: return@loop
            var docs = ""
            // Strip the line prefixes and guess until where the documentation  goes.
            docsAfterMacroRegex.findAll(containsDocs).forEach { line ->
                if (line.groups["line"]?.value?.containsAny(setOf("\\begin", "\\end")) == false) {
                    docs += " " + line.groups["line"]?.value
                }
            }
            map[command] = docs.trim()
        }
        return map
    }
}