package com.github.ajalt.clikt.samples.cp

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.output.TermUi
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.multiple
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import java.io.File

class Cp : CliktCommand(help = "Copy SOURCE to DEST, or multiple SOURCE(s) to directory DEST.") {
    private val interactive by option("-i", "--interactive", help = "prompt before overwrite").flag()
    private val recursive by option("-r", "--recursive", help = "copy directories recursively").flag()
    private val source by argument().multiple()
    private val dest by argument()

    override fun run() {
        val destFile = File(dest)
        for (fname in source) {
            val sourceFile = File(fname)
            try {
                if (recursive) sourceFile.copyRecursively(destFile)
                else sourceFile.copyTo(destFile)
            } catch (e: FileAlreadyExistsException) {
                if (interactive) {
                    val response = TermUi.confirm("overwrite '$dest'?", default = true)
                    if (response == false) continue
                }
                if (recursive) sourceFile.copyRecursively(destFile, overwrite = true)
                else sourceFile.copyTo(destFile, overwrite = true)
            }
        }
    }
}

fun main(args: Array<String>) = Cp().main(args)

Use file parameters in cp example

package com.github.ajalt.clikt.samples.cp

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.output.TermUi
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.multiple
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.file
import java.io.File

class Cp : CliktCommand(help = "Copy SOURCE to DEST, or multiple SOURCE(s) to directory DEST.") {
    val interactive by option("-i", "--interactive", help = "prompt before overwrite").flag()
    val recursive by option("-r", "--recursive", help = "copy directories recursively").flag()
    val source by argument().file(exists = true).multiple()
    val dest by argument().file(fileOkay = false)

    override fun run() {
        for (file in source) {
            try {
                if (recursive) file.copyRecursively(dest)
                else file.copyTo(dest)
            } catch (e: FileAlreadyExistsException) {
                if (interactive) {
                    val response = TermUi.confirm("overwrite '$dest'?", default = true)
                    if (response == false) continue
                }
                if (recursive) file.copyRecursively(dest, overwrite = true)
                else file.copyTo(dest, overwrite = true)
            }
        }
    }
}

fun main(args: Array<String>) = Cp().main(args)


package org.gradle.kotlin.dsl.accessors

import org.gradle.kotlin.dsl.fixtures.AbstractIntegrationTest

import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test

class GenerateProjectSchemaTest : AbstractIntegrationTest() {

    @Test
    fun `writes multi-project schema to gradle slash project dash schema dot json`() {

        withBuildScript("""
            plugins { java }
        """)

        build("kotlinDslAccessorsSnapshot")

        val generatedSchema =
            loadMultiProjectSchemaFrom(
                existing("gradle/project-schema.json"))

        val expectedSchema =
            mapOf(
                ":" to ProjectSchema(
                        extensions = mapOf(
                            "defaultArtifacts" to "org.gradle.api.internal.plugins.DefaultArtifactPublicationSet",
                            "ext" to "org.gradle.api.plugins.ExtraPropertiesExtension",
                            "reporting" to "org.gradle.api.reporting.ReportingExtension"),
                        conventions = mapOf(
                            "base" to "org.gradle.api.plugins.BasePluginConvention",
                            "java" to "org.gradle.api.plugins.JavaPluginConvention"),
                        configurations = listOf(
                            "apiElements", "archives", "compile", "compileClasspath", "compileOnly", "default",
                            "implementation", "runtime", "runtimeClasspath", "runtimeElements", "runtimeOnly",
                            "testCompile", "testCompileClasspath", "testCompileOnly", "testImplementation",
                            "testRuntime", "testRuntimeClasspath", "testRuntimeOnly")))

        assertThat(
            generatedSchema,
            equalTo(expectedSchema))
    }
}

Add newly added configurations to test case expectation

package org.gradle.kotlin.dsl.accessors

import org.gradle.kotlin.dsl.fixtures.AbstractIntegrationTest

import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test

class GenerateProjectSchemaTest : AbstractIntegrationTest() {

    @Test
    fun `writes multi-project schema to gradle slash project dash schema dot json`() {

        withBuildScript("""
            plugins { java }
        """)

        build("kotlinDslAccessorsSnapshot")

        val generatedSchema =
            loadMultiProjectSchemaFrom(
                existing("gradle/project-schema.json"))

        val expectedSchema =
            mapOf(
                ":" to ProjectSchema(
                        extensions = mapOf(
                            "defaultArtifacts" to "org.gradle.api.internal.plugins.DefaultArtifactPublicationSet",
                            "ext" to "org.gradle.api.plugins.ExtraPropertiesExtension",
                            "reporting" to "org.gradle.api.reporting.ReportingExtension"),
                        conventions = mapOf(
                            "base" to "org.gradle.api.plugins.BasePluginConvention",
                            "java" to "org.gradle.api.plugins.JavaPluginConvention"),
                        configurations = listOf(
                            "annotationProcessor",
                            "apiElements", "archives", "compile", "compileClasspath", "compileOnly", "default",
                            "implementation", "runtime", "runtimeClasspath", "runtimeElements", "runtimeOnly",
                            "testAnnotationProcessor",
                            "testCompile", "testCompileClasspath", "testCompileOnly", "testImplementation",
                            "testRuntime", "testRuntimeClasspath", "testRuntimeOnly")))

        assertThat(
            generatedSchema,
            equalTo(expectedSchema))
    }
}


package org.rust.lang.structure

import com.intellij.ide.structureView.StructureViewTreeElement
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase
import com.intellij.psi.NavigatablePsiElement
import org.rust.lang.core.psi.RustStructDeclField

class RustStructDeclFieldTreeElement(element: RustStructDeclField) : PsiTreeElementBase<RustStructDeclField>(element) {

    override fun getPresentableText(): String? {
        return element?.identifier?.text
    }

    override fun getChildrenBase(): Collection<StructureViewTreeElement> {
        return arrayListOf<StructureViewTreeElement>()
    }
}

Structure View: Include type info for struct fields

package org.rust.lang.structure

import com.intellij.ide.structureView.StructureViewTreeElement
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase
import com.intellij.psi.NavigatablePsiElement
import org.rust.lang.core.psi.RustStructDeclField

class RustStructDeclFieldTreeElement(element: RustStructDeclField) : PsiTreeElementBase<RustStructDeclField>(element) {

    override fun getPresentableText(): String? {
        return "${element?.identifier?.text}: ${element?.typeSum?.text}"
    }

    override fun getChildrenBase(): Collection<StructureViewTreeElement> {
        return arrayListOf<StructureViewTreeElement>()
    }
}


plugins {
  id("org.metaborg.gradle.config.root-project") version "0.3.21"
  id("org.metaborg.gitonium") version "0.1.3"

  // Set versions for plugins to use, only applying them in subprojects (apply false here).
  id("org.metaborg.spoofax.gradle.langspec") version "0.4.1" apply false
  id("de.set.ecj") version "1.4.1" apply false
}

subprojects {
  metaborg {
    configureSubProject()
  }
}

allprojects {
  // Override version from gitonium, as Spoofax Core uses a different versioning scheme.
  // Needs to be kept in sync with metaborgVersion of Spoofax 3 and theSpoofax 2 Gradle plugin.
  version = "2.5.10"
}

Update Spoofax 2 Gradle plugin to 0.4.2.

plugins {
  id("org.metaborg.gradle.config.root-project") version "0.3.21"
  id("org.metaborg.gitonium") version "0.1.3"

  // Set versions for plugins to use, only applying them in subprojects (apply false here).
  id("org.metaborg.spoofax.gradle.langspec") version "0.4.2" apply false
  id("de.set.ecj") version "1.4.1" apply false
}

subprojects {
  metaborg {
    configureSubProject()
  }
}

allprojects {
  // Override version from gitonium, as Spoofax Core uses a different versioning scheme.
  // Needs to be kept in sync with metaborgVersion of Spoofax 3 and theSpoofax 2 Gradle plugin.
  version = "2.5.10"
}


package com.nicoladefiorenze.room

import android.os.AsyncTask
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.EditText
import com.nicoladefiorenze.room.business.datasource.UserDataSource
import com.nicoladefiorenze.room.database.DatabaseProvider
import com.nicoladefiorenze.room.database.entity.Email
import com.nicoladefiorenze.room.database.entity.User
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers

/**
 * Project: Room<br/>
 * created on: 2017-05-20
 *
 * @author Nicola De Fiorenze
 */
class MainActivity : AppCompatActivity() {

    private val disposables = CompositeDisposable()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val database = DatabaseProvider.getDatabase(applicationContext)

        UserDataSource(database).getAllUsers().subscribeOn(Schedulers.io()).observeOn(
                AndroidSchedulers.mainThread())
                .subscribe(
                        { user -> println(user) },
                        { error -> println(error.message) }
                )

    }

    override fun onDestroy() {
        super.onDestroy()
        disposables.clear()
    }
}

Add the flowable to the composite disposable

package com.nicoladefiorenze.room

import android.os.AsyncTask
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.EditText
import com.nicoladefiorenze.room.business.datasource.UserDataSource
import com.nicoladefiorenze.room.database.DatabaseProvider
import com.nicoladefiorenze.room.database.entity.Email
import com.nicoladefiorenze.room.database.entity.User
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers

/**
 * Project: Room<br/>
 * created on: 2017-05-20
 *
 * @author Nicola De Fiorenze
 */
class MainActivity : AppCompatActivity() {

    private val disposables = CompositeDisposable()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val database = DatabaseProvider.getDatabase(applicationContext)

        disposables.add(UserDataSource(database).getAllUsers().subscribeOn(Schedulers.io()).observeOn(
                AndroidSchedulers.mainThread())
                .subscribe(
                        { user -> println(user) },
                        { error -> println(error.message) }
                )
        )

    }

    override fun onDestroy() {
        super.onDestroy()
        disposables.clear()
    }
}


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

package me.banes.chris.tivi.data.daos

import android.arch.paging.LivePagedListProvider
import android.arch.persistence.room.Insert
import android.arch.persistence.room.OnConflictStrategy
import io.reactivex.Flowable
import me.banes.chris.tivi.data.Entry
import me.banes.chris.tivi.data.entities.ListItem

