/*
 * Copyright 2010-2018 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 kotlin.collections

import kotlin.comparisons.*

/**
 * Sorts elements in the list in-place according to their natural sort order.
 *
 * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
 */
public actual fun <T : Comparable<T>> MutableList<T>.sort(): Unit = sortWith(Comparator<T> { a: T, b: T -> a.compareTo(b) })

/**
 * Sorts elements in the list in-place according to the order specified with [comparator].
 *
 * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
 */
public actual fun <T> MutableList<T>.sortWith(comparator: Comparator<in T>): Unit {
    if (size > 1) {
        val it = listIterator()
        val sortedArray = @Suppress("TYPE_PARAMETER_AS_REIFIED") toTypedArray().apply { sortWith(comparator) }
        for (v in sortedArray) {
            it.next()
            it.set(v)
        }
    }
}

Rewrite MutableList.sortWith to suppress warning instead of error

/*
 * Copyright 2010-2018 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 kotlin.collections

/**
 * Sorts elements in the list in-place according to their natural sort order.
 *
 * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
 */
public actual fun <T : Comparable<T>> MutableList<T>.sort(): Unit = sortWith(naturalOrder())

/**
 * Sorts elements in the list in-place according to the order specified with [comparator].
 *
 * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
 */
public actual fun <T> MutableList<T>.sortWith(comparator: Comparator<in T>): Unit {
    if (size > 1) {
        val it = listIterator()
        val sortedArray = @Suppress("UNCHECKED_CAST") (toTypedArray<Any?>() as Array<T>).apply { sortWith(comparator) }
        for (v in sortedArray) {
            it.next()
            it.set(v)
        }
    }
}


/*
 * Copyright 2021, TeamDev. All rights reserved.
 *
 * 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
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.protobuf

import com.google.common.truth.Truth.assertThat
import com.google.common.truth.extensions.proto.ProtoTruth.assertThat
import com.google.protobuf.Message
import com.google.protobuf.StringValue
import io.spine.test.protobuf.MessageToPack
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows

class `'Any' extensions should` {

    @Test
    fun `unpack Any into a concrete type`() {
        val msg = MessageToPack
            .newBuilder()
            .setValue(StringValue.of("bla bla"))
            .build()
        val any = AnyPacker.pack(msg)

        val unpacked = any.unpack<MessageToPack>()
        assertThat(unpacked)
            .isEqualTo(msg)
    }

    @Test
    fun `unpack Any without a concrete type`() {
        val msg = MessageToPack
            .newBuilder()
            .setValue(StringValue.of("foo bar"))
            .build()
        val any = AnyPacker.pack(msg)

        val unpacked = any.unpackGuessingType()
        val assertUnpacked = assertThat(unpacked)
        assertUnpacked
            .isInstanceOf(MessageToPack::class.java)
        assertUnpacked
            .isEqualTo(msg)
    }

    @Test
    fun `fail to unpack Any with an interface`() {
        val msg = MessageToPack
            .newBuilder()
            .setValue(StringValue.of("la la la"))
            .build()
        val any = AnyPacker.pack(msg)

        assertThrows<IllegalArgumentException> { any.unpack<Message>() }
    }

    @Test
    fun `pack message into Any`() {
        val msg = MessageToPack
            .newBuilder()
            .setValue(StringValue.of("la la la"))
            .build()
        val any = msg.pack()
        assertThat(any.typeUrl)
            .isEqualTo("types.spine.io/spine.test.protobuf.MessageToPack")
        assertThat(any.unpack<MessageToPack>())
            .isEqualTo(msg)
    }
}


import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("io.spring.convention.spring-sample-boot")
    kotlin("jvm")
    kotlin("plugin.spring") version "1.3.61"
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(project(":spring-security-core"))
    implementation(project(":spring-security-config"))
    implementation(project(":spring-security-web"))
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    testImplementation(project(":spring-security-test"))
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    }
}

Update Spring Kotlin plugin in sample

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("io.spring.convention.spring-sample-boot")
    kotlin("jvm")
    kotlin("plugin.spring") version "1.3.71"
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(project(":spring-security-core"))
    implementation(project(":spring-security-config"))
    implementation(project(":spring-security-web"))
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    testImplementation(project(":spring-security-test"))
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    }
}


package circlet.actions

import circlet.components.*
import circlet.model.*
import circlet.utils.*
import com.intellij.openapi.actionSystem.*
import klogging.*
import rx.subjects.*

private val log = KLoggers.logger("plugin/TestCircletAction.kt")

class TestCircletAction : AnAction() {

    override fun update(e: AnActionEvent?) {
        e ?: return
        val project = e.project
        project ?: return

        e.presentation.isEnabled = project.component<IdePluginClient>().connectionState != null
    }

    override fun actionPerformed(e: AnActionEvent?) {
        e ?: return
        val project = e.project
        project ?: return
        val client = project.component<IdePluginClient>()
        val connection = client.connectionState?.connection ?: return

        ServerApi(connection).getSpaces() then {
            it.forEach {
                log.info { "Space: ${it.name}" }
            }
        } catch {
            // >>> wtf...
        }

    }
}

Refactor CircletPage to get all necessary data before rendering content (reduces number of promiseComponents quite significantly)

package circlet.actions

import circlet.components.*
import circlet.model.*
import circlet.utils.*
import com.intellij.openapi.actionSystem.*
import klogging.*
import rx.subjects.*

private val log = KLoggers.logger("plugin/TestCircletAction.kt")

class TestCircletAction : AnAction() {

    override fun update(e: AnActionEvent?) {
        e ?: return
        val project = e.project
        project ?: return

        e.presentation.isEnabled = project.component<IdePluginClient>().connectionState != null
    }

    override fun actionPerformed(e: AnActionEvent?) {
        e ?: return
        val project = e.project
        project ?: return
        val client = project.component<IdePluginClient>()
        val connection = client.connectionState?.connection ?: return

        ServerApi(connection).spaces() then {
            it.forEach {
                log.info { "Space: ${it.name}" }
            }
        } catch {
            // >>> wtf...
        }

    }
}


package com.beust.kobalt.app

import com.beust.kobalt.api.ITemplateContributor
import com.beust.kobalt.api.JarTemplate
import com.beust.kobalt.plugin.KobaltPlugin

/**
 * Template that generates a Kobalt plug-in project.
 */
class KobaltPluginTemplate : ITemplateContributor {
    val pluginTemplate = object: JarTemplate("templates/kobaltPlugin.jar") {
        override val templateDescription = "Generate a sample Kobalt plug-in project"

        override val templateName = "kobalt-plugin"

        override val pluginName = KobaltPlugin.PLUGIN_NAME
    }

    override val templates = listOf(pluginTemplate)
}

Rename the template for consistency.

package com.beust.kobalt.app

import com.beust.kobalt.api.ITemplateContributor
import com.beust.kobalt.api.JarTemplate
import com.beust.kobalt.plugin.KobaltPlugin

/**
 * Template that generates a Kobalt plug-in project.
 */
class KobaltPluginTemplate : ITemplateContributor {
    val pluginTemplate = object: JarTemplate("templates/kobaltPlugin.jar") {
        override val templateDescription = "Generate a sample Kobalt plug-in project"

        override val templateName = "kobaltPlugin"

        override val pluginName = KobaltPlugin.PLUGIN_NAME
    }

    override val templates = listOf(pluginTemplate)
}


package org.jetbrains.ktor.application

import java.util.*

/** Current executing application
 */
public open class Application(val config: ApplicationConfig) {

    private val interceptors = ArrayList<(ApplicationRequest, (ApplicationRequest) -> ApplicationRequestStatus) -> ApplicationRequestStatus>()
    public fun intercept(handler: (request: ApplicationRequest, proceed: (ApplicationRequest) -> ApplicationRequestStatus) -> ApplicationRequestStatus) {
        interceptors.add(handler)
    }

    public fun handle(request: ApplicationRequest): ApplicationRequestStatus {
        val queryString = request.queryString()
        val requestLogString = "${request.httpMethod} -- ${request.uri}${if (queryString.isNotEmpty()) "?$queryString" else ""}"

        fun handle(index: Int, request: ApplicationRequest): ApplicationRequestStatus = when (index) {
            in interceptors.indices -> {
                val interceptor = interceptors[index]
                val proceed: (ApplicationRequest) -> ApplicationRequestStatus = { augmentedRequest -> handle(index + 1, augmentedRequest) }
                interceptor(request, proceed)
            }
            else -> ApplicationRequestStatus.Unhandled
        }

        val result = handle(0, request)
        config.log.info("$requestLogString -- $result")
        return result
    }

    public open fun dispose() {
    }
}

Fix logging of query parameters

package org.jetbrains.ktor.application

import java.util.*

/** Current executing application
 */
public open class Application(val config: ApplicationConfig) {

    private val interceptors = ArrayList<(ApplicationRequest, (ApplicationRequest) -> ApplicationRequestStatus) -> ApplicationRequestStatus>()
    public fun intercept(handler: (request: ApplicationRequest, proceed: (ApplicationRequest) -> ApplicationRequestStatus) -> ApplicationRequestStatus) {
        interceptors.add(handler)
    }

    public fun handle(request: ApplicationRequest): ApplicationRequestStatus {
        val queryString = request.queryString()
        val requestLogString = "${request.httpMethod} -- ${request.uri}"

        fun handle(index: Int, request: ApplicationRequest): ApplicationRequestStatus = when (index) {
            in interceptors.indices -> {
                val interceptor = interceptors[index]
                val proceed: (ApplicationRequest) -> ApplicationRequestStatus = { augmentedRequest -> handle(index + 1, augmentedRequest) }
                interceptor(request, proceed)
            }
            else -> ApplicationRequestStatus.Unhandled
        }

        val result = handle(0, request)
        config.log.info("$requestLogString -- $result")
        return result
    }

    public open fun dispose() {
    }
}


package com.intellij.debugger.streams.ui.impl

import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.streams.ui.ValueWithPosition
import java.awt.Graphics

/**
 * @author Vitaliy.Bibaev
 */
class PositionsAwareCollectionView(header: String,
                                   evaluationContext: EvaluationContextImpl,
                                   private val values: List<ValueWithPosition>) : CollectionView(header, evaluationContext,
                                                                                values.map { it.traceElement }) {
  override fun paintComponent(g: Graphics?) {
    super.paintComponent(g)

    val visibleRect = instancesTree.visibleRect
    for (value in values) {
      val rect = instancesTree.getRectByValue(value.traceElement)
      if (rect == null || !visibleRect.intersects(rect)) {
        value.position = -1
        value.isSelected = false
      }
      else {
        value.position = rect.y + rect.height / 2 - visibleRect.y
        value.isSelected = instancesTree.isSelected(value.traceElement)
      }
    }
  }
}