interface EntryDao<EC : Entry, LI : ListItem<EC>> {
    fun entries(): Flowable<List<LI>>
    fun entriesLiveList(): LivePagedListProvider<Int, LI>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(entry: EC): Long

    fun deleteAll()
}

Use ignore conflict resolution for entries

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

package me.banes.chris.tivi.data.daos

import android.arch.paging.LivePagedListProvider
import android.arch.persistence.room.Insert
import android.arch.persistence.room.OnConflictStrategy
import io.reactivex.Flowable
import me.banes.chris.tivi.data.Entry
import me.banes.chris.tivi.data.entities.ListItem

interface EntryDao<EC : Entry, LI : ListItem<EC>> {
    fun entries(): Flowable<List<LI>>
    fun entriesLiveList(): LivePagedListProvider<Int, LI>

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(entry: EC): Long

    fun deleteAll()
}


/*
 * Copyright 2016 Ralph
 *
 * 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 ms.ralph.quartz.sample

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import ms.ralph.quartz.Quartz

@Quartz
class SubActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sub)
    }
}

Add annotated field into sample

/*
 * Copyright 2016 Ralph
 *
 * 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 ms.ralph.quartz.sample

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import ms.ralph.quartz.Optional
import ms.ralph.quartz.Quartz
import ms.ralph.quartz.Required

@Quartz
class SubActivity : AppCompatActivity() {

    @Required
    var requiredField: String? = null

    @Optional
    var optionalField: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sub)
    }
}


package org.wordpress.aztec.spans

import android.content.Context
import android.text.style.ImageSpan
import android.text.style.ParagraphStyle
import android.view.View
import android.widget.Toast

internal class AztecCommentSpan(html: StringBuilder, context: Context, drawable: Int) : ImageSpan(context, drawable), ParagraphStyle {
    val mHtml: StringBuilder = html

    fun getHtml(): StringBuilder {
        return mHtml
    }

    fun onClick(view: View) {
        Toast.makeText(view.context, mHtml.toString(), Toast.LENGTH_SHORT).show()
    }
}

Add more and page types to custom comment span

package org.wordpress.aztec.spans

import android.content.Context
import android.text.style.ImageSpan
import android.view.View
import android.widget.Toast

internal class AztecCommentSpan(val mComment: AztecCommentSpan.Comment, context: Context, drawable: Int) : ImageSpan(context, drawable) {
    companion object {
        private val HTML_MORE: String = "<!--more-->"
        private val HTML_PAGE: String = "<!--nextpage-->"
    }

    enum class Comment constructor(internal val mHtml: String) {
        MORE(HTML_MORE),
        PAGE(HTML_PAGE)
    }

    fun onClick(view: View) {
        Toast.makeText(view.context, mComment.mHtml.toString(), Toast.LENGTH_SHORT).show()
    }
}


package tornadofx.testapps

import javafx.scene.layout.BorderStrokeStyle
import javafx.scene.shape.StrokeLineCap
import javafx.scene.shape.StrokeLineJoin
import javafx.scene.shape.StrokeType
import tornadofx.*

class BrokenLineApp : App(BrokenLineView::class, BrokenStyles::class)
class BrokenLineView : View("Broken Line Test") {
    override val root = stackpane {
        line {
            addClass(BrokenStyles.blue)
            endXProperty().bind(this@stackpane.widthProperty())
            endYProperty().bind(this@stackpane.heightProperty())
        }
        line {
            addClass(BrokenStyles.blue)
            endXProperty().bind(this@stackpane.widthProperty())
            startYProperty().bind(this@stackpane.heightProperty())
        }
        label("This is a label with a border").addClass(BrokenStyles.red)
    }
}

class BrokenStyles : Stylesheet() {
    companion object {
        val red by cssclass()
        val blue by cssclass()
    }

    init {
        root {
            padding = box(25.px)
            backgroundColor += c("white")
        }
        red {
            val radius = box(50.px)
            backgroundColor += c("white", 0.9)
            backgroundRadius += radius
            borderColor += box(c("red"))
            borderWidth += box(5.px)
            borderRadius += radius
            borderStyle += BorderStrokeStyle(
                StrokeType.CENTERED,
                StrokeLineJoin.MITER,
                StrokeLineCap.SQUARE,
                10.0,
                0.0,
                listOf(5.0, 15.0, 0.0, 15.0)
            )
            padding = box(50.px)
        }
        blue {
            stroke = c("dodgerblue")
            strokeWidth = 5.px
            strokeType = StrokeType.CENTERED
            strokeLineCap = StrokeLineCap.SQUARE
            strokeDashArray = listOf(25.px, 15.px, 0.px, 15.px)
        }
    }
}


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

package com.example.splitties.extensions.coroutines

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

@ExperimentalCoroutinesApi
suspend fun <E> Flow<E>.collectLatest(
    context: CoroutineContext = EmptyCoroutineContext,
    skipEquals: Boolean = false,
    action: suspend CoroutineScope.(E) -> Unit
): Unit = coroutineScope {
    var job: Job? = null
    var previousValue: E? = null // Null is safe as first value because at first, job is null.
    collect { newValue ->
        job?.let { // No skipEquals on first value since there's no job yet.
            if (skipEquals && previousValue == newValue) return@collect else it.cancelAndJoin()
        }
        previousValue = newValue
        job = launch(context) {
            action(newValue)
        }
    }
}

@ExperimentalCoroutinesApi
fun <E> infiniteFlow(generateValue: suspend () -> E): Flow<E> = flow {
    repeatWhileActive {
        emit(generateValue())
    }
}

Add missing import after package move

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

package com.example.splitties.extensions.coroutines

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import splitties.coroutines.repeatWhileActive
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

@ExperimentalCoroutinesApi
suspend fun <E> Flow<E>.collectLatest(
    context: CoroutineContext = EmptyCoroutineContext,
    skipEquals: Boolean = false,
    action: suspend CoroutineScope.(E) -> Unit
): Unit = coroutineScope {
    var job: Job? = null
    var previousValue: E? = null // Null is safe as first value because at first, job is null.
    collect { newValue ->
        job?.let { // No skipEquals on first value since there's no job yet.
            if (skipEquals && previousValue == newValue) return@collect else it.cancelAndJoin()
        }
        previousValue = newValue
        job = launch(context) {
            action(newValue)
        }
    }
}

@ExperimentalCoroutinesApi
fun <E> infiniteFlow(generateValue: suspend () -> E): Flow<E> = flow {
    repeatWhileActive {
        emit(generateValue())
    }
}


package org.purescript

import com.intellij.lang.Language

class PSLanguage : Language("Purescript", "text/purescript", "text/x-purescript", "application/x-purescript") {
    companion object {
        val INSTANCE = PSLanguage()

        /**
         * These modules are built into the purescript compiler,
         * and have no corresponding source files.
         *
         * See [https://pursuit.purescript.org/builtins/docs/Prim] for details.
         */
        val BUILTIN_MODULES = listOf(
            "Prim",
            "Prim.Boolean",
            "Prim.Coerce",
            "Prim.Ordering",
            "Prim.Row",
            "Prim.RowList",
            "Prim.Symbol",
            "Prim.TypeError",
        )

        /**
         * These types are built into the purescript compiles,
         * and are always available.
         *
         * See [https://pursuit.purescript.org/builtins/docs/Prim] for details.
         */
        val BUILTIN_TYPES = listOf(
            "Int",
            "Number",
            "String",
            "Char",
            "Boolean",
            "Array",
            "Type", // TODO Type is really a kind, not a type
        )
    }
}

Change build-in types and modules to be sets instead of lists

package org.purescript

import com.intellij.lang.Language

class PSLanguage : Language("Purescript", "text/purescript", "text/x-purescript", "application/x-purescript") {
    companion object {
        val INSTANCE = PSLanguage()

        /**
         * These modules are built into the purescript compiler,
         * and have no corresponding source files.
         *
         * See [https://pursuit.purescript.org/builtins/docs/Prim] for details.
         */
        val BUILTIN_MODULES = setOf(
            "Prim",
            "Prim.Boolean",
            "Prim.Coerce",
            "Prim.Ordering",
            "Prim.Row",
            "Prim.RowList",
            "Prim.Symbol",
            "Prim.TypeError",
        )

        /**
         * These types are built into the purescript compiles,
         * and are always available.
         *
         * See [https://pursuit.purescript.org/builtins/docs/Prim] for details.
         */
        val BUILTIN_TYPES = setOf(
            "Int",
            "Number",
            "String",
            "Char",
            "Boolean",
            "Array",
            "Type", // TODO Type is really a kind, not a type
        )
    }
}


package com.commit451.gitlab.api

import com.commit451.gitlab.api.converter.DashDateAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Rfc3339DateJsonAdapter
import java.util.*

object MoshiProvider {

    val moshi: Moshi by lazy {
        Moshi.Builder()
                .add(DashDateAdapter())
                .add(Date::class.java, Rfc3339DateJsonAdapter())
                .build()
    }
}

Handle null dates without crashing

package com.commit451.gitlab.api

import com.commit451.gitlab.api.converter.DashDateAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Rfc3339DateJsonAdapter
import java.util.*

object MoshiProvider {

    val moshi: Moshi by lazy {
        Moshi.Builder()
                .add(DashDateAdapter())
                .add(Date::class.java, Rfc3339DateJsonAdapter().nullSafe())
                .build()
    }
}


package com.barista_v.debug_artist.item

import com.barista_v.debug_artist.item.input.InputItemListener
import com.barista_v.debug_artist.item.phoenix.RestartListener
import com.barista_v.debug_artist.item.spinner.SpinnerItemListener
import com.jakewharton.scalpel.ScalpelFrameLayout

interface MenuItem
open class DividerMenuItem : MenuItem

open class SwitchMenuItem(val checked: Boolean = false) : MenuItem
open class ButtonMenuItem : MenuItem
open class LabelMenuItem(val properties: Map<String, String>) : MenuItem

class StethoSwitchMenuItem(checked: Boolean = false) : SwitchMenuItem(checked)
class LeakCanarySwitchMenuItem(checked: Boolean = false) : SwitchMenuItem(checked)
class PicassoLogsSwitchMenuItem(checked: Boolean = false) : SwitchMenuItem(checked)
class ScalpelSwitchMenuItem(val layout: ScalpelFrameLayout,
                            checked: Boolean = false) : SwitchMenuItem(checked)