Update tree values position when tree repainted

package com.intellij.debugger.streams.ui.impl

import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.streams.ui.PaintingListener
import com.intellij.debugger.streams.ui.ValueWithPosition
import com.intellij.openapi.application.ApplicationManager

/**
 * @author Vitaliy.Bibaev
 */
class PositionsAwareCollectionView(header: String,
                                   evaluationContext: EvaluationContextImpl,
                                   private val values: List<ValueWithPosition>) : CollectionView(header, evaluationContext,
                                                                                values.map { it.traceElement }) {
  init {
    instancesTree.addPaintingListener(object : PaintingListener {
      override fun componentPainted() {
        updateValues()
      }
    })
  }

  private fun updateValues(): Unit {
    val visibleRect = instancesTree.visibleRect
    for (value in values) {
      val rect = instancesTree.getRectByValue(value.traceElement)
      if (rect == null || !visibleRect.intersects(rect)) {
        value.position = -1
        value.isSelected = false
      }
      else {
        value.position = rect.y + rect.height / 2 - visibleRect.y
        value.isSelected = instancesTree.isSelected(value.traceElement)
      }
    }

    ApplicationManager.getApplication().invokeLater({})
  }
}


package com.intellij.debugger.streams.ui.impl

import com.intellij.debugger.streams.ui.LinkedValuesMapping
import com.intellij.debugger.streams.ui.ValueWithPosition
import com.intellij.ui.JBColor
import com.intellij.ui.components.JBLabel
import java.awt.BorderLayout
import java.awt.Graphics
import javax.swing.JPanel

/**
 * @author Vitaliy.Bibaev
 */
class MappingPane(private val beforeValues: List<ValueWithPosition>,
                  private val mapping: LinkedValuesMapping) : JPanel(BorderLayout()) {
  init {
    add(JBLabel("map"), BorderLayout.NORTH)
    add(MyDrawPane(), BorderLayout.CENTER)
  }

  private inner class MyDrawPane : JPanel() {
    override fun paintComponent(g: Graphics?) {
      if (g == null) {
        return
      }

      val x1 = x
      val x2 = x + width
      for (value in beforeValues) {
        if (!value.isVisible) continue
        val position: Int = value.position
        val linkedValues = mapping.getLinkedValues(value) ?: continue
        for (nextValue in linkedValues.filter { it.isVisible }) {
          g.color = JBColor.BLACK
          g.drawLine(x1, position, x2, nextValue.position)
        }
      }
    }
  }
}

Add workaround to align mapping pane with collection views

package com.intellij.debugger.streams.ui.impl

import com.intellij.debugger.streams.ui.LinkedValuesMapping
import com.intellij.debugger.streams.ui.ValueWithPosition
import com.intellij.ui.JBColor
import com.intellij.ui.components.JBLabel
import java.awt.BorderLayout
import java.awt.Graphics
import javax.swing.JPanel

/**
 * @author Vitaliy.Bibaev
 */
class MappingPane(private val beforeValues: List<ValueWithPosition>,
                  private val mapping: LinkedValuesMapping) : JPanel(BorderLayout()) {
  init {
    // TODO: fix this workaround
    add(JBLabel(" "), BorderLayout.NORTH)
    add(MyDrawPane(), BorderLayout.CENTER)
  }

  private inner class MyDrawPane : JPanel() {
    override fun paintComponent(g: Graphics?) {
      if (g == null) {
        return
      }

      val x1 = x
      val x2 = x + width
      for (value in beforeValues) {
        if (!value.isVisible) continue
        val position: Int = value.position
        val linkedValues = mapping.getLinkedValues(value) ?: continue
        for (nextValue in linkedValues.filter { it.isVisible }) {
          g.color = JBColor.BLACK
          g.drawLine(x1, position, x2, nextValue.position)
        }
      }
    }
  }
}


package com.example.wrench.di

import com.example.wrench.livedataprefs.LiveDataPreferencesFragmentViewModel
import com.example.wrench.service.WrenchServiceFragmentViewModel
import com.example.wrench.wrenchprefs.WrenchPreferencesFragmentViewModel
import com.izettle.wrench.preferences.WrenchPreferences
import com.izettle.wrench.service.WrenchPreferenceProvider
import com.izettle.wrench.service.WrenchService
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.ext.koin.viewModel
import org.koin.dsl.module.module

val sampleAppModule = module {
    factory { WrenchPreferences(androidContext()) }
    factory { androidContext().resources }
    factory { WrenchService.with(get()) }
    factory { WrenchPreferenceProvider(get<WrenchPreferences>()) }
    viewModel { LiveDataPreferencesFragmentViewModel(androidContext()) }
    viewModel { WrenchPreferencesFragmentViewModel(get(), get()) }
    viewModel { WrenchServiceFragmentViewModel(get()) }
}

Fix crash in sample application

package com.example.wrench.di

import com.example.wrench.livedataprefs.LiveDataPreferencesFragmentViewModel
import com.example.wrench.service.WrenchServiceFragmentViewModel
import com.example.wrench.wrenchprefs.WrenchPreferencesFragmentViewModel
import com.izettle.wrench.preferences.WrenchPreferences
import com.izettle.wrench.service.Provider
import com.izettle.wrench.service.WrenchPreferenceProvider
import com.izettle.wrench.service.WrenchService
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.ext.koin.viewModel
import org.koin.dsl.module.module

val sampleAppModule = module {
    factory { WrenchPreferences(androidContext()) }
    factory { androidContext().resources }
    factory { WrenchService.with(get()) }
    factory<Provider> { WrenchPreferenceProvider(get<WrenchPreferences>()) }
    viewModel { LiveDataPreferencesFragmentViewModel(androidContext()) }
    viewModel { WrenchPreferencesFragmentViewModel(get(), get()) }
    viewModel { WrenchServiceFragmentViewModel(get()) }
}


buildscript {
    var kotlinVer: String by extra
    kotlinVer = "1.2.40"
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVer")
    }
}

allprojects {
    apply { plugin("idea") }
    group = "com.github.epabst.kotlin-showcase"
    version = "1.0-SNAPSHOT"
    var kotlinVer: String by extra
    kotlinVer = "1.2.40"
    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
        maven {
            url = uri("http://nexus.yested.net/nexus/content/repositories/releases/")
        }
    }
}

Remove bogus reference to nexus.yested.net

buildscript {
    var kotlinVer: String by extra
    kotlinVer = "1.2.40"
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVer")
    }
}

allprojects {
    apply { plugin("idea") }
    group = "com.github.epabst.kotlin-showcase"
    version = "1.0-SNAPSHOT"
    var kotlinVer: String by extra
    kotlinVer = "1.2.40"
    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
    }
}


package jp.toastkid.yobidashi

import android.app.Application
import com.squareup.leakcanary.LeakCanary
import jp.toastkid.yobidashi.browser.bookmark.BookmarkInitializer
import jp.toastkid.yobidashi.libs.preference.PreferenceApplier
import jp.toastkid.yobidashi.notification.widget.NotificationWidget
import jp.toastkid.yobidashi.settings.color.SavedColors
import timber.log.Timber

/**
 * For using LeakCanary and so on...

 * @author toastkidjp
 */
class ExtendedApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        LeakCanary.install(this)

        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        }

        val preferenceApplier = PreferenceApplier(this)

        if (preferenceApplier.isFirstLaunch) {
            SavedColors.insertDefaultColors(this)
            preferenceApplier.updateLastAd()
            BookmarkInitializer.invoke(this)
        }

        if (preferenceApplier.useNotificationWidget()) {
            NotificationWidget.show(this)
        }
    }

}

Add Orma initialization in Application class.

package jp.toastkid.yobidashi

import android.app.Application
import com.squareup.leakcanary.LeakCanary
import io.reactivex.Completable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import jp.toastkid.yobidashi.browser.bookmark.BookmarkInitializer
import jp.toastkid.yobidashi.libs.db.DbInitter
import jp.toastkid.yobidashi.libs.preference.PreferenceApplier
import jp.toastkid.yobidashi.notification.widget.NotificationWidget
import jp.toastkid.yobidashi.settings.color.SavedColors
import timber.log.Timber

/**
 * For using LeakCanary and so on...
 *
 * @author toastkidjp
 */
class ExtendedApplication : Application() {

    val disposables = CompositeDisposable()

    override fun onCreate() {
        super.onCreate()
        disposables.add(
                Completable.create { e ->
                    LeakCanary.install(this)
                    e.onComplete()
                }.subscribeOn(Schedulers.computation())
                        .subscribe({}, {Timber.e(it)})
        )

        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        }

        val preferenceApplier = PreferenceApplier(this)

        if (preferenceApplier.isFirstLaunch) {
            SavedColors.insertDefaultColors(this)
            preferenceApplier.updateLastAd()
            BookmarkInitializer.invoke(this)
        } else {
            disposables.add(
                    Completable.create { e ->
                        DbInitter.init(this)
                        e.onComplete()
                    }.subscribeOn(Schedulers.io())
                            .subscribe({}, {Timber.e(it)})
            )
        }

        if (preferenceApplier.useNotificationWidget()) {
            NotificationWidget.show(this)
        }
    }

    override fun onTerminate() {
        super.onTerminate()
        disposables.dispose()
    }

}


/*
 * Use of this source code is governed by the MIT license that can be
 * found in the LICENSE file.
 */

package org.rust.ide.settings

import com.intellij.application.options.editor.AutoImportOptionsProvider
import com.intellij.openapi.application.ApplicationBundle
import com.intellij.openapi.options.UiDslConfigurable
import com.intellij.ui.ContextHelpLabel
import com.intellij.ui.layout.RowBuilder
import org.rust.RsBundle

class RsAutoImportOptions : UiDslConfigurable.Simple(), AutoImportOptionsProvider {

    override fun RowBuilder.createComponentRow() {
        val settings = RsCodeInsightSettings.getInstance()
        titledRow(RsBundle.message("settings.rust.auto.import.title")) {
            row {
                checkBox(
                    RsBundle.message("settings.rust.auto.import.show.popup"),
                    settings::showImportPopup
                )
            }
            row {
                checkBox(
                    RsBundle.message("settings.rust.auto.import.on.completion"),
                    settings::importOutOfScopeItems
                )
            }
            row {
                cell {
                    checkBox(
                        ApplicationBundle.message("checkbox.add.unambiguous.imports.on.the.fly"),
                        settings::addUnambiguousImportsOnTheFly
                    )
                    ContextHelpLabel.create(ApplicationBundle.message("help.add.unambiguous.imports"))()
                }
            }
        }
    }
}

Fix auto-import options for 2022.1

/*
 * Use of this source code is governed by the MIT license that can be
 * found in the LICENSE file.
 */

package org.rust.ide.settings

import com.intellij.application.options.editor.AutoImportOptionsProvider
import com.intellij.openapi.application.ApplicationBundle
import com.intellij.openapi.options.UiDslUnnamedConfigurable
import com.intellij.ui.dsl.builder.Panel
import com.intellij.ui.dsl.builder.RightGap
import com.intellij.ui.dsl.builder.bindSelected
import org.rust.RsBundle

class RsAutoImportOptions : UiDslUnnamedConfigurable.Simple(), AutoImportOptionsProvider {

    override fun Panel.createContent() {
        val settings = RsCodeInsightSettings.getInstance()
        group(RsBundle.message("settings.rust.auto.import.title")) {
            row {
                checkBox(RsBundle.message("settings.rust.auto.import.show.popup"))
                    .bindSelected(settings::showImportPopup)
            }
            row {
                checkBox(RsBundle.message("settings.rust.auto.import.on.completion"))
                    .bindSelected(settings::importOutOfScopeItems)
            }
            row {
                checkBox(ApplicationBundle.message("checkbox.add.unambiguous.imports.on.the.fly"))
                    .bindSelected(settings::addUnambiguousImportsOnTheFly)
                    .gap(RightGap.SMALL)
                contextHelp(ApplicationBundle.message("help.add.unambiguous.imports"))
            }
        }
    }
}


package guru.stefma.androidartifacts

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.publish.maven.MavenPublication

class JavaArtifactsPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        val extension = project.createJavaArtifactsExtension()
        project.applyMavenPublishPlugin()
        val publicationTasks = project.tasks.createListAvailablePublicationTask()
        val publicationName = "maven"
        project.tasks.createJavaArtifactsTask(publicationName)
        // TODO: Think if we can do that better lazy somehow
        // see https://docs.gradle.org/current/userguide/lazy_configuration.html
        project.afterEvaluate {
            createPublication(extension, project, publicationName, publicationTasks)
        }
    }

    private fun Project.createJavaArtifactsExtension() =
            extensions.create("javaArtifact", ArtifactsExtension::class.java)

    private fun createPublication(
            extension: ArtifactsExtension,
            project: Project,
            publicationName: String,
            publicationTasks: ListGeneratedPublicationTasks
    ) {
        publicationTasks.publicationNames += publicationName
        project.publishingExtension.publications.create(publicationName, MavenPublication::class.java) {
            it.from(project.components.getByName("java"))
            // Publish sources only if set to true
            if (extension.sources) it.addJavaSourcesArtifact(project, "maven")
            // Publish javadoc only if set to true
            if (extension.javadoc) it.addJavaJavadocArtifact(project, "maven")

            it.setupMetadata(project, extension)
        }
    }

}

Use variable instead of hardcoding

package guru.stefma.androidartifacts

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.publish.maven.MavenPublication

class JavaArtifactsPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        val extension = project.createJavaArtifactsExtension()
        project.applyMavenPublishPlugin()
        val publicationTasks = project.tasks.createListAvailablePublicationTask()
        val publicationName = "maven"
        project.tasks.createJavaArtifactsTask(publicationName)
        // TODO: Think if we can do that better lazy somehow
        // see https://docs.gradle.org/current/userguide/lazy_configuration.html
        project.afterEvaluate {
            createPublication(extension, project, publicationName, publicationTasks)
        }
    }

    private fun Project.createJavaArtifactsExtension() =
            extensions.create("javaArtifact", ArtifactsExtension::class.java)

    private fun createPublication(
            extension: ArtifactsExtension,
            project: Project,
            publicationName: String,
            publicationTasks: ListGeneratedPublicationTasks
    ) {
        publicationTasks.publicationNames += publicationName
        project.publishingExtension.publications.create(publicationName, MavenPublication::class.java) {
            it.from(project.components.getByName("java"))
            // Publish sources only if set to true
            if (extension.sources) it.addJavaSourcesArtifact(project, publicationName)
            // Publish javadoc only if set to true
            if (extension.javadoc) it.addJavaJavadocArtifact(project, publicationName)

            it.setupMetadata(project, extension)
        }
    }

}


plugins {
    java
}

repositories {
    mavenCentral()
}

// tag::exclude-transitive-dependencies[]
configurations {
    "implementation" {
        exclude(group = "commons-collections", module = "commons-collections")
    }
}

dependencies {
    implementation("commons-beanutils:commons-beanutils:1.9.4")
    implementation("com.opencsv:opencsv:4.6")
}
// end::exclude-transitive-dependencies[]

tasks.register("printArtifacts") {
    val runtimeClasspath: FileCollection = configurations.runtimeClasspath.get()
    doLast {
        runtimeClasspath.forEach { println(it.name) }
    }
}

Adjust the snippet for configuration cache

plugins {
    java
}

repositories {
    mavenCentral()
}

// tag::exclude-transitive-dependencies[]
configurations {
    "implementation" {
        exclude(group = "commons-collections", module = "commons-collections")
    }
}

dependencies {
    implementation("commons-beanutils:commons-beanutils:1.9.4")
    implementation("com.opencsv:opencsv:4.6")
}
// end::exclude-transitive-dependencies[]

tasks.register("printArtifacts") {
    val runtimeClasspath: FileCollection = configurations["runtimeClasspath"]
    doLast {
        runtimeClasspath.forEach { println(it.name) }
    }
}


Add a unit test for the cycle search algorithm

/*
 * 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.graph

import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class CycleSearcherTest {
  @Test
  fun testMinimalCycle() {
    val graph = HashDirectedGraph<Int>()
    graph.put(1, 2)
    graph.put(2, 1)
    val cycles = graph.findCycles()
    assertEquals(1, cycles.size)
    assertEquals(3, cycles.first().size)
  }

  @Test
  fun testCycle() {
    val graph = HashDirectedGraph<Int>()
    graph.put(1, 2)
    graph.put(2, 3)
    graph.put(3, 1)
    val cycles = graph.findCycles()
    assertEquals(1, cycles.size)
    assertEquals(4, cycles.first().size)
  }

  @Test
  fun testMinimalCycleWithTail() {
    val graph = HashDirectedGraph<Int>()
    graph.put(1, 2)
    graph.put(2, 3)
    graph.put(3, 2)
    val cycles = graph.findCycles()
    assertEquals(1, cycles.size)
    assertEquals(3, cycles.first().size)
  }

  @Test
  fun testCycleWithTail() {
    val graph = HashDirectedGraph<Int>()
    graph.put(1, 2)
    graph.put(2, 3)
    graph.put(3, 4)
    graph.put(4, 2)
    val cycles = graph.findCycles()
    assertEquals(1, cycles.size)
    assertEquals(4, cycles.first().size)
  }

  @Test
  fun testButterflyCycle() {
    val graph = HashDirectedGraph<Int>()
    graph.put(1, 2)
    graph.put(2, 3)
    graph.put(3, 2)
    graph.put(2, 4)
    graph.put(4, 2)
    val cycles = graph.findCycles().toList()
    assertEquals(2, cycles.size)
    assertEquals(3, cycles[0].size)
    assertEquals(3, cycles[1].size)
  }

  @Test
  fun testAcyclicGraph() {
    val graph = HashDirectedGraph<Int>()
    graph.put(1, 2)
    graph.put(2, 3)
    graph.put(3, 4)
    val cycles = graph.findCycles()
    assertTrue(cycles.isEmpty())
  }
}


/*
 * 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
 *
 * https://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)
    }
}


Add helper methods to find networks by chainID

package org.walleth.data.networks

import org.kethereum.model.ChainId

fun getNetworkDefinitionByChainID(chainID: ChainId) = ALL_NETWORKS.firstOrNull { it.chain.id == chainID }

fun ChainId.findNetworkDefinition() = ALL_NETWORKS.firstOrNull { it.chain.id == this }


plugins {
    java
}

// tag::ignore-property-selected[]
normalization {
    runtimeClasspath {
        properties("**/build-info.properties") {
            ignoreProperty 'timestamp'
        }
    }
}
// end::ignore-property-selected[]

// tag::ignore-property-all[]
normalization {
    runtimeClasspath {
        properties {
            ignoreProperty 'timestamp'
        }
    }
}
// end::ignore-property-all[]

Fix issue with kotlin sample

plugins {
    java
}

// tag::ignore-property-selected[]
normalization {
    runtimeClasspath {
        properties("**/build-info.properties") {
            ignoreProperty("timestamp")
        }
    }
}
// end::ignore-property-selected[]

// tag::ignore-property-all[]
normalization {
    runtimeClasspath {
        properties {
            ignoreProperty("timestamp")
        }
    }
}
// end::ignore-property-all[]


Add new extension functions for SingleLiveEvent to serve as sugar-syntax for shorten calls posting UiState LiveData changes.

package com.github.ramonrabello.kiphy.common.extensions

import com.github.ramonrabello.kiphy.common.arch.state.SingleLiveEvent
import com.github.ramonrabello.kiphy.common.arch.state.UiState

fun SingleLiveEvent<UiState>.postEmptyState() = run { postValue(UiState.Empty) }
fun SingleLiveEvent<UiState>.postLoadingState() = run { postValue(UiState.Loading) }
fun SingleLiveEvent<UiState>.postLoadedState() = run { postValue(UiState.Loaded) }
fun SingleLiveEvent<UiState>.postErrorState() = run { postValue(UiState.Error) }


package com.masahirosaito.spigot.homes.tests

enum class Permission(val permission: String) {

    HOME_DEFAULT("homes.command"),
    HOME_NAME("homes.command.name"),
    HOME_PLAYER("homes.command.player"),
    HOME_PLAYER_NAME("homes.command.player.name"),

    HOME_SET("homes.command.set"),
    HOME_SET_NAME("homes.command.set.name"),

    HOME_DELETE("homes.command.delete"),
    HOME_DELETE_NAME("homes.command.delete.name")
}

Add two permissions for invite command

package com.masahirosaito.spigot.homes.tests

enum class Permission(val permission: String) {

    HOME_DEFAULT("homes.command"),
    HOME_NAME("homes.command.name"),
    HOME_PLAYER("homes.command.player"),
    HOME_PLAYER_NAME("homes.command.player.name"),

    HOME_SET("homes.command.set"),
    HOME_SET_NAME("homes.command.set.name"),

    HOME_DELETE("homes.command.delete"),
    HOME_DELETE_NAME("homes.command.delete.name"),

    HOME_INVITE("homes.command.invite"),
    HOME_INVITE_NAME("homes.command.invite.name")
}


import com.github.kamatama41.gradle.gitrelease.GitReleaseExtension

buildscript {
    val kotlinVersion = "1.2.31"
    extra["kotlinVersion"] = kotlinVersion
    repositories {
        jcenter()
        maven { setUrl("http://kamatama41.github.com/maven-repository/repository") }
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
        classpath("com.github.kamatama41:gradle-git-release-plugin:0.2.0")
    }
}