class LynksButtonMenuItem : ButtonMenuItem()

class PhoenixButtonMenuItem(val restartListener: RestartListener) : ButtonMenuItem()

class SpinnerMenuItem(val id: Int,
                      val name: String,
                      val options: Array<String>,
                      val selectedItem: Int,
                      val listener: SpinnerItemListener) : ButtonMenuItem()

class InputMenuItem(val id: Int,
                    val name: String,
                    val inputItemListener: InputItemListener) : ButtonMenuItem()

Fix items are not final so can't be mocked

package com.barista_v.debug_artist.item

import com.barista_v.debug_artist.item.input.InputItemListener
import com.barista_v.debug_artist.item.phoenix.RestartListener
import com.barista_v.debug_artist.item.spinner.SpinnerItemListener
import com.jakewharton.scalpel.ScalpelFrameLayout

open class MenuItem
open class DividerMenuItem : MenuItem()

open class SwitchMenuItem(val checked: Boolean = false) : MenuItem()
open class ButtonMenuItem : MenuItem()
open class LabelMenuItem(val properties: Map<String, String>) : MenuItem()

class StethoSwitchMenuItem(checked: Boolean = false) : SwitchMenuItem(checked)
class LeakCanarySwitchMenuItem(checked: Boolean = false) : SwitchMenuItem(checked)
class PicassoLogsSwitchMenuItem(checked: Boolean = false) : SwitchMenuItem(checked)
class ScalpelSwitchMenuItem(val layout: ScalpelFrameLayout,
                            checked: Boolean = false) : SwitchMenuItem(checked)

class LynksButtonMenuItem : ButtonMenuItem()

class PhoenixButtonMenuItem(val restartListener: RestartListener) : ButtonMenuItem()

class SpinnerMenuItem(val id: Int,
                      val name: String,
                      val options: Array<String>,
                      val selectedItem: Int,
                      val listener: SpinnerItemListener) : ButtonMenuItem()

class InputMenuItem(val id: Int,
                    val name: String,
                    val inputItemListener: InputItemListener) : ButtonMenuItem()


package eu.kanade.tachiyomi.widget.preference

import android.content.Context
import android.util.AttributeSet
import androidx.preference.ListPreference
import androidx.preference.PreferenceViewHolder
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferenceValues

class ThemesPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    ListPreference(context, attrs),
    ThemesPreferenceAdapter.OnItemClickListener {

    private val adapter = ThemesPreferenceAdapter(this)

    init {
        layoutResource = R.layout.pref_themes_list
    }

    override fun onBindViewHolder(holder: PreferenceViewHolder) {
        super.onBindViewHolder(holder)

        val themesList = holder.findViewById(R.id.themes_list) as RecyclerView
        themesList.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        themesList.adapter = adapter
    }

    override fun onItemClick(position: Int) {
        value = entries[position].name
        callChangeListener(value)
    }

    var entries: List<PreferenceValues.AppTheme> = emptyList()
        set(value) {
            field = value
            adapter.setItems(value)
        }
}

Fix crash when tapping title of "App theme" preference

package eu.kanade.tachiyomi.widget.preference

import android.content.Context
import android.util.AttributeSet
import androidx.preference.ListPreference
import androidx.preference.PreferenceViewHolder
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferenceValues

class ThemesPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    ListPreference(context, attrs),
    ThemesPreferenceAdapter.OnItemClickListener {

    private val adapter = ThemesPreferenceAdapter(this)

    init {
        layoutResource = R.layout.pref_themes_list
    }

    override fun onBindViewHolder(holder: PreferenceViewHolder) {
        super.onBindViewHolder(holder)

        val themesList = holder.findViewById(R.id.themes_list) as RecyclerView
        themesList.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
        themesList.adapter = adapter
    }

    override fun onItemClick(position: Int) {
        value = entries[position].name
        callChangeListener(value)
    }

    override fun onClick() {
        // no-op; not actually a DialogPreference
    }

    var entries: List<PreferenceValues.AppTheme> = emptyList()
        set(value) {
            field = value
            adapter.setItems(value)
        }
}


package me.mrkirby153.KirBot.command.executors.admin

import me.mrkirby153.KirBot.Bot
import me.mrkirby153.KirBot.command.BaseCommand
import me.mrkirby153.KirBot.command.Command
import me.mrkirby153.KirBot.command.CommandCategory
import me.mrkirby153.KirBot.command.CommandExecutor
import me.mrkirby153.KirBot.command.args.CommandContext
import me.mrkirby153.KirBot.utils.Context
import net.dv8tion.jda.core.entities.User

@Command(name = "su", arguments = ["<user:user>", "<command:string...>"])
class CommandSu : BaseCommand(CommandCategory.ADMIN) {

    override fun execute(context: Context, cmdContext: CommandContext) {
        val user = cmdContext.get<User>("user")
        val command = cmdContext.get<String>("command")

        val c = Context(context.shard, context)
        c.customAuthor = user
        c.customMessage = command
        Bot.LOG.warn(
                "Executing command \"$command\" as ${c.author} - Requested by ${context.author}")
        CommandExecutor.execute(c)
    }
}

Fix incorrect permissions on su command

package me.mrkirby153.KirBot.command.executors.admin

import me.mrkirby153.KirBot.Bot
import me.mrkirby153.KirBot.command.BaseCommand
import me.mrkirby153.KirBot.command.Command
import me.mrkirby153.KirBot.command.CommandCategory
import me.mrkirby153.KirBot.command.CommandExecutor
import me.mrkirby153.KirBot.command.args.CommandContext
import me.mrkirby153.KirBot.user.CLEARANCE_GLOBAL_ADMIN
import me.mrkirby153.KirBot.utils.Context
import net.dv8tion.jda.core.entities.User

@Command(name = "su", arguments = ["<user:user>", "<command:string...>"], clearance = CLEARANCE_GLOBAL_ADMIN)
class CommandSu : BaseCommand(CommandCategory.ADMIN) {

    override fun execute(context: Context, cmdContext: CommandContext) {
        val user = cmdContext.get<User>("user")
        val command = cmdContext.get<String>("command")

        val c = Context(context.shard, context)
        c.customAuthor = user
        c.customMessage = command
        Bot.LOG.warn(
                "Executing command \"$command\" as ${c.author} - Requested by ${context.author}")
        CommandExecutor.execute(c)
    }
}


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

object AndroidComponents {
    const val VERSION = "95.0.20211101155331"
}

Update to first Android Components 96.0 Nightly build

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

object AndroidComponents {
    const val VERSION = "96.0.20211102173221"
}


package com.masahirosaito.spigot.homes.tests

enum class Permission(val permission: String) {

    HOME("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"),

    HOME_PRIVATE("homes.command.private"),
    HOME_PRIVATE_NAME("homes.command.private.name"),

    HOME_HELP("homes.command.help"),
    HOME_HELP_COMMAND("homes.command.help.command")
}

Add two permission for list command testing

package com.masahirosaito.spigot.homes.tests

enum class Permission(val permission: String) {

    HOME("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"),

    HOME_PRIVATE("homes.command.private"),
    HOME_PRIVATE_NAME("homes.command.private.name"),

    HOME_HELP("homes.command.help"),
    HOME_HELP_COMMAND("homes.command.help.command"),

    HOME_LIST("homes.command.list"),
    HOME_LIST_PLAYER("homes.command.list.player")
}


package org.purescript.keyword

import com.intellij.testFramework.fixtures.BasePlatformTestCase

class KeywordCompletionContributorTest : BasePlatformTestCase() {
    fun `test do`() {
        val src = """
                    module Main where
                    dof = 1
                    main = d{-caret-}
                    """.trimIndent()
        val replace = src.replace("{-caret-}", "<caret>")
        myFixture.configureByText("Main.purs", replace)
        myFixture.testCompletionVariants("Main.purs", "do", "dof")
    }

}


val kotlinVersion by extra("1.3.72")
val gradlePluginVersion by extra("4.0.0")

val compileSdk by extra(29)
val buildTools by extra("29.0.3")
val minSdk by extra(21)
val targetSdk by extra(29)

Reduce the min supported sdk to 18

val kotlinVersion by extra("1.3.72")
val gradlePluginVersion by extra("4.0.0")

val compileSdk by extra(29)
val buildTools by extra("29.0.3")
val minSdk by extra(18)
val targetSdk by extra(29)


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

package org.mozilla.focus.whatsnew

import android.content.Context
import mozilla.components.support.ktx.android.content.appVersionName

/**
* Convenience class to deal with the application version number
* I opted to keep it contained to the whatsnew package. We may
* want to pull it
*/
open class WhatsNewVersion(internal open val version: String) {

    override fun hashCode(): Int {
        return version.hashCode()
    }

    override fun equals(other: Any?): Boolean {
        if (other is WhatsNewVersion) {
            return version == other.version
        }

        return false
    }

    val majorVersionNumber: Int
        get() = version.split(".").first().toInt()
}

data class ContextWhatsNewVersion(private val context: Context) : WhatsNewVersion("") {
    override val version: String
        get() = context.appVersionName ?: ""
}

Remove useless null elvis operator check.

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

package org.mozilla.focus.whatsnew

import android.content.Context
import mozilla.components.support.ktx.android.content.appVersionName

/**
* Convenience class to deal with the application version number
* I opted to keep it contained to the whatsnew package. We may
* want to pull it
*/
open class WhatsNewVersion(internal open val version: String) {

    override fun hashCode(): Int {
        return version.hashCode()
    }

    override fun equals(other: Any?): Boolean {
        if (other is WhatsNewVersion) {
            return version == other.version
        }

        return false
    }

    val majorVersionNumber: Int
        get() = version.split(".").first().toInt()
}

data class ContextWhatsNewVersion(private val context: Context) : WhatsNewVersion("") {
    override val version: String
        get() = context.appVersionName
}


package mil.nga.giat.mage.form

import androidx.compose.runtime.mutableStateOf
import mil.nga.giat.mage.form.field.FieldState
import mil.nga.giat.mage.form.field.FieldValue

class FormState(
  val id: Long? = null,
  val remoteId: String? = null,
  val eventId: String,
  val definition: Form,
  val fields: List<FieldState<*, *>>,
  expanded: Boolean = false,
) {
  val expanded = mutableStateOf(expanded)

  fun isValid(): Boolean {
    var valid = true
    for (fieldState in fields) {
      if (!fieldState.isValid) {
        fieldState.isFocusedDirty = true
        fieldState.enableShowErrors()
        valid = false
      }
    }

    return valid
  }

  companion object {
    fun fromForm(id: Long? = null, remoteId: String? = null, eventId: String, form: Form, defaultForm: Form? = null): FormState {
      val defaultFields = defaultForm?.fields?.associateTo(mutableMapOf()) {
        it.name to it.value
      }

      val fields = mutableListOf<FieldState<*, out FieldValue>>()
      for (field in form.fields) {
        val fieldState = FieldState.fromFormField(field, field.value, defaultFields?.get(field.name))
        fields.add(fieldState)
      }

      return FormState(id, remoteId, eventId, form, fields)
    }
  }
}

Fix observation create mapview update

package mil.nga.giat.mage.form

import androidx.compose.runtime.mutableStateOf
import mil.nga.giat.mage.form.field.FieldState
import mil.nga.giat.mage.form.field.FieldValue

class FormState(
  val id: Long? = null,
  val remoteId: String? = null,
  val eventId: String,
  val definition: Form,
  val fields: List<FieldState<*, *>>,
  expanded: Boolean = false,
) {
  val expanded = mutableStateOf(expanded)

  fun isValid(): Boolean {
    var valid = true
    for (fieldState in fields) {
      if (!fieldState.isValid) {
        fieldState.isFocusedDirty = true
        fieldState.enableShowErrors()
        valid = false
      }
    }

    return valid
  }

  companion object {
    fun fromForm(remoteId: String? = null, eventId: String, form: Form, defaultForm: Form? = null): FormState {
      val defaultFields = defaultForm?.fields?.associateTo(mutableMapOf()) {
        it.name to it.value
      }

      val fields = mutableListOf<FieldState<*, out FieldValue>>()
      for (field in form.fields) {
        val fieldState = FieldState.fromFormField(field, field.value, defaultFields?.get(field.name))
        fields.add(fieldState)
      }

      return FormState(form.id, remoteId, eventId, form, fields)
    }
  }
}


package org.jetbrains.ktor.http

import org.jetbrains.ktor.application.*
import java.util.*
import java.util.concurrent.*

public open class RequestCookies(private val request: ApplicationRequest) {
    private val map = ConcurrentHashMap<Pair<CookieEncoding, String>, String>()

    // TODO: Remove in favor of default parameter value when KT-9140 is fixed
    public operator fun get(name: String): String? = get(name, CookieEncoding.URI_ENCODING)

    public operator fun get(name: String, encoding: CookieEncoding): String? {
        val rawValue = parsedRawCookies[name] ?: return null
        return map.computeIfAbsent(encoding to name) { decodeCookieValue(rawValue, encoding) }
    }

    public open val parsedRawCookies: Map<String, String> by lazy {
        request.headers.getAll("Cookie")?.fold(HashMap<String, String>()) { acc, e -> acc.putAll(parseClientCookiesHeader(e)); acc }
                ?: emptyMap<String, String>()
    }
}

Remove workaround for Kotlin bug KT-9140

package org.jetbrains.ktor.http

import org.jetbrains.ktor.application.*
import java.util.*
import java.util.concurrent.*

public open class RequestCookies(private val request: ApplicationRequest) {
    private val map = ConcurrentHashMap<Pair<CookieEncoding, String>, String>()

    public operator fun get(name: String, encoding: CookieEncoding = CookieEncoding.URI_ENCODING): String? {
        val rawValue = parsedRawCookies[name] ?: return null
        return map.computeIfAbsent(encoding to name) { decodeCookieValue(rawValue, encoding) }
    }

    public open val parsedRawCookies: Map<String, String> by lazy {
        request.headers.getAll("Cookie")?.fold(HashMap<String, String>()) { acc, e -> acc.putAll(parseClientCookiesHeader(e)); acc }
                ?: emptyMap<String, String>()
    }
}


package com.lloydramey.cfn.model

import com.fasterxml.jackson.annotation.JsonIgnore
import com.lloydramey.cfn.model.functions.AwsTemplateValue

data class Export(val name: AwsTemplateValue)

class Output(@JsonIgnore val name: String, val value: AwsTemplateValue, val description: String? = null, val export: Export? = null)

Allow specifying a string name without val

package com.lloydramey.cfn.model

import com.fasterxml.jackson.annotation.JsonIgnore
import com.lloydramey.cfn.model.functions.AwsTemplateValue
import com.lloydramey.cfn.model.functions.Val

data class Export(val name: AwsTemplateValue) {
    constructor(name: String) : this(Val(name))
}

class Output(@JsonIgnore val name: String, val value: AwsTemplateValue, val description: String? = null, val export: Export? = null)


package com.github.ramonrabello.kiphy.data

import com.github.ramonrabello.kiphy.BuildConfig
import com.github.ramonrabello.kiphy.trends.TrendingEndpoint
import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

/**
 * Class that will handle access to Giphy API endpoints
 * in a fluent way.
 */
object GiphyApi {

    private var retrofit: Retrofit
    private const val BASE_URL = "http://api.giphy.com"

    init {
        val okHttpClient = OkHttpClient.Builder()
        okHttpClient.addInterceptor {
            chain ->
            val original = chain.request()
            val requestBuilder = original.newBuilder()
            requestBuilder.addHeader("api_key", BuildConfig.GIPHY_API_KEY)
            val request = requestBuilder.build()
            chain.proceed(request)
        }

        if (BuildConfig.DEBUG){
            val loggingInterceptor = HttpLoggingInterceptor()
            loggingInterceptor.level = HttpLoggingInterceptor.Level.HEADERS
            okHttpClient.addInterceptor(loggingInterceptor)
        }

        retrofit = Retrofit.Builder().baseUrl(BASE_URL)
                .client(okHttpClient.build())
                .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
                .build()
    }

    fun trending(): TrendingEndpoint = retrofit.create(TrendingEndpoint::class.java)
}

Add const val for api key header.

package com.github.ramonrabello.kiphy.data

import com.github.ramonrabello.kiphy.BuildConfig
import com.github.ramonrabello.kiphy.trends.TrendingEndpoint
import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

/**
 * Class that will handle access to Giphy API endpoints
 * in a fluent way.
 */
object GiphyApi {
    private const val API_KEY_PARAM = "api_key"
    private var retrofit: Retrofit
    private const val BASE_URL = "http://api.giphy.com"

    init {
        val okHttpClient = OkHttpClient.Builder()
        okHttpClient.addInterceptor {
            chain ->
            val original = chain.request()
            val requestBuilder = original.newBuilder()
            requestBuilder.addHeader(API_KEY_PARAM, BuildConfig.GIPHY_API_KEY)
            val request = requestBuilder.build()
            chain.proceed(request)
        }

        if (BuildConfig.DEBUG){
            val loggingInterceptor = HttpLoggingInterceptor()
            loggingInterceptor.level = HttpLoggingInterceptor.Level.HEADERS
            okHttpClient.addInterceptor(loggingInterceptor)
        }

        retrofit = Retrofit.Builder().baseUrl(BASE_URL)
                .client(okHttpClient.build())
                .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
                .build()
    }

    fun trending(): TrendingEndpoint = retrofit.create(TrendingEndpoint::class.java)
}


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

import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.psi.PsiElement
import com.jetbrains.rider.actions.RiderActionCallStrategy
import com.jetbrains.rider.actions.RiderActionSupportPolicy
import com.jetbrains.rider.actions.RiderActions

class AsmDefActionCallPolicy : RiderActionSupportPolicy() {
    override fun getCallStrategy(psiElement: PsiElement, backendActionId: String): RiderActionCallStrategy {
        if (backendActionId == IdeActions.ACTION_RENAME)
            return RiderActionCallStrategy.FRONTEND_FIRST
        if (RiderActions.GOTO_DECLARATION == backendActionId || IdeActions.ACTION_FIND_USAGES == backendActionId
            || backendActionId == "CtrlClick")
            return RiderActionCallStrategy.BACKEND_FIRST

        return RiderActionCallStrategy.FRONTEND_ONLY
    }

    override fun isAvailable(psiElement: PsiElement, backendActionId: String): Boolean {
        val viewProvider = psiElement.containingFile?.viewProvider ?: return false
        return viewProvider.fileType == AsmDefFileType
    }
}

Use defined constant for CtrlClick

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

import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.psi.PsiElement
import com.jetbrains.rider.actions.RiderActionCallStrategy
import com.jetbrains.rider.actions.RiderActionSupportPolicy
import com.jetbrains.rider.actions.RiderActions
import com.jetbrains.rider.hyperlinks.RiderCtrlClickHost

class AsmDefActionCallPolicy : RiderActionSupportPolicy() {
    override fun getCallStrategy(psiElement: PsiElement, backendActionId: String): RiderActionCallStrategy {
        if (backendActionId == IdeActions.ACTION_RENAME)
            return RiderActionCallStrategy.FRONTEND_FIRST
        if (RiderActions.GOTO_DECLARATION == backendActionId || IdeActions.ACTION_FIND_USAGES == backendActionId
            || RiderCtrlClickHost.resharperActionId == backendActionId)
            return RiderActionCallStrategy.BACKEND_FIRST

        return RiderActionCallStrategy.FRONTEND_ONLY
    }

    override fun isAvailable(psiElement: PsiElement, backendActionId: String): Boolean {
        val viewProvider = psiElement.containingFile?.viewProvider ?: return false
        return viewProvider.fileType == AsmDefFileType
    }
}


plugins {
  id("org.metaborg.gradle.config.root-project") version "0.3.8"
  id("org.metaborg.gitonium") version "0.1.2"
}

subprojects {
  metaborg {
    configureSubProject()
  }
}

allprojects {
  version = "2.6.0-SNAPSHOT" // Override version from Git, as Spoofax Core uses a different versioning scheme.

  repositories {
    maven("https://pluto-build.github.io/mvnrepository/")
    maven("https://sugar-lang.github.io/mvnrepository/")
    maven("http://nexus.usethesource.io/content/repositories/public/")
  }
}