apply {
    plugin("idea")
    plugin("kotlin")
    plugin("com.github.kamatama41.git-release")
}

repositories {
    jcenter()
}

configure<JavaPluginConvention> {
    sourceCompatibility = JavaVersion.VERSION_1_7
    targetCompatibility = JavaVersion.VERSION_1_7
}

val kotlinVersion: String by extra
dependencies {
    compile("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
    compile("org.embulk:embulk-standards:0.8.18")
    compile("org.embulk:embulk-test:0.8.18")
    testCompile("junit:junit:4.12")
}

configure<GitReleaseExtension> {
    groupId = "com.github.kamatama41"
    artifactId = "embulk-test-helpers"
    repoUri = "git@github.com:kamatama41/maven-repository.git"
    repoDir = file("${System.getProperty("user.home")}/gh-maven-repository")
}

Cut off support for Java 7

import com.github.kamatama41.gradle.gitrelease.GitReleaseExtension

buildscript {
    val kotlinVersion = "1.2.31"
    extra["kotlinVersion"] = kotlinVersion
    repositories {
        jcenter()
        maven { setUrl("http://kamatama41.github.com/maven-repository/repository") }
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
        classpath("com.github.kamatama41:gradle-git-release-plugin:0.2.0")
    }
}

apply {
    plugin("idea")
    plugin("kotlin")
    plugin("com.github.kamatama41.git-release")
}

repositories {
    jcenter()
}

configure<JavaPluginConvention> {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

val kotlinVersion: String by extra
dependencies {
    compile("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
    compile("org.embulk:embulk-standards:0.8.18")
    compile("org.embulk:embulk-test:0.8.18")
    testCompile("junit:junit:4.12")
}

configure<GitReleaseExtension> {
    groupId = "com.github.kamatama41"
    artifactId = "embulk-test-helpers"
    repoUri = "git@github.com:kamatama41/maven-repository.git"
    repoDir = file("${System.getProperty("user.home")}/gh-maven-repository")
}


dependencies {
    implementation(project(":binaryCompatibility"))
    implementation(project(":cleanup"))
    implementation(project(":configuration"))
    implementation(project(":kotlinDsl"))
    implementation(project(":profiling"))
    implementation(project(":plugins"))
}

Add missing dependency to `buildSrc/uber-plugins`

dependencies {
    implementation(project(":binaryCompatibility"))
    implementation(project(":buildquality"))
    implementation(project(":cleanup"))
    implementation(project(":configuration"))
    implementation(project(":kotlinDsl"))
    implementation(project(":profiling"))
    implementation(project(":plugins"))
}


package com.xamoom.android.xamoomsdk

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.altbeacon.beacon.Beacon
import java.util.*
import kotlin.collections.HashMap

class BeaconViewModel: ViewModel() {
 // TODO: Change to minor as key
 val beacons: MutableLiveData<HashMap<Long, Beacon>> by lazy {
  MutableLiveData(emptyMap<Long, Beacon>() as HashMap)
 }

 fun addBeacon(beacon: Beacon) {
  val newValue = beacons.value?: emptyMap<Long, Beacon>() as HashMap
  newValue[System.currentTimeMillis()] = beacon
  beacons.postValue(newValue)
 }

 fun clearBeacons() {
  val empty = beacons.value
  empty?.clear()
  beacons.postValue(empty)
 }
}

Change beaconViewModel to save per minor id

package com.xamoom.android.xamoomsdk

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.altbeacon.beacon.Beacon
import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.LinkedHashMap

class BeaconViewModel : ViewModel() {
    val beacons: MutableLiveData<HashMap<Int, Beacon>> by lazy {
        MutableLiveData(hashMapOf<Int, Beacon>())
    }
    val isInsideRegion: MutableLiveData<Boolean> by lazy { MutableLiveData(false) }

    fun addBeacon(beacon: Beacon) {
        val newValue = beacons.value ?: emptyMap<Int, Beacon>() as HashMap
        newValue[beacon.id3.toInt()] = beacon
        beacons.postValue(newValue)
    }

    fun clearBeacons() {
        val empty = beacons.value
        empty?.clear()
        beacons.postValue(empty)
    }
}


package com.nilhcem.devoxxfr.scraper.api

import com.nilhcem.devoxxfr.scraper.model.devoxx.Speaker
import com.squareup.moshi.Moshi
import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path

interface DevoxxApi {

    companion object {
        private val ENDPOINT = "https://cfp.devoxx.fr/api/conferences/devoxxFR2016/"
        private val MOSHI = MoshiConverterFactory.create(Moshi.Builder().build())

        val SERVICE = Retrofit.Builder()
                .client(OkHttpClient())
                .baseUrl(ENDPOINT)
                .addConverterFactory(MOSHI)
                .build()
                .create(DevoxxApi::class.java)
    }

    @GET("speakers/{uuid}")
    fun getSpeakerDetails(@Path("uuid") uuid: String): Call<Speaker>
}

Create api method to get ScheduleDay

package com.nilhcem.devoxxfr.scraper.api

import com.nilhcem.devoxxfr.scraper.model.devoxx.ScheduleDay
import com.nilhcem.devoxxfr.scraper.model.devoxx.Speaker
import com.squareup.moshi.Moshi
import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path

interface DevoxxApi {

    companion object {
        private val ENDPOINT = "https://cfp.devoxx.fr/api/conferences/devoxxFR2016/"
        private val MOSHI = MoshiConverterFactory.create(Moshi.Builder().build())

        val SERVICE = Retrofit.Builder()
                .client(OkHttpClient())
                .baseUrl(ENDPOINT)
                .addConverterFactory(MOSHI)
                .build()
                .create(DevoxxApi::class.java)
    }

    @GET("schedules/{day}")
    fun getScheduleForDay(@Path("day") day: String): Call<ScheduleDay>

    @GET("speakers/{uuid}")
    fun getSpeakerDetails(@Path("uuid") uuid: String): Call<Speaker>
}


package org.kethereum.functions

import org.kethereum.functions.rlp.RLPList
import org.kethereum.functions.rlp.encode
import org.kethereum.functions.rlp.toRLP
import org.kethereum.model.SignatureData
import org.kethereum.model.Transaction
import org.walleth.khex.hexToByteArray

fun Transaction.toRLPList(signature: SignatureData?) = RLPList(listOf(
        nonce!!.toRLP(),
        gasPrice.toRLP(),
        gasLimit.toRLP(),
        (to?.hex?.let { it } ?: "0x").hexToByteArray().toRLP(),
        value.toRLP(),
        input.toByteArray().toRLP()
).let {

    if (signature == null) {
        it
    } else {
        it.plus(listOf(
                signature.v.toRLP(),
                signature.r.toRLP(),
                signature.s.toRLP()
        ))
    }
})

fun Transaction.encodeRLP(signature: SignatureData? = null) = toRLPList(signature).encode()

Add method to encodeRLP a SignedTransaction()

package org.kethereum.functions

import org.kethereum.functions.rlp.RLPList
import org.kethereum.functions.rlp.encode
import org.kethereum.functions.rlp.toRLP
import org.kethereum.model.SignatureData
import org.kethereum.model.SignedTransaction
import org.kethereum.model.Transaction
import org.walleth.khex.hexToByteArray

fun Transaction.toRLPList(signature: SignatureData?) = RLPList(listOf(
        nonce!!.toRLP(),
        gasPrice.toRLP(),
        gasLimit.toRLP(),
        (to?.hex?.let { it } ?: "0x").hexToByteArray().toRLP(),
        value.toRLP(),
        input.toByteArray().toRLP()
).let {

    if (signature == null) {
        it
    } else {
        it.plus(listOf(
                signature.v.toRLP(),
                signature.r.toRLP(),
                signature.s.toRLP()
        ))
    }
})

fun Transaction.encodeRLP(signature: SignatureData? = null) = toRLPList(signature).encode()
fun SignedTransaction.encodeRLP() = transaction.toRLPList(signatureData).encode()


description = "doma-slf4j"

dependencies {
    api("org.slf4j:slf4j-api:1.7.32")
    implementation(project(":doma-core"))
    testImplementation("ch.qos.logback:logback-classic:1.2.5")
}

Update dependency ch.qos.logback:logback-classic to v1.2.6

description = "doma-slf4j"

dependencies {
    api("org.slf4j:slf4j-api:1.7.32")
    implementation(project(":doma-core"))
    testImplementation("ch.qos.logback:logback-classic:1.2.6")
}


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

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

class StringElement : CommandElement<String> {

    override fun parse(list: ArgumentList): String {
        return if (list.peek().startsWith("\"")) {
            val string = buildString {
                while (true) {
                    if(!list.hasNext()){
                        throw ArgumentParseException("Unmatched quotes")
                    }
                    val next = list.popFirst()
                    append(next + " ")
                    if (next.endsWith("\"")) {
                        break
                    }
                }
            }
            string.trim().substring(1..(string.length-3))
        } else {
            list.popFirst()
        }
    }
}

Update regex to support escaped quotes with "

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

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

class StringElement : CommandElement<String> {

    override fun parse(list: ArgumentList): String {
        return if (list.peek().matches(Regex("^(?<!\\\\)\\\".*"))) {
            val string = buildString {
                while (true) {
                    if(!list.hasNext()){
                        throw ArgumentParseException("Unmatched quotes")
                    }
                    val next = list.popFirst()
                    append(next + " ")
                    if (next.matches(Regex(".*(?<!\\\\)\\\"\$"))) {
                        break
                    }
                }
            }
            string.trim().substring(1..(string.length-3)).replace("\\\"", "\"")
        } else {
            list.popFirst()
        }
    }
}


package com.chibatching.kotpref

import org.robolectric.RobolectricGradleTestRunner
import org.robolectric.annotation.Config
import org.robolectric.manifest.AndroidManifest
import org.robolectric.res.FileFsFile

class CustomRobolectricTestRunner(testClass: Class<*>) : RobolectricGradleTestRunner(testClass) {

    companion object {
        val BUILD_OUTPUT = "build/intermediates"
        val TEST_FLAVOR = "androidTest"
    }

    override fun getAppManifest(config: Config?): AndroidManifest? {

        val res = FileFsFile.from(BUILD_OUTPUT, "res/merged", TEST_FLAVOR, BuildConfig.BUILD_TYPE)
        val assets = FileFsFile.from(BUILD_OUTPUT, "assets", TEST_FLAVOR, BuildConfig.BUILD_TYPE)
        val manifest = FileFsFile.from(BUILD_OUTPUT, "manifest", TEST_FLAVOR, BuildConfig.BUILD_TYPE, "AndroidManifest.xml")

        return AndroidManifest(manifest, res, assets, BuildConfig.APPLICATION_ID)
    }
}

Fix test resource file path in TestRunner

package com.chibatching.kotpref

import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.manifest.AndroidManifest
import org.robolectric.res.FileFsFile

class CustomRobolectricTestRunner(testClass: Class<*>) : RobolectricTestRunner(testClass) {

    companion object {
        val BUILD_OUTPUT = "build/intermediates/bundles"
    }

    override fun getAppManifest(config: Config?): AndroidManifest? {

        val res = FileFsFile.from(BUILD_OUTPUT, BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, "res")
        val assets = FileFsFile.from(BUILD_OUTPUT, BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, "assets")
        val manifest = FileFsFile.from(BUILD_OUTPUT, BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, "AndroidManifest.xml")

        return AndroidManifest(manifest, res, assets, BuildConfig.APPLICATION_ID)
    }
}


/*
 * Use of this source code is governed by the MIT license that can be
 * found in the LICENSE file.
 */

package org.rust.ide.annotator.fixes

import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.rust.ide.core.overrideImplement.generateTraitMembers
import org.rust.lang.core.psi.RsImplItem

/**
 * Adds unimplemented methods and associated types to an impl block
 */
class ImplementMembersFix(
    implBody: RsImplItem
) : LocalQuickFixAndIntentionActionOnPsiElement(implBody) {

    override fun getText(): String = "Implement methods"

    override fun getFamilyName(): String = text

    override fun startInWriteAction(): Boolean = false

    override fun invoke(
        project: Project,
        file: PsiFile,
        editor: Editor?,
        startElement: PsiElement,
        endElement: PsiElement
    ) {
        val impl = (startElement as RsImplItem)
        generateTraitMembers(impl, editor)
    }
}

Change "Implement methods" to "Implement members"

/*
 * Use of this source code is governed by the MIT license that can be
 * found in the LICENSE file.
 */

package org.rust.ide.annotator.fixes

import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.rust.ide.core.overrideImplement.generateTraitMembers
import org.rust.lang.core.psi.RsImplItem

/**
 * Adds unimplemented methods and associated types to an impl block
 */
class ImplementMembersFix(
    implBody: RsImplItem
) : LocalQuickFixAndIntentionActionOnPsiElement(implBody) {

    override fun getText(): String = "Implement members"

    override fun getFamilyName(): String = text

    override fun startInWriteAction(): Boolean = false

    override fun invoke(
        project: Project,
        file: PsiFile,
        editor: Editor?,
        startElement: PsiElement,
        endElement: PsiElement
    ) {
        val impl = (startElement as RsImplItem)
        generateTraitMembers(impl, editor)
    }
}


package org.nwapw.abacus.context

import org.nwapw.abacus.exception.ContextException
import kotlin.reflect.KProperty

/**
 * A delegate to search a hierarchy made up of [EvaluationContext].
 *
 * ChainSearchDelegate is a variable delegate written specifically for use in [EvaluationContext], because
 * of its hierarchical structure. Variables not found in the current context are searched
 * for in its parent, which continues recursively until the context being examined has no parent.
 * This class assists that logic, which is commonly re-used with different variable types, by calling
 * [valueGetter] on the current context, then its parent, etc.
 *
 * @param V the type of the property to search recursively.
 * @property valueGetter the getter lambda to access the value from the context.
 */
class ChainSearchDelegate<out V>(private val valueGetter: EvaluationContext.() -> V?) {

    operator fun getValue(selfRef: Any, property: KProperty<*>): V {
        var currentRef = selfRef as EvaluationContext
        var returnedValue = currentRef.valueGetter()
        while (returnedValue == null) {
            currentRef = currentRef.parent ?: break
            returnedValue = currentRef.valueGetter()
        }
        return returnedValue ?: throw ContextException()
    }

}

Add more descriptive message to context exceptions.

package org.nwapw.abacus.context

import org.nwapw.abacus.exception.ContextException
import kotlin.reflect.KProperty

/**
 * A delegate to search a hierarchy made up of [EvaluationContext].
 *
 * ChainSearchDelegate is a variable delegate written specifically for use in [EvaluationContext], because
 * of its hierarchical structure. Variables not found in the current context are searched
 * for in its parent, which continues recursively until the context being examined has no parent.
 * This class assists that logic, which is commonly re-used with different variable types, by calling
 * [valueGetter] on the current context, then its parent, etc.
 *
 * @param V the type of the property to search recursively.
 * @property valueGetter the getter lambda to access the value from the context.
 */
class ChainSearchDelegate<out V>(private val valueGetter: EvaluationContext.() -> V?) {

    operator fun getValue(selfRef: Any, property: KProperty<*>): V {
        var currentRef = selfRef as EvaluationContext
        var returnedValue = currentRef.valueGetter()
        while (returnedValue == null) {
            currentRef = currentRef.parent ?: break
            returnedValue = currentRef.valueGetter()
        }
        return returnedValue ?: throw ContextException("context chain does not contain value")
    }

}


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

package androidx.build.resources

import com.android.build.gradle.LibraryExtension
import org.gradle.api.Project
import org.gradle.api.tasks.Copy
import java.io.File

fun Project.configurePublicResourcesStub(extension: LibraryExtension) {
    val targetResFolder = File(project.buildDir, "generated/res/public-stub")

    val generatePublicResourcesTask = tasks.register(
        "generatePublicResourcesStub",
        Copy::class.java
    ) { task ->
        task.from(File(project.rootDir, "buildSrc/res"))
        task.into(targetResFolder)
    }

    extension.libraryVariants.all { variant ->
        variant.registerGeneratedResFolders(
            project.files(targetResFolder).builtBy(generatePublicResourcesTask)
        )
    }
}

Use playground agnostic way of determining project.rootDir

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

package androidx.build.resources

import androidx.build.getSupportRootFolder
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Project
import org.gradle.api.tasks.Copy
import java.io.File

fun Project.configurePublicResourcesStub(extension: LibraryExtension) {
    val targetResFolder = File(project.buildDir, "generated/res/public-stub")

    val generatePublicResourcesTask = tasks.register(
        "generatePublicResourcesStub",
        Copy::class.java
    ) { task ->
        task.from(File(project.getSupportRootFolder(), "buildSrc/res"))
        task.into(targetResFolder)
    }

    extension.libraryVariants.all { variant ->
        variant.registerGeneratedResFolders(
            project.files(targetResFolder).builtBy(generatePublicResourcesTask)
        )
    }
}


import org.asciidoctor.gradle.jvm.pdf.AsciidoctorPdfTask
import org.asciidoctor.gradle.jvm.ProcessMode

// tag::using-two-plugins-three-backends[]
plugins {
    id("org.asciidoctor.jvm.pdf")
//    id("com.gradle.build-scan") version "1.16"
}

repositories {
    jcenter()
}

asciidoctorj {
    modules.getDiagram().setVersion("1.5.16")
    logLevel = LogLevel.INFO
}

tasks.named<AsciidoctorPdfTask>("asciidoctorPdf") {
    inProcess = "OUT_OF_PROCESS"
    logDocuments = true
    setSourceDir("src/docs/asciidoc")

    sources ("subdir/sample2.ad")
}
// end::using-two-plugins-three-backends[]

tasks.register<DefaultTask>("runGradleTest") {
    group = "Custom"
    dependsOn("asciidoctorPdf")
}

Use named type rather than string in Kotlin DSL

import org.asciidoctor.gradle.jvm.pdf.AsciidoctorPdfTask
import org.asciidoctor.gradle.jvm.ProcessMode

// tag::using-two-plugins-three-backends[]
plugins {
    id("org.asciidoctor.jvm.pdf")
//    id("com.gradle.build-scan") version "1.16"
}

repositories {
    jcenter()
}

asciidoctorj {
    modules.getDiagram().setVersion("1.5.16")
    logLevel = LogLevel.INFO
}

tasks.named<AsciidoctorPdfTask>("asciidoctorPdf") {
    inProcess = ProcessMode.OUT_OF_PROCESS
    logDocuments = true
    setSourceDir("src/docs/asciidoc")

    sources ("subdir/sample2.ad")
}
// end::using-two-plugins-three-backends[]

tasks.register<DefaultTask>("runGradleTest") {
    group = "Custom"
    dependsOn("asciidoctorPdf")
}


package io.ktor.client

import io.ktor.client.backend.*
import io.ktor.client.call.*
import io.ktor.client.features.*
import io.ktor.client.request.*
import io.ktor.client.response.*
import io.ktor.client.utils.*

object HttpClientFactory {
    fun createDefault(backendFactory: HttpClientBackendFactory, block: ClientConfig.() -> Unit = {}): HttpClient {
        val backend = backendFactory {}

        return ClientConfig(backend).apply {
            install("backend") {
                requestPipeline.intercept(HttpRequestPipeline.Send) { builder ->
                    val request = (builder as? HttpRequestBuilder)?.build() ?: return@intercept
                    if (request.body !is HttpMessageBody) error("Body can't be processed: ${request.body}")

                    val response = backend.makeRequest(request)
                    proceedWith(HttpClientCall(request, response, context))
                }

                responsePipeline.intercept(HttpResponsePipeline.After) { container ->
                    container.response.close()
                }
            }

            install(HttpPlainText)
            install(HttpIgnoreBody)
            block()
        }.build()
    }
}

Check body type in backend response

package io.ktor.client

import io.ktor.client.backend.*
import io.ktor.client.call.*
import io.ktor.client.features.*
import io.ktor.client.request.*
import io.ktor.client.response.*
import io.ktor.client.utils.*

object HttpClientFactory {
    fun createDefault(backendFactory: HttpClientBackendFactory, block: ClientConfig.() -> Unit = {}): HttpClient {
        val backend = backendFactory {}

        return ClientConfig(backend).apply {
            install("backend") {
                requestPipeline.intercept(HttpRequestPipeline.Send) { builder ->
                    val request = (builder as? HttpRequestBuilder)?.build() ?: return@intercept

                    if (request.body !is HttpMessageBody) error("Body can't be processed: ${request.body}")
                    val response = backend.makeRequest(request)
                    if (response.body !is HttpMessageBody) error("Client backend response has wrong format: ${request.body}")

                    proceedWith(HttpClientCall(request, response, context))
                }

                responsePipeline.intercept(HttpResponsePipeline.After) { container ->
                    container.response.close()
                }
            }

            install(HttpPlainText)
            install(HttpIgnoreBody)
            block()
        }.build()
    }
}


Add attribute class for easier element manipulation

package org.wordpress.aztec

import org.xml.sax.Attributes
import org.xml.sax.helpers.AttributesImpl

class AztecAttributes(attributes: Attributes = AttributesImpl()) : AttributesImpl(attributes) {

    fun setValue(key: String, value: String) {
        val index = getIndex(key)
        if (index == -1) {
            addAttribute("", key, key, "string", value)
        } else {
            setValue(index, value)
        }
    }

    fun isEmpty() : Boolean {
        return length == 0
    }

    fun hasAttribute(key: String) : Boolean {
        return getValue(key) == null
    }

    override fun toString(): String {
        val sb = StringBuilder()
        for (i in 0..this.length-1) {
            sb.append(this.getLocalName(i))
            sb.append("=\"")
            sb.append(this.getValue(i))
            sb.append("\" ")
        }
        return sb.trimEnd().toString()
    }
}


Create a class to obtain texts wrapping the Android SDK

package com.wilderpereira.lmgtfygen.utils

import android.content.res.Resources
import android.support.annotation.StringRes
import javax.inject.Inject

class TextProvider @Inject constructor(val resources: Resources){

    fun getText(@StringRes resId: Int): String = resources.getString(resId)
}


plugins {
    jacoco
}

afterEvaluate {
    tasks.withType<JacocoReport> {
        dependsOn(tasks.getByName("test"))
        reports {
            xml.isEnabled = true
            xml.destination = file("${coverageRoot(project)}/xmlReport")

            html.isEnabled = true
            html.destination = file("${coverageRoot(project)}/htmlReport")
        }
    }
}

fun coverageRoot(project: Project): String {
    return "${project(":coverage").buildDir}/${project.name}"
}

Fix xml coverage report name

plugins {
    jacoco
}

afterEvaluate {
    tasks.withType<JacocoReport> {
        dependsOn(tasks.getByName("test"))
        reports {
            xml.isEnabled = true
            xml.destination = file("${coverageRoot(project)}/report.xml")

            html.isEnabled = true
            html.destination = file("${coverageRoot(project)}/htmlReport")
        }
    }
}

fun coverageRoot(project: Project): String {
    return "${project(":coverage").buildDir}/${project.name}"
}


package de.markusfisch.android.binaryeye.actions.web

import android.content.Context
import de.markusfisch.android.binaryeye.R
import de.markusfisch.android.binaryeye.actions.IAction
import de.markusfisch.android.binaryeye.content.openUrl

object WebAction : IAction {
	private val colloquialRegex =
		"""^(http[s]*://)*([a-z0-9]+[a-z0-9-]*[a-z0-9]+[.])+[a-z]{2,}([?#/]+[\w/=&;._-]*)*$""".toRegex(
			RegexOption.IGNORE_CASE
		)

	override val iconResId: Int = R.drawable.ic_action_open
	override val titleResId: Int = R.string.open_url

	override fun canExecuteOn(data: ByteArray): Boolean {
		return String(data).trim().matches(colloquialRegex)
	}

	override suspend fun execute(context: Context, data: ByteArray) {
		var url = String(data).trim()
		if (!url.startsWith("http") && !url.startsWith("ftp")) {
			url = "http://${url}"
		}
		context.openUrl(url)
	}
}

Simplify RegEx to recognize URLs

package de.markusfisch.android.binaryeye.actions.web

import android.content.Context
import de.markusfisch.android.binaryeye.R
import de.markusfisch.android.binaryeye.actions.IAction
import de.markusfisch.android.binaryeye.content.openUrl

object WebAction : IAction {
	private val colloquialRegex =
		"^(http[s]*://)*[A-Za-z0-9]{3,}\\.[A-Za-z]{2,}[^ \t\r\n]*$".toRegex()

	override val iconResId: Int = R.drawable.ic_action_open
	override val titleResId: Int = R.string.open_url

	override fun canExecuteOn(data: ByteArray): Boolean {
		return String(data).trim().matches(colloquialRegex)
	}

	override suspend fun execute(context: Context, data: ByteArray) {
		var url = String(data).trim()
		if (!url.startsWith("http") && !url.startsWith("ftp")) {
			url = "http://${url}"
		}
		context.openUrl(url)
	}
}


Add color generator from original project ported to kotlin

package com.kennyc.textdrawable

import kotlin.random.Random

class ColorGenerator private constructor(private val mColors: List<Int>) {
    private val mRandom: Random = Random(System.currentTimeMillis())

    val randomColor: Int
        get() = mColors[mRandom.nextInt(mColors.size)]

    fun getColor(key: Any): Int {
        return mColors[Math.abs(key.hashCode()) % mColors.size]
    }

    companion object {

        var DEFAULT: ColorGenerator = create(listOf(
                -0xe9c9c,
                -0xa7aa7,
                -0x65bc2,
                -0x1b39d2,
                -0x98408c,
                -0xa65d42,
                -0xdf6c33,
                -0x529d59,
                -0x7fa87f
        ))

        var MATERIAL: ColorGenerator = create(listOf(
                -0x1a8c8d,
                -0xf9d6e,
                -0x459738,
                -0x6a8a33,
                -0x867935,
                -0x9b4a0a,
                -0xb03c09,
                -0xb22f1f,
                -0xb24954,
                -0x7e387c,
                -0x512a7f,
                -0x759b,
                -0x2b1ea9,
                -0x2ab1,
                -0x48b3,
                -0x5e7781,
                -0x6f5b52
        ))

        fun create(colorList: List<Int>): ColorGenerator {
            return ColorGenerator(colorList)
        }
    }
}


package api.item

import api.predef.*
import io.luna.game.model.item.Item

/**
 * A model representing a loot table. Loot tables are collections of items that can select items to be picked based
 * on their rarity.
 *
 * @author lare96
 */
class LootTable(private val items: List<LootTableItem>) : Iterable<LootTableItem> {

    override fun iterator(): Iterator<LootTableItem> = items.iterator()

    /**
     * Picks [amount] items from this loot table.
     */
    fun pick(amount: Int): List<Item> {
        val lootItems = ArrayList<Item>(amount)
        for (loot in items) {
            if (roll(loot)) {
                lootItems += loot.getItem()
            }
        }
        return lootItems
    }

    /**
     * Picks one item from this loot table.
     */
    fun pick(): Item = pickAll().random()

    /**
     * Picks all items from this loot table.
     */
    fun pickAll(): List<Item> = pick(items.size)

    /**
     * Determines if [loot] will be picked based on its rarity.
     */
    private fun roll(loot: LootTableItem): Boolean {
        val chance = loot.chance
        return when {
            chance.numerator <= 0 -> false
            chance.numerator >= chance.denominator -> true
            rand(0, chance.denominator) <= chance.numerator -> true
            else -> false
        }
    }
}

Test and fix bugs with loot tables

package api.item

import api.predef.*
import io.luna.game.model.item.Item

/**
 * A model representing a loot table. Loot tables are collections of items that can select items to be picked based
 * on their rarity.
 *
 * @author lare96
 */
class LootTable(private val items: List<LootTableItem>) : Iterable<LootTableItem> {

    override fun iterator(): Iterator<LootTableItem> = items.iterator()

    /**
     * Rolls on one item from this loot table.
     */
    fun pick(): Item? {
        val all = pickAll()
        return when (all.isEmpty()) {
            true -> null
            false -> all.random()
        }
    }

    /**
     * Rolls on all items from this loot table.
     */
    fun pickAll(): List<Item> {
        val lootItems = ArrayList<Item>(items.size)
        for (loot in items) {
            if (roll(loot)) {
                lootItems += loot.getItem()
            }
        }
        return lootItems
    }

    /**
     * Determines if [loot] will be picked based on its rarity.
     */
    private fun roll(loot: LootTableItem): Boolean {
        val chance = loot.chance
        return when {
            chance.numerator <= 0 -> false
            chance.numerator >= chance.denominator -> true
            rand(0, chance.denominator) <= chance.numerator -> true
            else -> false
        }
    }
}


package com.louiscad.splittiessample.extensions

import android.view.View
import androidx.core.view.isInvisible
import androidx.core.view.isVisible

inline fun <R> View.visibleInScope(finallyInvisible: Boolean = false, block: () -> R) = try {
    isVisible = true
    block()
} finally {
    visibility = if (finallyInvisible) View.INVISIBLE else View.GONE
}

inline fun <R> View.goneInScope(block: () -> R) = try {
    isVisible = false
    block()
} finally {
    isVisible = true
}

inline fun <R> View.invisibleInScope(block: () -> R) = try {
    isInvisible = true
    block()
} finally {
    isInvisible = false
}

Add contracts to view visibility scope extensions

package com.louiscad.splittiessample.extensions

import android.view.View
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

@ExperimentalContracts
inline fun <R> View.visibleInScope(finallyInvisible: Boolean = false, block: () -> R): R {
    contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
    return try {
        isVisible = true
        block()
    } finally {
        visibility = if (finallyInvisible) View.INVISIBLE else View.GONE
    }
}

@ExperimentalContracts
inline fun <R> View.goneInScope(block: () -> R): R {
    contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
    return try {
        isVisible = false
        block()
    } finally {
        isVisible = true
    }
}

@ExperimentalContracts
inline fun <R> View.invisibleInScope(block: () -> R): R {
    contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
    return try {
        isInvisible = true
        block()
    } finally {
        isInvisible = false
    }
}


package venus.riscv.insts.dsl

import venus.riscv.insts.dsl.formats.ITypeFormat
import venus.riscv.insts.dsl.impls.ITypeImplementation32
import venus.riscv.insts.dsl.impls.NoImplementation
import venus.riscv.insts.dsl.parsers.ITypeParser
import venus.riscv.insts.dsl.relocators.InstructionRelocator32
import venus.riscv.insts.dsl.relocators.InstructionRelocator64
import venus.riscv.insts.dsl.relocators.NoRelocator32
import venus.riscv.insts.dsl.relocators.NoRelocator64

class ITypeInstruction(
        name: String,
        opcode: Int,
        funct3: Int,
        eval32: (Int, Int) -> Int,
        eval64: (Long, Long) -> Long = { _, _ -> throw NotImplementedError("no rv64") },
        relocator32: InstructionRelocator32 = NoRelocator32,
        relocator64: InstructionRelocator64 = NoRelocator64
) : Instruction(
        name = name,
        format = ITypeFormat(opcode, funct3),
        parser = ITypeParser,
        impl32 = ITypeImplementation32(eval32),
        impl64 = NoImplementation,
        relocator32 = relocator32,
        relocator64 = relocator64
)

Add stubs for RV64 support


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

@file:Suppress("PackageDirectoryMismatch")

import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.androidJvm
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.common
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.js
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.native
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import java.util.Locale

fun KotlinTarget.configureMavenPublication() {
    val suffix = when (platformType) {
        common -> "-metadata"
        jvm -> ""
        js -> "-js"
        androidJvm -> ""
        native -> "-${name.toLowerCase(Locale.ROOT)}"
    }
    mavenPublication {
        val prefix = if (project.isFunPack) "splitties-fun-pack" else "splitties"
        artifactId = "$prefix-${project.name}$suffix"
    }
    if (platformType == androidJvm) {
        (this as KotlinAndroidTarget).publishLibraryVariants("debug", "release")
        this.publishLibraryVariantsGroupedByFlavor = true
    }
}

Disable metadata for android publications

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

@file:Suppress("PackageDirectoryMismatch")

import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.androidJvm
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.common
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.js
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.native
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import java.util.Locale

fun KotlinTarget.configureMavenPublication() {
    val suffix = when (platformType) {
        common -> "-metadata"
        jvm -> ""
        js -> "-js"
        androidJvm -> ""
        native -> "-${name.toLowerCase(Locale.ROOT)}"
    }
    mavenPublication {
        val prefix = if (project.isFunPack) "splitties-fun-pack" else "splitties"
        artifactId = "$prefix-${project.name}$suffix"
        if (platformType == androidJvm) {
            val capitalizedPublicationName = "${name.first().toTitleCase()}${name.substring(1)}"
            project.tasks.getByName("generateMetadataFileFor${capitalizedPublicationName}Publication")
                .apply { enabled = false }
        }
    }
    if (platformType == androidJvm) {
        (this as KotlinAndroidTarget).publishLibraryVariants("debug", "release")
        this.publishLibraryVariantsGroupedByFlavor = true
    }
}


/*
 * Copyright 2019 PolyForest
 *
 * 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.
 */

val GRADLE_VERSION: String by extra
val PRODUCT_VERSION: String by extra
val PRODUCT_GROUP: String by extra
allprojects {
    repositories {
        jcenter()
    }

    tasks.withType<Wrapper> {
        gradleVersion = GRADLE_VERSION
        distributionType = Wrapper.DistributionType.ALL
    }

    if (tasks.findByName(":clean") != null) {
        val clean by tasks.existing(Delete::class) {
            delete(fileTree(".").matching {
                include("**/out/", "**/dist/", "**/www", "**/wwwDist")
            })
            // Pseudo-Code:TODO | remove
            afterEvaluate {
                println("[$name] - $delete")
            }
        }
    }

    version = PRODUCT_VERSION
    group = PRODUCT_GROUP
}

Refactor clean task and remove debug println

/*
 * Copyright 2019 PolyForest
 *
 * 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.
 */

val GRADLE_VERSION: String by extra
val PRODUCT_VERSION: String by extra
val PRODUCT_GROUP: String by extra
allprojects {
    repositories {
        jcenter()
    }

    tasks.withType<Wrapper> {
        gradleVersion = GRADLE_VERSION
        distributionType = Wrapper.DistributionType.ALL
    }

    tasks.withType(Delete::class.java)
            .matching {
                it.name == BasePlugin.CLEAN_TASK_NAME
            }
            .all {
                delete(fileTree(".").matching {
                    include("**/out/", "**/dist/", "**/www", "**/wwwDist")
                })
            }

    version = PRODUCT_VERSION
    group = PRODUCT_GROUP
}


/*
 * Copyright 2000-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * See LICENSE in the project root for license information.
 */

package jetbrains.buildServer.dotnet

import jetbrains.buildServer.agent.CommandLineArgument
import jetbrains.buildServer.agent.runner.ParametersService
import kotlin.coroutines.experimental.buildSequence

class CustomCommand(
        _parametersService: ParametersService,
        override val resultsAnalyzer: ResultsAnalyzer,
        private val _targetService: TargetService,
        private val _commonArgumentsProvider: DotnetCommonArgumentsProvider,
        override val toolResolver: DotnetToolResolver,
        private val _vstestLoggerEnvironment: EnvironmentBuilder)
    : DotnetCommandBase(_parametersService) {

    override val commandType: DotnetCommandType
        get() = DotnetCommandType.Custom

    override val targetArguments: Sequence<TargetArguments>
        get() = _targetService.targets.map { TargetArguments(sequenceOf(CommandLineArgument(it.targetFile.path))) }

    override val arguments: Sequence<CommandLineArgument>
        get() = _commonArgumentsProvider.arguments

    override val environmentBuilders: Sequence<EnvironmentBuilder>
        get() = buildSequence { yield(_vstestLoggerEnvironment) }
}


Add ReceiveChannel.doOnEach(…) in sample sources

/*
 * Copyright (c) 2018. Louis Cognault Ayeva Derman
 *
 * 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.louiscad.splittiessample.extensions.coroutines

import kotlinx.coroutines.experimental.CoroutineScope
import kotlinx.coroutines.experimental.channels.ReceiveChannel
import kotlinx.coroutines.experimental.channels.consumeEach
import kotlinx.coroutines.experimental.launch
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.experimental.EmptyCoroutineContext
import kotlin.coroutines.experimental.coroutineContext

suspend inline fun <E> ReceiveChannel<E>.doOnEach(
        context: CoroutineContext = EmptyCoroutineContext,
        noinline action: suspend (E) -> Unit
) = CoroutineScope(coroutineContext).launch(context) { consumeEach { action(it) } }


package com.beust.kobalt

import com.beust.kobalt.misc.KFiles

object Constants {
    const val LOG_DEFAULT_LEVEL = 1
    const val LOG_MAX_LEVEL = 3
    val BUILD_FILE_NAME = "Build.kt"
    val BUILD_FILE_DIRECTORY = "kobalt/src"
    val BUILD_FILE_PATH = KFiles.joinDir(BUILD_FILE_DIRECTORY, BUILD_FILE_NAME)
    val KOTLIN_COMPILER_VERSION = "1.1.0-beta-22"

    internal val DEFAULT_REPOS = listOf<String>(
            //            "https://maven-central.storage.googleapis.com/",
            "http://repo1.maven.org/maven2/",
            "https://jcenter.bintray.com/",
            "http://repository.jetbrains.com/all/",
            "https://dl.bintray.com/kotlin/kotlin-eap",
            "https://dl.bintray.com/kotlin/kotlin-eap-1.1"

            // snapshots
//            "https://oss.sonatype.org/content/repositories/snapshots/"
//            , "https://repository.jboss.org/nexus/content/repositories/root_repository/"
    )

}

Remove the JetBrains repo (which contains snapshots).

package com.beust.kobalt

import com.beust.kobalt.misc.KFiles

object Constants {
    const val LOG_DEFAULT_LEVEL = 1
    const val LOG_MAX_LEVEL = 3
    val BUILD_FILE_NAME = "Build.kt"
    val BUILD_FILE_DIRECTORY = "kobalt/src"
    val BUILD_FILE_PATH = KFiles.joinDir(BUILD_FILE_DIRECTORY, BUILD_FILE_NAME)
    val KOTLIN_COMPILER_VERSION = "1.1.0-beta-22"

    internal val DEFAULT_REPOS = listOf<String>(
            //            "https://maven-central.storage.googleapis.com/",
            "http://repo1.maven.org/maven2/",
            "https://jcenter.bintray.com/",
//            "http://repository.jetbrains.com/all/", // <-- contains snapshots
            "https://dl.bintray.com/kotlin/kotlin-eap",
            "https://dl.bintray.com/kotlin/kotlin-eap-1.1"

            // snapshots
//            "https://oss.sonatype.org/content/repositories/snapshots/"
//            , "https://repository.jboss.org/nexus/content/repositories/root_repository/"
    )

}


Add a base Fragment that does not use Bridge

package com.livefront.bridgesample.base

import android.os.Bundle
import android.support.v4.app.Fragment
import com.evernote.android.state.StateSaver

open class NonBridgeBaseFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        StateSaver.restoreInstanceState(this, savedInstanceState)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        StateSaver.saveInstanceState(this, outState)
    }
}


package io.gitlab.arturbosch.tinbo.api.config

import org.apache.log4j.LogManager
import java.io.IOException

/**
 * @author artur
 */
object Notification {

	private val logger = LogManager.getLogger(javaClass)

	private const val NOTIFY_SEND_ERROR = "Could not execute 'notify-send', install it to get notifications about finished timers."

	fun notify(header: String, message: String) {
		try {
			ProcessBuilder("notify-send", header, message, "--icon=dialog-information").start()
		} catch (e: IOException) {
			println(NOTIFY_SEND_ERROR)
			logger.error(NOTIFY_SEND_ERROR, e)
		}
	}

}

Support windows msg for notifications

package io.gitlab.arturbosch.tinbo.api.config

import java.io.IOException
import java.io.UncheckedIOException

/**
 * @author artur
 */
object Notification {

	private const val NOTIFY_SEND_ERROR =
			"Could not execute 'notify-send', install 'libnotify' to get notifications about finished timers."
	private const val MSG_ERROR = "Could not send notification via msg.exe."

	fun notify(header: String, message: String) {
		if (System.getProperty("os.name").contains("Windows")) {
			try {
				ProcessBuilder("msg", "*", "$header - $message").start()
			} catch (e: IOException) {
				println(MSG_ERROR)
				throw UncheckedIOException(e)
			}
		} else {
			try {
				ProcessBuilder("notify-send", header, message, "--icon=dialog-information").start()
			} catch (e: IOException) {
				println(NOTIFY_SEND_ERROR)
				throw UncheckedIOException(e)
			}
		}
	}
}


plugins {
    java
}

dependencies {
    repositories {
        mavenCentral()
    }

    implementation(Lib.commons_io)
    implementation(Lib.annimon)
    implementation(Lib.univocity)
}

val updateBusStops by tasks.creating(JavaExec::class) {
    classpath(sourceSets["main"].runtimeClasspath)
    main = "fr.cph.chicago.update.UpdateBusStops"
    args("$buildDir/tmp/", "${parent!!.projectDir}/android-app/src/main/assets/")
}

val updateTrainStops by tasks.creating(JavaExec::class) {
    classpath(sourceSets["main"].runtimeClasspath)
    main = "fr.cph.chicago.update.UpdateTrainStops"
    args("$buildDir/tmp/", "${parent!!.projectDir}/android-app/src/main/assets/")
}

val update: Task by tasks.creating {
    dependsOn(updateBusStops, updateTrainStops)
}

Use non deprecated api in update-app

plugins {
    java
}

dependencies {
    repositories {
        mavenCentral()
    }

    implementation(Lib.commons_io)
    implementation(Lib.annimon)
    implementation(Lib.univocity)
}

val updateBusStops by tasks.creating(JavaExec::class) {
    classpath(sourceSets["main"].runtimeClasspath)
    mainClass.set("fr.cph.chicago.update.UpdateBusStops")
    args("$buildDir/tmp/", "${parent!!.projectDir}/android-app/src/main/assets/")
}

val updateTrainStops by tasks.creating(JavaExec::class) {
    classpath(sourceSets["main"].runtimeClasspath)
    mainClass.set("fr.cph.chicago.update.UpdateTrainStops")
    args("$buildDir/tmp/", "${parent!!.projectDir}/android-app/src/main/assets/")
}

val update: Task by tasks.creating {
    dependsOn(updateBusStops, updateTrainStops)
}


package net.squanchy.eventdetails.widget

import android.content.Context
import android.support.design.widget.CoordinatorLayout
import android.util.AttributeSet
import android.view.View
import kotlinx.android.synthetic.main.activity_event_details.view.*
import net.squanchy.R
import net.squanchy.schedule.domain.view.Event
import net.squanchy.schedule.domain.view.Event.Type
import net.squanchy.support.widget.SpeakerView

class EventDetailsCoordinatorLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet,
    defStyleAttr: Int = 0
) : CoordinatorLayout(context, attrs, defStyleAttr) {

    internal fun updateWith(event: Event, listener: OnEventDetailsClickListener) {
        eventDetailsHeaderLayout.updateWith(event, listener)
        eventDetailsLayout.updateWith(event)

        if (canBeFavorited(event)) {
            favoriteFab.setImageResource(
                    if (event.favorited)
                        R.drawable.ic_favorite_filled
                    else R.drawable.ic_favorite_empty
            )
            favoriteFab.setOnClickListener { listener.onFavoriteClick() }
            favoriteFab.visibility = View.VISIBLE
        } else {
            favoriteFab.visibility = View.GONE
        }
    }

    private fun canBeFavorited(event: Event) = event.type === Type.TALK || event.type === Type.KEYNOTE

    internal interface OnEventDetailsClickListener : OnFavoriteClickListener, SpeakerView.OnSpeakerClickListener

    internal interface OnFavoriteClickListener {

        fun onFavoriteClick()
    }
}

Allow workshops to be favourited

package net.squanchy.eventdetails.widget

import android.content.Context
import android.support.design.widget.CoordinatorLayout
import android.util.AttributeSet
import androidx.view.isVisible
import kotlinx.android.synthetic.main.activity_event_details.view.*
import net.squanchy.R
import net.squanchy.schedule.domain.view.Event
import net.squanchy.schedule.domain.view.Event.Type
import net.squanchy.support.widget.SpeakerView

class EventDetailsCoordinatorLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet,
    defStyleAttr: Int = 0
) : CoordinatorLayout(context, attrs, defStyleAttr) {

    internal fun updateWith(event: Event, listener: OnEventDetailsClickListener) {
        eventDetailsHeaderLayout.updateWith(event, listener)
        eventDetailsLayout.updateWith(event)

        if (event.canBeFavorited) {
            val favoriteImage = if (event.favorited) R.drawable.ic_favorite_filled else R.drawable.ic_favorite_empty
            favoriteFab.setImageResource(favoriteImage)
            favoriteFab.setOnClickListener { listener.onFavoriteClick() }
            favoriteFab.isVisible = true
        } else {
            favoriteFab.isVisible = false
        }
    }

    private val Event.canBeFavorited
        get() = type == Type.TALK || type == Type.KEYNOTE || type == Type.WORKSHOP

    internal interface OnEventDetailsClickListener : OnFavoriteClickListener, SpeakerView.OnSpeakerClickListener

    internal interface OnFavoriteClickListener {

        fun onFavoriteClick()
    }
}


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

package org.gradle.kotlin.dsl.resolver

import org.gradle.api.artifacts.transform.ArtifactTransform

import org.gradle.kotlin.dsl.support.unzipTo

import java.io.File

/**
 * This dependency transform is responsible for extracting the sources from
 * a downloaded ZIP of the Gradle sources, and will return the list of main sources
 * subdirectories for all subprojects.
 */
class ExtractGradleSourcesTransform : ArtifactTransform() {

    override
    fun transform(input: File): List<File> {
        unzipTo(input, outputDirectory)
        return sourceDirectories()
    }

    private
    fun sourceDirectories() = outputDirectory.walk().filter(this::isSourceDirectory).toList()

    private
    fun isSourceDirectory(file: File) =
        file.isDirectory && file.parentFile.name == "main" && file.parentFile.parentFile.name == "src"

}

Fix code style: `override` on same line


package engineer.carrot.warren.thump.config

import net.minecraftforge.common.config.Configuration

class GeneralConfiguration(configuration: Configuration) {
    var obfuscateUserSourceFromMinecraft = true

    init {
        this.obfuscateUserSourceFromMinecraft = configuration.getBoolean(OBFUSCATE_USER_SOURCE_FROM_MINECRAFT, CATEGORY, this.obfuscateUserSourceFromMinecraft, OBFUSCATE_USER_SOURCE_FROM_MINECRAFT_COMMENT)
    }

    companion object {
        private val CATEGORY = "general"
        private val OBFUSCATE_USER_SOURCE_FROM_MINECRAFT = "ObfuscateUserSourceFromMinecraft"
        private val OBFUSCATE_USER_SOURCE_FROM_MINECRAFT_COMMENT = "Inserts a zero-width character in to source usernames going from Minecraft to IRC - commonly used to prevent unnecessary pings."
    }
}

Remove specific reference to IRC from general config

package engineer.carrot.warren.thump.config

import net.minecraftforge.common.config.Configuration

class GeneralConfiguration(configuration: Configuration) {
    var obfuscateUserSourceFromMinecraft = true

    init {
        this.obfuscateUserSourceFromMinecraft = configuration.getBoolean(OBFUSCATE_USER_SOURCE_FROM_MINECRAFT, CATEGORY, this.obfuscateUserSourceFromMinecraft, OBFUSCATE_USER_SOURCE_FROM_MINECRAFT_COMMENT)
    }

    companion object {
        private val CATEGORY = "general"
        private val OBFUSCATE_USER_SOURCE_FROM_MINECRAFT = "ObfuscateUserSourceFromMinecraft"
        private val OBFUSCATE_USER_SOURCE_FROM_MINECRAFT_COMMENT = "Inserts a zero-width character in to source usernames going from Minecraft to other services - commonly used to prevent unnecessary pings."
    }
}


package io.sweers.rxpalette

import android.graphics.Bitmap
import android.support.v7.graphics.Palette
import rx.Observable

/**
 * Generate the `Palette` synchronously.
 */
public inline fun Palette.generate(bitmap: Bitmap): Observable<Palette> = RxPalette.generate(bitmap)

/**
 * Generate the `Palette` synchronously.
 */
public inline fun Palette.Builder.generate(): Observable<Palette> = RxPalette.generate(this)

/**
 * Generate the `Palette` asynchronously.
 */
public inline fun Palette.generateAsync(bitmap: Bitmap): Observable<Palette> = RxPalette.generateAsync(bitmap)

/**
 * Generate the `Palette` asynchronously.
 */
public inline fun Palette.Builder.generateAsync(): Observable<Palette> = RxPalette.generateAsync(this)

Change Kotlin API to use asObservable

package io.sweers.rxpalette

import android.graphics.Bitmap
import android.support.v7.graphics.Palette
import rx.Observable

/**
 * Generate the `Palette` synchronously.
 */
public inline fun Palette.asObservable(bitmap: Bitmap): Observable<Palette> = RxPalette.generate(bitmap)

/**
 * Generate the `Palette` synchronously.
 */
public inline fun Palette.Builder.asObservable(): Observable<Palette> = RxPalette.generate(this)

/**
 * Generate the `Palette` asynchronously.
 */
public inline fun Palette.generateAsync(bitmap: Bitmap): Observable<Palette> = RxPalette.generateAsync(bitmap)

/**
 * Generate the `Palette` asynchronously.
 */
public inline fun Palette.Builder.generateAsync(): Observable<Palette> = RxPalette.generateAsync(this)


package fr.o80.featurereminder

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import androidx.core.content.systemService
import java.util.Calendar
import android.content.Intent
import fr.o80.sample.lib.core.Const
import timber.log.Timber
import java.util.Date

/**
 * @author Olivier Perez
 */
object ScheduleRemind {

    fun scheduleReminder(context: Context) {
        val nextTrigger = Calendar.getInstance().apply {
            set(Calendar.HOUR, 18)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }

        if (nextTrigger.before(Date())) {
            nextTrigger.add(Calendar.DAY_OF_MONTH, 1)
        }

        val intent = Intent(context, RemiderReceiver::class.java)
        val alarmIntent = PendingIntent.getBroadcast(context, Const.REQUEST_CODE_REMINDER_ALARM, intent, PendingIntent.FLAG_UPDATE_CURRENT)

        context.systemService<AlarmManager>()
                .setRepeating(AlarmManager.RTC, nextTrigger.timeInMillis, AlarmManager.INTERVAL_DAY, alarmIntent)

        Timber.i("Reminder scheduled")
    }

}

Fix set hour of reminder alarm

package fr.o80.featurereminder

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import androidx.core.content.systemService
import java.util.Calendar
import android.content.Intent
import fr.o80.sample.lib.core.Const
import timber.log.Timber
import java.util.Date

/**
 * @author Olivier Perez
 */
object ScheduleRemind {

    fun scheduleReminder(context: Context) {
        val nextTrigger = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, 18)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }

        if (nextTrigger.before(Calendar.getInstance())) {
            nextTrigger.add(Calendar.DAY_OF_MONTH, 1)
        }

        val intent = Intent(context, RemiderReceiver::class.java)
        val alarmIntent = PendingIntent.getBroadcast(context, Const.REQUEST_CODE_REMINDER_ALARM, intent, PendingIntent.FLAG_UPDATE_CURRENT)

        context.systemService<AlarmManager>()
                .setRepeating(AlarmManager.RTC, nextTrigger.timeInMillis, AlarmManager.INTERVAL_DAY, alarmIntent)

        Timber.i("Reminder scheduled, next execution is %s", nextTrigger)
    }

}


package me.echeung.moemoekyun.client.api.library

class Jpop private constructor() : Library(
        NAME,
        "wss://listen.moe/gateway",
        "https://listen.moe/fallback") {
    companion object {
        const val NAME = "jpop"

        val INSTANCE: Library = Jpop()
    }
}

Switch to beta socket for jpop

package me.echeung.moemoekyun.client.api.library

class Jpop private constructor() : Library(
        NAME,
        "wss://listen.moe/beta_gateway",
        "https://listen.moe/fallback") {
    companion object {
        const val NAME = "jpop"

        val INSTANCE: Library = Jpop()
    }
}


Create a local storage implementation based on SharedPreferences

package com.felipecosta.kotlinrxjavasample.data

import android.content.SharedPreferences

class SharedPreferencesStorage(private val key: String,
                               private val sharedPreferences: SharedPreferences) : LocalStorage {

    override var storageValue: String
        get() = sharedPreferences.getString(key, "")
        set(value) = sharedPreferences.edit().putString(key, value).apply()

}