Change UseTheSource.io to use HTTPS

plugins {
  id("org.metaborg.gradle.config.root-project") version "0.3.8"
  id("org.metaborg.gitonium") version "0.1.2"
}

subprojects {
  metaborg {
    configureSubProject()
  }
}

allprojects {
  version = "2.6.0-SNAPSHOT" // Override version from Git, as Spoofax Core uses a different versioning scheme.

  repositories {
    maven("https://pluto-build.github.io/mvnrepository/")
    maven("https://sugar-lang.github.io/mvnrepository/")
    maven("https://nexus.usethesource.io/content/repositories/public/")
  }
}


Add test for non-matching environment inspection

package nl.hannahsten.texifyidea.inspections.latex

import nl.hannahsten.texifyidea.inspections.TexifyInspectionTestBase

class LatexNonMatchingEnvironmentInspectionTest : TexifyInspectionTestBase(LatexNonMatchingEnvironmentInspection()) {
    fun `test no warning`() = testHighlighting("""
        \begin{center}
            bla
        \end{center}
    """.trimIndent())

    fun `test warnings`() = testHighlighting("""
        <error descr="DefaultEnvironment name does not match with the name in \end.">\begin{center}</error>
            bla
        <error descr="DefaultEnvironment name does not match with the name in \begin.">\end{left}</error>
    """.trimIndent())

    fun `test begin quick fix`() = testNamedQuickFix("""
        \begin{center}
            bla
        \end{left}
    """.trimIndent(), """
        \begin{left}
            bla
        \end{left}
    """.trimIndent(),
    quickFixName = "Change \\begin environment to 'left'",
    numberOfFixes = 2)

    fun `test end quick fix`() = testNamedQuickFix("""
        \begin{center}
            bla
        \end{left}
    """.trimIndent(), """
        \begin{center}
            bla
        \end{center}
    """.trimIndent(),
    quickFixName = "Change \\end environment to 'center'",
    numberOfFixes = 2)
}


package org.fedorahosted.freeotp.ui

import android.os.Handler
import android.os.Looper
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.launch
import org.fedorahosted.freeotp.data.OtpTokenDatabase

class TokenTouchCallback(private val lifecycleOwner: LifecycleOwner,
                         private val adapter: TokenListAdapter,
                         private val optTokenDatabase: OtpTokenDatabase)
    : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN , 0) {

    var moveRunnable: Runnable? = null

    private val handler = Handler(Looper.getMainLooper())

    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
        moveRunnable?.let {
            handler.removeCallbacks(it)
        }

        moveRunnable = Runnable {
            lifecycleOwner.lifecycleScope.launch {
                val sourceToken = adapter.currentList[viewHolder.adapterPosition] ?: return@launch
                val targetToken = adapter.currentList[target.adapterPosition] ?: return@launch
                optTokenDatabase.otpTokenDao().move(sourceToken.id, targetToken.id)
            }
        }

        moveRunnable?.let {
            handler.postDelayed(it, 150)
        }

        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
    }
}

Allow token to be moved left and right in landscape mode

package org.fedorahosted.freeotp.ui

import android.os.Handler
import android.os.Looper
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.launch
import org.fedorahosted.freeotp.data.OtpTokenDatabase

class TokenTouchCallback(private val lifecycleOwner: LifecycleOwner,
                         private val adapter: TokenListAdapter,
                         private val optTokenDatabase: OtpTokenDatabase)
    : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP
        or ItemTouchHelper.DOWN
        or ItemTouchHelper.LEFT
        or ItemTouchHelper.RIGHT, 0) {

    private var moveRunnable: Runnable? = null

    private val handler = Handler(Looper.getMainLooper())

    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
        moveRunnable?.let {
            handler.removeCallbacks(it)
        }

        moveRunnable = Runnable {
            lifecycleOwner.lifecycleScope.launch {
                val sourceToken = adapter.currentList[viewHolder.adapterPosition] ?: return@launch
                val targetToken = adapter.currentList[target.adapterPosition] ?: return@launch
                optTokenDatabase.otpTokenDao().move(sourceToken.id, targetToken.id)
            }
        }

        moveRunnable?.let {
            handler.postDelayed(it, 150)
        }

        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
    }
}


package org.stepic.droid.configuration

object RemoteConfig {
    const val PREFIX = "remote_config_"

    const val MIN_DELAY_RATE_DIALOG_SEC = "min_delay_rate_dialog_sec"
    const val SHOW_STREAK_DIALOG_AFTER_LOGIN = "show_streak_dialog_after_login"
    const val SHOW_NOTIFICATIONS_BADGES = "show_notifications_badges"
    const val ADAPTIVE_COURSES = "adaptive_courses_android"
    const val ADAPTIVE_BACKEND_URL = "adaptive_backend_url"
    const val IS_LOCAL_SUBMISSIONS_ENABLED = "is_local_submissions_enabled"
    const val IS_PEER_REVIEW_ENABLED = "is_peer_review_enabled"
    const val IS_DISABLED_STEPS_SUPPORTED = "is_disabled_steps_supported"
    const val SEARCH_QUERY_PARAMS_ANDROID = "search_query_params_android"
}

Add feature flag to remote config

package org.stepic.droid.configuration

object RemoteConfig {
    const val PREFIX = "remote_config_"

    const val MIN_DELAY_RATE_DIALOG_SEC = "min_delay_rate_dialog_sec"
    const val SHOW_STREAK_DIALOG_AFTER_LOGIN = "show_streak_dialog_after_login"
    const val SHOW_NOTIFICATIONS_BADGES = "show_notifications_badges"
    const val ADAPTIVE_COURSES = "adaptive_courses_android"
    const val ADAPTIVE_BACKEND_URL = "adaptive_backend_url"
    const val IS_LOCAL_SUBMISSIONS_ENABLED = "is_local_submissions_enabled"
    const val IS_PEER_REVIEW_ENABLED = "is_peer_review_enabled"
    const val IS_DISABLED_STEPS_SUPPORTED = "is_disabled_steps_supported"
    const val SEARCH_QUERY_PARAMS_ANDROID = "search_query_params_android"
    const val IS_NEW_HOME_SCREEN_ENABLED = "is_new_home_screen_enabled"
}


Introduce a file registry that is aware of all class files passed to the processor

/*
 * Copyright 2015 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.files

import io.michaelrocks.lightsaber.processor.commons.closeQuitely
import io.michaelrocks.lightsaber.processor.io.FileSource
import io.michaelrocks.lightsaber.processor.io.fileSource
import org.objectweb.asm.Type
import java.io.Closeable
import java.io.File
import java.util.*

interface FileRegistry : Closeable {
  fun add(files: Iterable<File>)
  fun add(file: File)
  fun readClass(type: Type): ByteArray
}

class FileRegistryImpl : FileRegistry {
  private val sources = HashMap<File, FileSource>()
  private val filesByTypes = HashMap<Type, File>()

  override fun add(files: Iterable<File>) {
    require(files.all { it !in sources }) { "Some files already added to registry" }
    files.forEach { add(it) }
  }

  override fun add(file: File) {
    require(file !in sources) { "File $file already added to registry" }
    val fileSource = file.fileSource()
    sources.put(file, fileSource)
    fileSource.listFiles { path, type ->
      if (type == FileSource.EntryType.CLASS) {
        filesByTypes.put(Type.getObjectType(path.substringBeforeLast(".class")), file)
      }
    }
  }

  override fun readClass(type: Type): ByteArray {
    val file = filesByTypes[type]!!
    val fileSource = sources[file]!!
    return fileSource.readFile("${type.internalName}.class")
  }

  override fun close() {
    sources.values.forEach { it.closeQuitely() }
    sources.clear()
    filesByTypes.clear()
  }
}


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

package com.pyamsoft.pydroid.ui.rating.dialog

import android.os.Bundle
import androidx.lifecycle.LifecycleOwner
import com.pyamsoft.pydroid.ui.arch.UiComponent
import com.pyamsoft.pydroid.ui.arch.ViewEvent.EMPTY
import io.reactivex.Observable

internal class RatingChangelogUiComponent internal constructor(
  private val changelogView: RatingChangelogView,
  owner: LifecycleOwner
) : UiComponent<EMPTY>(owner) {

  override fun id(): Int {
    return changelogView.id()
  }

  override fun create(savedInstanceState: Bundle?) {
    changelogView.inflate(savedInstanceState)
    owner.run { changelogView.teardown() }
  }

  override fun saveState(outState: Bundle) {
    changelogView.saveState(outState)
  }

  override fun onUiEvent(): Observable<EMPTY> {
    return Observable.empty()
  }

}

Fix changelog not displaying bug

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

package com.pyamsoft.pydroid.ui.rating.dialog

import android.os.Bundle
import androidx.lifecycle.LifecycleOwner
import com.pyamsoft.pydroid.ui.arch.UiComponent
import com.pyamsoft.pydroid.ui.arch.ViewEvent.EMPTY
import io.reactivex.Observable

internal class RatingChangelogUiComponent internal constructor(
  private val changelogView: RatingChangelogView,
  owner: LifecycleOwner
) : UiComponent<EMPTY>(owner) {

  override fun id(): Int {
    return changelogView.id()
  }

  override fun create(savedInstanceState: Bundle?) {
    changelogView.inflate(savedInstanceState)
    owner.runOnDestroy { changelogView.teardown() }
  }

  override fun saveState(outState: Bundle) {
    changelogView.saveState(outState)
  }

  override fun onUiEvent(): Observable<EMPTY> {
    return Observable.empty()
  }

}


package org.purescript.parser

import com.intellij.psi.tree.IElementType

abstract class Parsec {
    var name: String? = null
        get() {
            if (field == null) {
                field = calcName()
            }
            return field
        }
        private set
    var expectedName: HashSet<String?>? = null
        get() {
            if (field == null) {
                field = calcExpectedName()
            }
            return field
        }
        private set
    private var canBeEmpty: Boolean? = null
    abstract fun parse(context: ParserContext): ParserInfo
    protected abstract fun calcName(): String
    protected abstract fun calcExpectedName(): HashSet<String?>
    operator fun plus(other: Parsec): Parsec {
        return Combinators.seq(this, other)
    }
    fun then(next: Parsec): Parsec {
        return this + next
    }

    fun or(next: Parsec): Parsec {
        return Combinators.choice(this, next)
    }

    fun sepBy1(next: Parsec): Parsec {
        return Combinators.sepBy1(this, next)
    }

    fun `as`(node: IElementType): SymbolicParsec {
        return SymbolicParsec(this, node)
    }

    abstract fun canStartWith(type: IElementType): Boolean
    fun canBeEmpty(): Boolean {
        if (canBeEmpty == null) {
            canBeEmpty = calcCanBeEmpty()
        }
        return canBeEmpty!!
    }

    protected abstract fun calcCanBeEmpty(): Boolean
}

Add sepBy method in parsers

package org.purescript.parser

import com.intellij.psi.tree.IElementType

abstract class Parsec {
    var name: String? = null
        get() {
            if (field == null) {
                field = calcName()
            }
            return field
        }
        private set
    var expectedName: HashSet<String?>? = null
        get() {
            if (field == null) {
                field = calcExpectedName()
            }
            return field
        }
        private set
    private var canBeEmpty: Boolean? = null
    abstract fun parse(context: ParserContext): ParserInfo
    protected abstract fun calcName(): String
    protected abstract fun calcExpectedName(): HashSet<String?>
    operator fun plus(other: Parsec): Parsec {
        return Combinators.seq(this, other)
    }
    fun then(next: Parsec): Parsec {
        return this + next
    }

    fun or(next: Parsec): Parsec {
        return Combinators.choice(this, next)
    }

    fun sepBy1(next: Parsec): Parsec {
        return Combinators.sepBy1(this, next)
    }

    fun `as`(node: IElementType): SymbolicParsec {
        return SymbolicParsec(this, node)
    }

    abstract fun canStartWith(type: IElementType): Boolean
    fun canBeEmpty(): Boolean {
        if (canBeEmpty == null) {
            canBeEmpty = calcCanBeEmpty()
        }
        return canBeEmpty!!
    }

    protected abstract fun calcCanBeEmpty(): Boolean
    fun sepBy(parsec: Parsec): Parsec = Combinators.sepBy(this, parsec)
}


data class PhoneNumber(private val rawNumber: String) {
    companion object {
        private val validationRegex = Regex("^1?(\\d{10})$")
    }
    private val cleanedNumber = rawNumber.replace(Regex("[^\\d]"), "")

    val number = validationRegex.matchEntire(cleanedNumber)?.groupValues?.last() ?: throw IllegalArgumentException()
    val areaCode = number.substring(0, 3)
    val exchangeCode = number.substring(3, 6)
    val subscriberNumber = number.substring(6, 10)

    override fun toString() = "($areaCode) $exchangeCode-$subscriberNumber"
}

Update phone number example for compatibility

data class PhoneNumber(private val rawNumber: String) {
    companion object {
        private val validationRegex = Regex("^1?([2-9]\\d{2}[2-9]\\d{6})$")
    }
    private val cleanedNumber = rawNumber.replace(Regex("[^\\d]"), "")

    val number = validationRegex.matchEntire(cleanedNumber)?.groupValues?.last() ?: throw IllegalArgumentException()
    val areaCode = number.substring(0, 3)
    val exchangeCode = number.substring(3, 6)
    val subscriberNumber = number.substring(6, 10)

    override fun toString() = "($areaCode) $exchangeCode-$subscriberNumber"
}


package org.purescript.ide.formatting

import com.intellij.formatting.*
import com.intellij.formatting.Spacing.getReadOnlySpacing
import com.intellij.lang.ASTNode
import com.intellij.psi.TokenType.WHITE_SPACE
import com.intellij.psi.formatter.common.AbstractBlock

class PSBlock(
    node: ASTNode,
    wrap: Wrap?,
    alignment: Alignment?,
    private val spacingBuilder: SpacingBuilder
) :
    AbstractBlock(node, wrap, alignment) {
    override fun buildChildren(): MutableList<Block> {
        val blocks = arrayListOf<Block>()
        var child = myNode.firstChildNode
        while (child != null) {
            if (child.elementType !== WHITE_SPACE && child.textLength != 0) {
                val block: Block = PSBlock(
                    child,
                    Wrap.createWrap(WrapType.NONE, false),
                    Alignment.createAlignment(),
                    spacingBuilder
                )
                blocks.add(block)
            }
            child = child.treeNext
        }
        return blocks
    }

    override fun isLeaf(): Boolean {
        return myNode.firstChildNode == null
    }

    override fun getSpacing(child1: Block?, child2: Block): Spacing? {
        return getReadOnlySpacing();
        //return spacingBuilder.getSpacing(this, child1, child2);
    }

}

Use spacing builder and don't have any indentation

package org.purescript.ide.formatting

import com.intellij.formatting.*
import com.intellij.formatting.Spacing.getReadOnlySpacing
import com.intellij.lang.ASTNode
import com.intellij.psi.TokenType.WHITE_SPACE
import com.intellij.psi.formatter.common.AbstractBlock

class PSBlock(
    node: ASTNode,
    wrap: Wrap?,
    alignment: Alignment?,
    private val spacingBuilder: SpacingBuilder
) :
    AbstractBlock(node, wrap, alignment) {
    override fun buildChildren(): MutableList<Block> {
        val blocks = arrayListOf<Block>()
        var child = myNode.firstChildNode
        while (child != null) {
            if (child.elementType !== WHITE_SPACE && child.textLength != 0) {
                val block: Block = PSBlock(
                    child,
                    Wrap.createWrap(WrapType.NONE, false),
                    Alignment.createAlignment(),
                    spacingBuilder
                )
                blocks.add(block)
            }
            child = child.treeNext
        }
        return blocks
    }

    override fun isLeaf(): Boolean {
        return myNode.firstChildNode == null
    }

    override fun getIndent(): Indent? {
        return Indent.getNoneIndent()
    }

    override fun getSpacing(child1: Block?, child2: Block): Spacing? {
        return spacingBuilder.getSpacing(this, child1, child2);
    }

}


package venus.simulator

import org.junit.Test
import kotlin.test.assertEquals
import venus.assembler.Assembler
import venus.linker.Linker

class Lab3Test {
    @Test
    fun Ex1() {
        val prog = Assembler.assemble(
"""
        .data
        .word 2, 4, 6, 8
n:      .word 9

        .text
main: 		add     t0, x0, x0
		addi    t1, x0, 1
		la      t3, n
		lw      t3, 0(t3)
fib: 		beq     t3, x0, finish
		add     t2, t1, t0
		mv      t0, t1
		mv      t1, t2
		addi    t3, t3, -1
		jal     x0, fib
finish: 	addi    a0, x0, 1
		addi    a1, t0, 0
		ecall
		addi    a0, x0, 10
		ecall
"""
        )
        val linked = Linker.link(listOf(prog))
        val sim = Simulator(linked)
        sim.run()
        assertEquals(34, sim.getReg(11))
    }
}

Fix test to not write to console

package venus.simulator

import org.junit.Test
import kotlin.test.assertEquals
import venus.assembler.Assembler
import venus.linker.Linker

class Lab3Test {
    @Test
    fun Ex1() {
        val prog = Assembler.assemble(
"""
        .data
        .word 2, 4, 6, 8
n:      .word 9

        .text
main: 		add     t0, x0, x0
		addi    t1, x0, 1
		la      t3, n
		lw      t3, 0(t3)
fib: 		beq     t3, x0, finish
		add     t2, t1, t0
		mv      t0, t1
		mv      t1, t2
		addi    t3, t3, -1
		jal     x0, fib
finish: addi    a0, x0, 1
		addi    a1, t0, 0
		# ecall
		addi    a0, x0, 10
		ecall
"""
        )
        val linked = Linker.link(listOf(prog))
        val sim = Simulator(linked)
        sim.run()
        assertEquals(34, sim.getReg(11))
    }
}


package io.github.vyo.twig

import nl.komponents.kovenant.async
import kotlin.concurrent.currentThread

/**
 * Created by Manuel Weidmann on 24.11.2015.
 */

class Logger(caller: Any) {
    val caller: Any = caller
    var threshold: Level

    init {
        threshold = root.threshold
    }

    companion object root {
        var threshold: Level = Level.INFO
    }

    fun log(message: String, level: Level) {
        if (level < threshold || level < root.threshold) return
        val thread: Thread = currentThread
        async {
            println("{${ escape("thread") }:${ escape(thread) }" +
                    "${escape("time")}:${escape(System.currentTimeMillis())}," +
                    "${escape("level")}:${escape(level.toInt())}," +
                    "${ escape("name") }:${ escape(caller) }, " +
                    "${escape("message")}:${escape(message)}}")
        }
    }

    private fun escape(string: Any): String {
        return "\"${string.toString()}\""
    }

    fun trace(message: String) {
        log(message, Level.TRACE)
    }

    fun debug(message: String) {
        log(message, Level.DEBUG)
    }

    fun info(message: String) {
        log(message, Level.INFO)
    }

    fun warn(message: String) {
        log(message, Level.WARN)
    }

    fun error(message: String) {
        log(message, Level.ERROR)
    }

    fun fatal(message: String) {
        log(message, Level.FATAL)
    }
}

Set up caller field the Kotlin-way

package io.github.vyo.twig

import nl.komponents.kovenant.async
import kotlin.concurrent.currentThread

/**
 * Created by Manuel Weidmann on 24.11.2015.
 */

class Logger(val caller: Any) {
    var threshold: Level

    init {
        threshold = root.threshold
    }

    companion object root {
        var threshold: Level = Level.INFO
    }

    fun log(message: String, level: Level) {
        if (level < threshold || level < root.threshold) return
        val thread: Thread = currentThread
        async {
            println("{${ escape("thread") }:${ escape(thread) }" +
                    "${escape("time")}:${escape(System.currentTimeMillis())}," +
                    "${escape("level")}:${escape(level.toInt())}," +
                    "${ escape("name") }:${ escape(caller) }, " +
                    "${escape("message")}:${escape(message)}}")
        }
    }

    private fun escape(string: Any): String {
        return "\"${string.toString()}\""
    }

    fun trace(message: String) {
        log(message, Level.TRACE)
    }

    fun debug(message: String) {
        log(message, Level.DEBUG)
    }

    fun info(message: String) {
        log(message, Level.INFO)
    }

    fun warn(message: String) {
        log(message, Level.WARN)
    }

    fun error(message: String) {
        log(message, Level.ERROR)
    }

    fun fatal(message: String) {
        log(message, Level.FATAL)
    }
}


import org.gradle.build.ClasspathManifest
import org.gradle.gradlebuild.testing.integrationtests.cleanup.EmptyDirectoryCheck
import org.gradle.gradlebuild.unittestandcompile.ModuleType

plugins {
    `java-library`
}

dependencies {
    api(project(":core"))
    api(project(":versionControl"))

    implementation(project(":resources"))
    implementation(project(":resourcesHttp"))

    implementation(library("asm"))
    implementation(library("asm_commons"))
    implementation(library("asm_util"))
    implementation(library("commons_lang"))
    implementation(library("commons_io"))
    implementation(library("ivy"))
    implementation(library("slf4j_api"))
    implementation(library("gson"))
    implementation(library("jcip"))
    implementation(library("maven3"))

    runtimeOnly(library("bouncycastle_provider"))
    runtimeOnly(project(":installationBeacon"))

    testImplementation(library("nekohtml"))

    integTestRuntimeOnly(project(":ivy"))
    integTestRuntimeOnly(project(":maven"))
    integTestRuntimeOnly(project(":resourcesS3"))
    integTestRuntimeOnly(project(":resourcesSftp"))
    integTestRuntimeOnly(project(":testKit"))

    testFixturesImplementation(project(":internalIntegTesting"))
}

gradlebuildJava {
    // TODO Source Compatibility was set to 1.6. Why? Is this worker code?
    moduleType = ModuleType.WORKER
}

testFixtures {
    from(":core")
    from(":messaging")
    from(":modelCore")
    from(":versionControl")
}

testFilesCleanup {
    isErrorWhenNotEmpty = false
}

val classpathManifest by tasks.getting(ClasspathManifest::class) {
    additionalProjects = listOf(project(":runtimeApiInfo"))
}

Change module type of dependency-management project to CORE

import org.gradle.build.ClasspathManifest
import org.gradle.gradlebuild.testing.integrationtests.cleanup.EmptyDirectoryCheck
import org.gradle.gradlebuild.unittestandcompile.ModuleType

plugins {
    `java-library`
}

dependencies {
    api(project(":core"))
    api(project(":versionControl"))

    implementation(project(":resources"))
    implementation(project(":resourcesHttp"))

    implementation(library("asm"))
    implementation(library("asm_commons"))
    implementation(library("asm_util"))
    implementation(library("commons_lang"))
    implementation(library("commons_io"))
    implementation(library("ivy"))
    implementation(library("slf4j_api"))
    implementation(library("gson"))
    implementation(library("jcip"))
    implementation(library("maven3"))

    runtimeOnly(library("bouncycastle_provider"))
    runtimeOnly(project(":installationBeacon"))

    testImplementation(library("nekohtml"))

    integTestRuntimeOnly(project(":ivy"))
    integTestRuntimeOnly(project(":maven"))
    integTestRuntimeOnly(project(":resourcesS3"))
    integTestRuntimeOnly(project(":resourcesSftp"))
    integTestRuntimeOnly(project(":testKit"))

    testFixturesImplementation(project(":internalIntegTesting"))
}

gradlebuildJava {
    moduleType = ModuleType.CORE
}

testFixtures {
    from(":core")
    from(":messaging")
    from(":modelCore")
    from(":versionControl")
}

testFilesCleanup {
    isErrorWhenNotEmpty = false
}

val classpathManifest by tasks.getting(ClasspathManifest::class) {
    additionalProjects = listOf(project(":runtimeApiInfo"))
}


package pl.mg6.likeornot.commons

fun <T> List<T>.batch(chunkSize: Int): List<List<T>> {
    if (chunkSize <= 0) {
        throw IllegalArgumentException("chunkSize must be greater than 0")
    }
    return mapIndexed { index, item -> IndexedItem(index, item) }
            .groupBy { it.index / chunkSize }
            .map { it.value.map { it.item } }
}

private class IndexedItem<T>(val index: Int, val item: T)

Make batching code more performant.

package pl.mg6.likeornot.commons

fun <T> List<T>.batch(chunkSize: Int): List<List<T>> {
    if (chunkSize <= 0) {
        throw IllegalArgumentException("chunkSize must be greater than 0")
    }
    val list = mutableListOf<MutableList<T>>()
    for (i in 0 until size) {
        if (i % chunkSize == 0) {
            list.add(mutableListOf())
        }
        list.last().add(get(i))
    }
    return list
}


package com.github.panpf.sketch.sample.vm

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.github.panpf.sketch.sample.ds.GiphyGifListPagingSource

class GiphyGifListViewModel(application: Application) : AndroidViewModel(application) {
    val pagingFlow = Pager(
        config = PagingConfig(
            pageSize = 80,
            enablePlaceholders = false,
        ),
        initialKey = 0,
        pagingSourceFactory = {
            GiphyGifListPagingSource(application)
        }
    ).flow.cachedIn(viewModelScope)
}

Fix GIF example page no content bug

package com.github.panpf.sketch.sample.vm

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.github.panpf.sketch.sample.ds.GiphyGifListPagingSource

class GiphyGifListViewModel(application: Application) : AndroidViewModel(application) {
    val pagingFlow = Pager(
        config = PagingConfig(
            pageSize = 40,
            enablePlaceholders = false,
        ),
        initialKey = 0,
        pagingSourceFactory = {
            GiphyGifListPagingSource(application)
        }
    ).flow.cachedIn(viewModelScope)
}


package br.com.bloder.migration.configuration

import android.content.Context
import br.com.bloder.migration.Migration
import br.com.bloder.migration.internal.detail.MigrationDetail
import br.com.bloder.migration.internal.detail.RealmConfigurationDetail
import io.realm.RealmConfiguration

/**
 * Get some properties to create realm configuration object
 */
class BetterRealmConfiguration() {

    /**
     * Treat all realm configuration properties
     *
     * @param context build realm configuration context
     * @param realmConfigurationDetails build realm configuration properties
     */
    class Builder(private val context : Context) {

        private var realmConfigurationDetails : RealmConfigurationDetail = RealmConfigurationDetail()
        private var migrationDetail : MigrationDetail = MigrationDetail()

        constructor(context: Context, realmConfigurationDetail: RealmConfigurationDetail) : this(context) {
            this.realmConfigurationDetails = realmConfigurationDetail
        }

        /**
         * Set realm name in realm configuration details
         *
         * @param name realm file name
         */
        fun name (name: String) : Builder {
            realmConfigurationDetails.name = name
            return this
        }

        /**
         * Set a migration in migration detail
         *
         * @param migration migration class
         */
        fun migration (migration : Migration) : MigrationBuilder {
            this.migrationDetail.migration = migration
            return MigrationBuilder(context, migrationDetail, realmConfigurationDetails)
        }

        /**
         * Build a realm configuration object
         *
         * @return realm configuration object instance
         */
        fun build() : RealmConfiguration = BetterRealmConfiguration(realmConfigurationDetails, context).createRealmConfiguration()
    }

    /**
     * Set each migration version
     *
     * @param context call builder class with correct context
     * @param migrationDetail receive version
     * @param realmConfigurationDetails set migration in this object
     */
    class MigrationBuilder(private val context: Context,
                           private var migrationDetail: MigrationDetail,
                           private var realmConfigurationDetails: RealmConfigurationDetail) {

        fun withVersion (version: Int) : Builder {
            migrationDetail.version = version
            realmConfigurationDetails.migration.add(migrationDetail)
            return Builder(context, realmConfigurationDetails)
        }
    }

    private var realmConfigurationDetails : RealmConfigurationDetail = RealmConfigurationDetail()
    private var context : Context? = null

    constructor(realmConfigurationDetail: RealmConfigurationDetail, context: Context) : this() {
        this.realmConfigurationDetails = realmConfigurationDetail
        this.context = context
    }

    /**
     * Create realm configuration object instance
     *
     * @return realm configuration object
     */
    fun createRealmConfiguration() : RealmConfiguration {
        val realmConfiguration : RealmConfiguration.Builder = RealmConfiguration.Builder(context)
        realmConfiguration.name(realmConfigurationDetails.name)
        return realmConfiguration.build()
    }
}


package rs.emulate.modern.codec.store

import com.google.common.io.MoreFiles
import com.google.common.jimfs.Configuration
import com.google.common.jimfs.Jimfs
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import rs.emulate.modern.ModernCache
import java.nio.file.Paths

class JagexFileStoreTest {

    @Test
    fun `open no data file`() {
        Jimfs.newFileSystem(Configuration.unix()).use { fs ->
            assertThrows(IllegalArgumentException::class.java) {
                JagexFileStore.open(fs.getPath("/"))
            }
        }
    }

    @Test
    fun `open non-existent dir`() {
        Jimfs.newFileSystem(Configuration.unix()).use { fs ->
            assertThrows(IllegalArgumentException::class.java) {
                JagexFileStore.open(fs.getPath("/non-existent"))
            }
        }
    }

    @Test
    fun `open file`() {
        Jimfs.newFileSystem(Configuration.unix()).use { fs ->
            MoreFiles.touch(fs.getPath("/file"))

            assertThrows(IllegalArgumentException::class.java) {
                JagexFileStore.open(fs.getPath("/file"))
            }
        }
    }

    @Test
    fun `opens cache and reference table`() {
        val fs = JagexFileStore.open(
            Paths.get("/home/gtierney/workspace/github/apollo-rsps/vicis/data/resources/181"),
            FileStoreOption.Lenient
        )
        val cache = ModernCache.open(fs)
    }

    // TODO add read/write/etc. tests
}

Remove integration test for modern cache

package rs.emulate.modern.codec.store

import com.google.common.io.MoreFiles
import com.google.common.jimfs.Configuration
import com.google.common.jimfs.Jimfs
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import rs.emulate.modern.ModernCache
import java.nio.file.Paths

class JagexFileStoreTest {

    @Test
    fun `open no data file`() {
        Jimfs.newFileSystem(Configuration.unix()).use { fs ->
            assertThrows(IllegalArgumentException::class.java) {
                JagexFileStore.open(fs.getPath("/"))
            }
        }
    }

    @Test
    fun `open non-existent dir`() {
        Jimfs.newFileSystem(Configuration.unix()).use { fs ->
            assertThrows(IllegalArgumentException::class.java) {
                JagexFileStore.open(fs.getPath("/non-existent"))
            }
        }
    }

    @Test
    fun `open file`() {
        Jimfs.newFileSystem(Configuration.unix()).use { fs ->
            MoreFiles.touch(fs.getPath("/file"))

            assertThrows(IllegalArgumentException::class.java) {
                JagexFileStore.open(fs.getPath("/file"))
            }
        }
    }
}


package org.gradle.kotlin.dsl.plugins

import org.gradle.kotlin.dsl.fixtures.AbstractIntegrationTest
import org.gradle.kotlin.dsl.fixtures.gradleRunnerFor

open class AbstractPluginTest : AbstractIntegrationTest() {

    protected
    fun buildWithPlugin(vararg arguments: String) =
        gradleRunnerFor(projectRoot)
            .withPluginClasspath()
            .withArguments(*arguments)
            .build()!!
}

Remove `withPluginClasspath` from plugins test

package org.gradle.kotlin.dsl.plugins

import org.gradle.kotlin.dsl.fixtures.AbstractIntegrationTest
import org.gradle.kotlin.dsl.fixtures.gradleRunnerFor

open class AbstractPluginTest : AbstractIntegrationTest() {

    protected
    fun buildWithPlugin(vararg arguments: String) =
        gradleRunnerFor(projectRoot)
            .withArguments(*arguments)
            .build()!!
}


Add a test to ensure that the Kodein configuration is complete.

/*
   Copyright 2017-2018 Charles Korn.

   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 batect

import batect.cli.CommandLineOptions
import batect.logging.LogSink
import batect.testutils.InMemoryLogSink
import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.throws
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.describe
import org.jetbrains.spek.api.dsl.it
import org.jetbrains.spek.api.dsl.on
import org.kodein.di.Copy
import org.kodein.di.Kodein
import org.kodein.di.generic.bind
import org.kodein.di.generic.instance
import java.io.ByteArrayOutputStream
import java.io.PrintStream

object InjectionConfigurationSpec : Spek({
    describe("Kodein injection configuration") {
        val originalConfiguration = createKodeinConfiguration(PrintStream(ByteArrayOutputStream()), PrintStream(ByteArrayOutputStream()))
        val configuration = Kodein.direct {
            extend(originalConfiguration, copy = Copy.All)
            bind<CommandLineOptions>() with instance(CommandLineOptions(taskName = "test-task"))
            bind<LogSink>() with instance(InMemoryLogSink())
        }

        describe("each registered class") {
            configuration.container.tree.bindings.keys.forEach { key ->
                on("attempting to get an instance matching $key") {
                    it("does not throw an invalid configuration exception") {
                        assertThat({ configuration.Instance(key.type, key.tag) }, !throws<Throwable>())
                    }
                }
            }
        }
    }
})


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

package com.google.idea.perf.cachedvaluetracer

data class CachedValueStats(
    val name: String,
    val lifetime: Long,
    val hits: Long,
    val misses: Long
) {
    val hitRatio: Double
        get() = hits.toDouble() / (hits + misses)
}

Add cached value stat documentation

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

package com.google.idea.perf.cachedvaluetracer

/**
 * Represents an aggregation of cached values properties.
 * @property name a name that represents the cached value aggregation
 * @property lifetime the aggregate lifetime of cached values
 * @property hits the number of times a cached value was reused
 * @property misses the number of times a cached value was created or invalidated
 */
data class CachedValueStats(
    val name: String,
    val lifetime: Long,
    val hits: Long,
    val misses: Long
) {
    val hitRatio: Double
        get() = hits.toDouble() / (hits + misses)
}


package com.github.ramonrabello.kiphy.presentation.trends

import android.graphics.Rect
import android.support.v7.widget.RecyclerView
import android.view.View

/**
 * Spacing item decoration for recycler view.
 */
class SpacingItemDecoration(val itemOffset:Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        outRect.apply {
            bottom = itemOffset
            top = itemOffset
            left = itemOffset
            right = itemOffset
        }
    }
}

Refactor to use AndroidX packages

package com.github.ramonrabello.kiphy.presentation.trends

import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView

/**
 * Spacing item decoration for recycler view.
 */
class SpacingItemDecoration(private val itemOffset:Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        outRect.apply {
            bottom = itemOffset
            top = itemOffset
            left = itemOffset
            right = itemOffset
        }
    }
}


package com.github.ramonrabello.kiphy.trends.data

import com.github.ramonrabello.kiphy.trends.TrendingApi
import com.github.ramonrabello.kiphy.trends.model.TrendingResponse
import io.reactivex.Single

interface TrendingDataSource {

    fun loadTrending(): Single<TrendingResponse>

    class Remote(private val api: TrendingApi) : TrendingDataSource {

        override fun loadTrending() =  api.loadTrending()

    }
}

Add Local inner class as stub just to be used by repository.

package com.github.ramonrabello.kiphy.trends.data

import com.github.ramonrabello.kiphy.trends.TrendingApi
import com.github.ramonrabello.kiphy.trends.model.TrendingResponse
import io.reactivex.Single

interface TrendingDataSource {

    fun loadTrending(): Single<TrendingResponse>

    class Remote(private val api: TrendingApi) : TrendingDataSource {

        override fun loadTrending() = api.loadTrending()

    }

    class Local : TrendingDataSource {

        override fun loadTrending() = Single.fromCallable { TrendingResponse((emptyList())) }

    }
}


package com.ids1024.whitakerswords

import java.util.ArrayList
import android.widget.TextView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.support.v7.widget.RecyclerView
import android.text.SpannableStringBuilder

class SearchAdapter(results: ArrayList<SpannableStringBuilder>) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
    var results = results

    override fun getItemCount(): Int {
        return results.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.text_view.text = results.get(position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.getContext()).inflate(R.layout.result, null)
        return ViewHolder(view)
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val text_view: TextView = view.findViewById(R.id.result_text)
    }
}

Make LayoutInflator.inflate() call match docs

package com.ids1024.whitakerswords

import java.util.ArrayList
import android.widget.TextView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.support.v7.widget.RecyclerView
import android.text.SpannableStringBuilder

class SearchAdapter(results: ArrayList<SpannableStringBuilder>) : RecyclerView.Adapter<SearchAdapter.ViewHolder>() {
    var results = results

    override fun getItemCount(): Int {
        return results.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.text_view.text = results.get(position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.result, parent, false)
        return ViewHolder(view)
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val text_view: TextView = view.findViewById(R.id.result_text)
    }
}


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

package com.demonwav.mcdev.platform.mixin.inspection.injector

import com.demonwav.mcdev.util.Parameter
import com.demonwav.mcdev.util.isErasureEquivalentTo
import com.intellij.psi.PsiParameter

data class ParameterGroup(val parameters: List<Parameter>?,
                          val required: Boolean = parameters != null,
                          val default: Boolean = required) {

    val size
        get() = this.parameters?.size ?: 0

    val wildcard
        get() = this.parameters == null

    fun match(parameters: Array<PsiParameter>, currentPosition: Int): Boolean {
        if (this.parameters == null) {
            // Wildcard parameter groups always match
            return true
        }

        // Check if remaining parameter count is enough
        if (currentPosition + size > parameters.size) {
            return false
        }

        var pos = currentPosition

        // Check parameter types
        for ((_, type) in this.parameters) {
            if (!type.isErasureEquivalentTo(parameters[pos++].type)) {
                return false
            }
        }

        return true
    }
}

Allow using array types instead of varargs for injectors

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

package com.demonwav.mcdev.platform.mixin.inspection.injector

import com.demonwav.mcdev.util.Parameter
import com.demonwav.mcdev.util.isErasureEquivalentTo
import com.intellij.psi.PsiArrayType
import com.intellij.psi.PsiEllipsisType
import com.intellij.psi.PsiParameter

data class ParameterGroup(val parameters: List<Parameter>?,
                          val required: Boolean = parameters != null,
                          val default: Boolean = required) {

    val size
        get() = this.parameters?.size ?: 0

    fun match(parameters: Array<PsiParameter>, currentPosition: Int): Boolean {
        if (this.parameters == null) {
            // Wildcard parameter groups always match
            return true
        }

        // Check if remaining parameter count is enough
        if (currentPosition + size > parameters.size) {
            return false
        }

        var pos = currentPosition

        // Check parameter types
        for ((_, type) in this.parameters) {
            val expectedType = parameters[pos++].type
            if (!type.isErasureEquivalentTo(expectedType)) {
                // Allow using array instead of varargs
                if (expectedType !is PsiEllipsisType || type !is PsiArrayType || type != expectedType.toArrayType()) {
                    return false
                }
            }
        }

        return true
    }
}


Add test for serializing WallpaperInteractiveWatchFaceInstanceParams

/*
 * Copyright 2022 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.wear.watchface.control.data

import android.content.ComponentName
import androidx.versionedparcelable.ParcelUtils
import androidx.wear.watchface.data.DeviceConfig
import androidx.wear.watchface.data.WatchUiState
import androidx.wear.watchface.style.UserStyle
import java.io.ByteArrayOutputStream
import org.junit.Test

class WallpaperInteractiveWatchFaceInstanceParamsTest {
    @Test
    fun canBeWrittenToOutputStream() {
        val params = WallpaperInteractiveWatchFaceInstanceParams(
            "instanceId",
            DeviceConfig(
                false,
                false,
                10,
                10
            ),
            WatchUiState(
                false,
                0,
            ),
            UserStyle(emptyMap()).toWireFormat(),
            null,
            ComponentName("some.package", "SomeClass")
        )

        val dummyOutputStream = ByteArrayOutputStream()

        // Should not throw an exception
        ParcelUtils.toOutputStream(params, dummyOutputStream)
    }
}