dependencies {
    api("me.champeau.gradle:japicmp-gradle-plugin:0.2.7")

    implementation(project(":buildPlatform"))
    implementation(project(":kotlinDsl"))
    implementation("com.google.code.gson:gson:2.8.2")
    implementation("org.javassist:javassist:3.23.0-GA")
    implementation("com.github.javaparser:javaparser-core")
    implementation("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.0.5")

    testImplementation("org.jsoup:jsoup:1.11.3")
}

tasks {
    compileGroovy {
        classpath += files(compileKotlin)
    }
}

Upgrade kotlinx.metadata from 0.0.5 to 0.1.0 in buildSrc

dependencies {
    api("me.champeau.gradle:japicmp-gradle-plugin:0.2.7")

    implementation(project(":buildPlatform"))
    implementation(project(":kotlinDsl"))
    implementation("com.google.code.gson:gson:2.8.2")
    implementation("org.javassist:javassist:3.23.0-GA")
    implementation("com.github.javaparser:javaparser-core")
    implementation("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0")

    testImplementation("org.jsoup:jsoup:1.11.3")
}

tasks {
    compileGroovy {
        classpath += files(compileKotlin)
    }
}


package org.wikipedia.navtab

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_nav_tab_overlay_fill.view.*
import org.wikipedia.R

class NavTabOverlayLayout constructor(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
    init {
        View.inflate(context, R.layout.view_nav_tab_overlay, null)
    }

    fun pick(navTab: NavTab) {
        removeAllViews()
        for (i in 0 until NavTab.size()) {
            var childView = View(context)
            if (NavTab.of(i) == navTab) {
                childView = View.inflate(context, R.layout.view_nav_tab_overlay_fill, null)
                childView.pulsingBaseIcon.setImageResource(navTab.icon())
                childView.pulsingCircleOuter.startAnimation(AnimationUtils.loadAnimation(context, R.anim.pulsing_circle))
            }
            childView.layoutParams = LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f)
            addView(childView)
        }
        visibility = VISIBLE
    }

    fun hide() {
        visibility = GONE
    }
}

Update constructor of custom view

package org.wikipedia.navtab

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_nav_tab_overlay_fill.view.*
import org.wikipedia.R

class NavTabOverlayLayout constructor(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs) {
    init {
        View.inflate(context, R.layout.view_nav_tab_overlay, null)
    }

    fun pick(navTab: NavTab) {
        removeAllViews()
        for (i in 0 until NavTab.size()) {
            var childView = View(context)
            if (NavTab.of(i) == navTab) {
                childView = View.inflate(context, R.layout.view_nav_tab_overlay_fill, null)
                childView.pulsingBaseIcon.setImageResource(navTab.icon())
                childView.pulsingCircleOuter.startAnimation(AnimationUtils.loadAnimation(context, R.anim.pulsing_circle))
            }
            childView.layoutParams = LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f)
            addView(childView)
        }
        visibility = VISIBLE
    }

    fun hide() {
        visibility = GONE
    }
}


/*
 * Copyright 2018 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
 *
 *     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 app.tivi.extensions

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch

suspend fun <A, B> Collection<A>.parallelForEach(
    concurrency: Int = 10,
    block: suspend (A) -> B
): Unit = coroutineScope {
    val semaphore = Channel<Unit>(concurrency)
    forEach { item ->
        launch {
            semaphore.send(Unit) // Acquire concurrency permit
            block(item)
            semaphore.receive() // Release concurrency permit
        }
    }
}

Add try-finally block to make sure we release the concurrency permit

/*
 * Copyright 2018 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
 *
 *     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 app.tivi.extensions

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch

suspend fun <A> Collection<A>.parallelForEach(
    concurrency: Int = 10,
    block: suspend (A) -> Unit
): Unit = coroutineScope {
    val semaphore = Channel<Unit>(concurrency)
    forEach { item ->
        launch {
            semaphore.send(Unit) // Acquire concurrency permit
            try {
                block(item)
            } finally {
                semaphore.receive() // Release concurrency permit
            }
        }
    }
}


package com.elpassion.intelijidea.common

import com.elpassion.intelijidea.util.mfFilename
import org.junit.Assert.assertEquals
import org.junit.Test

class MFCommandLineTest {

    @Test
    fun shouldGenerateCommandLineToExecute() {
        val commandLine = MFCommandLine(
                buildCommand = "./gradlew",
                taskName = "build")
        commandLine.verify()
    }

    @Test
    fun shouldGenerateProperCommandLineToExecute() {
        val commandLine = MFCommandLine(
                buildCommand = "gradle",
                taskName = "assembleDebug")
        commandLine.verify()
    }

    @Test
    fun shouldGenerateProperCommandLineWithCustomPathToExecute() {
        val commandLine = MFCommandLine(
                mfPath = "/customPath",
                buildCommand = "gradle",
                taskName = "build")
        commandLine.verify()
    }

    @Test
    fun shouldGenerateProperCommandLineWithWhiteSpacePathToExecute() {
        val commandLine = MFCommandLine(
                mfPath = "/White Spaced Path",
                buildCommand = "gradle",
                taskName = "build")
        commandLine.verify()
    }

    private fun MFCommandLine.verify() {
        val expectedParams = listOf(
                "${if (mfPath != null) "$mfPath/" else ""}$mfFilename",
                "$buildCommand $taskName"
        ).map { if (it.contains(" ")) "\"$it\"" else it }
        assertEquals("bash ${expectedParams.joinToString(separator = " ")}", commandLineString)
    }
}

Add command line factory for test purpose

package com.elpassion.intelijidea.common

import com.elpassion.intelijidea.util.mfFilename
import org.junit.Assert.assertEquals
import org.junit.Test

class MFCommandLineTest {

    @Test
    fun shouldGenerateCommandLineToExecute() {
        val commandLine = createCommandLine()
        commandLine.verify()
    }

    @Test
    fun shouldGenerateProperCommandLineToExecute() {
        val commandLine = createCommandLine(buildCommand = "gradle", taskName = "assembleDebug")
        commandLine.verify()
    }

    @Test
    fun shouldGenerateProperCommandLineWithCustomPathToExecute() {
        val commandLine = createCommandLine(mfPath = "/customPath")
        commandLine.verify()
    }

    @Test
    fun shouldGenerateProperCommandLineWithWhiteSpacePathToExecute() {
        val commandLine = createCommandLine(mfPath = "/White Spaced Path")
        commandLine.verify()
    }

    private fun MFCommandLine.verify() {
        val expectedParams = listOf(
                "${if (mfPath != null) "$mfPath/" else ""}$mfFilename",
                "$buildCommand $taskName"
        ).map { if (it.contains(" ")) "\"$it\"" else it }
        assertEquals("bash ${expectedParams.joinToString(separator = " ")}", commandLineString)
    }

    private fun createCommandLine(mfPath: String = "", buildCommand: String = "./gradlew", taskName: String = "build")
            = MFCommandLine(mfPath, buildCommand, taskName)
}


package com.sampsonjoliver.firestarter

import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.sampsonjoliver.firestarter.service.SessionManager
import com.sampsonjoliver.firestarter.views.login.LoginActivity

abstract class FirebaseActivity : AppCompatActivity(),
        SessionManager.SessionAuthListener {

    override fun onLogin() {

    }

    override fun onLogout() {
        applicationContext.startActivity(Intent(this, LoginActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
                addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        })
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        SessionManager.startSession(this, this)
    }

    override fun onStop() {
        super.onStop()
        SessionManager.stopSession()
    }
}

Change to Firebase session lifecycle calls

package com.sampsonjoliver.firestarter

import android.content.Intent
import android.os.Build
import android.support.v7.app.AppCompatActivity
import com.sampsonjoliver.firestarter.service.SessionManager
import com.sampsonjoliver.firestarter.views.login.LoginActivity

abstract class FirebaseActivity : AppCompatActivity(),
        SessionManager.SessionAuthListener {

    override fun onLogin() {

    }

    override fun onLogout() {
        applicationContext.startActivity(Intent(this, LoginActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
                addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        })
    }

    override fun onResume() {
        super.onResume()
        SessionManager.startSession(this, this)
    }

    override fun onPause() {
        super.onPause()
        SessionManager.stopSession()
    }
}


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

package org.jetbrains.plugins.ideavim.action.motion.visual

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

class VisualExitModeActionTest : VimTestCase() {
  fun `test exit visual mode after line end`() {
    doTest("vl<Esc>", "12${c}3", "12${c}3", CommandState.Mode.COMMAND, CommandState.SubMode.NONE)
  }
}

Add test for double exiting visual mode

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

package org.jetbrains.plugins.ideavim.action.motion.visual

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

class VisualExitModeActionTest : VimTestCase() {
  fun `test exit visual mode after line end`() {
    doTest("vl<Esc>", "12${c}3", "12${c}3", CommandState.Mode.COMMAND, CommandState.SubMode.NONE)
  }

  fun `test double exit`() {
    doTest("vl<Esc><Esc>", "12${c}3", "12${c}3", CommandState.Mode.COMMAND, CommandState.SubMode.NONE)
    assertTrue(myFixture.editor.settings.isBlockCursor)
  }
}


package com.goldenpiedevs.schedule.app.core.api.lessons

import com.goldenpiedevs.schedule.app.core.dao.BaseResponseModel
import com.goldenpiedevs.schedule.app.core.dao.timetable.DaoWeekModel
import com.goldenpiedevs.schedule.app.core.dao.timetable.TimeTableData
import io.realm.Realm
import io.realm.RealmList
import kotlinx.coroutines.experimental.Deferred
import kotlinx.coroutines.experimental.async
import retrofit2.Response

class LessonsManager(private val lessonsService: LessonsService) {
    fun loadTimeTable(groupId: Int?): Deferred<Response<BaseResponseModel<TimeTableData>>> = async {
        val response = lessonsService.getGroupTimeTable(groupId).await()

        if (response.isSuccessful) {
            var realm = Realm.getDefaultInstance()

            realm.executeTransaction {
                it.copyToRealmOrUpdate(listOf(response.body()!!.data!!.weeks!!.firstWeekModel!!,
                        response.body()!!.data!!.weeks!!.secondWeekModel!!)
                        .map {
                            val daoWeekModel = DaoWeekModel()
                            daoWeekModel.weekNumber = it.weekNumber

                            daoWeekModel.days = RealmList()
                            daoWeekModel.days.addAll(it.daysMap!!.entries.map { it.value })

                            daoWeekModel
                        })
            }

            if(!realm.isClosed)
                realm.close()
        }

        response
    }
}

Save only days with lessons

package com.goldenpiedevs.schedule.app.core.api.lessons

import com.goldenpiedevs.schedule.app.core.dao.BaseResponseModel
import com.goldenpiedevs.schedule.app.core.dao.timetable.DaoWeekModel
import com.goldenpiedevs.schedule.app.core.dao.timetable.TimeTableData
import io.realm.Realm
import io.realm.RealmList
import kotlinx.coroutines.experimental.Deferred
import kotlinx.coroutines.experimental.async
import retrofit2.Response

class LessonsManager(private val lessonsService: LessonsService) {
    fun loadTimeTable(groupId: Int?): Deferred<Response<BaseResponseModel<TimeTableData>>> = async {
        val response = lessonsService.getGroupTimeTable(groupId).await()

        if (response.isSuccessful) {
            val realm = Realm.getDefaultInstance()

            realm.executeTransaction { transaction ->
                transaction.copyToRealmOrUpdate(listOf(response.body()!!.data!!.weeks!!.firstWeekModel!!,
                        response.body()!!.data!!.weeks!!.secondWeekModel!!)
                        .map { map ->
                            val daoWeekModel = DaoWeekModel()
                            daoWeekModel.weekNumber = map.weekNumber

                            daoWeekModel.days = RealmList()
                            daoWeekModel.days.addAll(map.daysMap!!.entries
                                    .filter { !it.value.lessons.isEmpty() }
                                    .map { it.value })

                            daoWeekModel
                        })
            }

            if (!realm.isClosed)
                realm.close()
        }

        response
    }
}


/* 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 = "91.0.20210613190144"
}

Update Mozilla Android Components to 91.0.20210624190127.

/* 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 = "91.0.20210624190127"
}


package com.github.jk1.ytplugin.notifications

import com.github.jk1.ytplugin.whenActive
import com.intellij.icons.AllIcons
import com.intellij.ide.browsers.BrowserLauncher
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.DumbAware

class ConfigureNotificationsAction(private val notification: YouTrackNotification) :
        AnAction("Configure", "", AllIcons.General.Settings), DumbAware {

    override fun actionPerformed(event: AnActionEvent) {
        event.whenActive {
            // todo: user login or id instead of 'me'
            val url = "${notification.repoUrl}/users/me?tab=notifications"
            ServiceManager.getService(BrowserLauncher::class.java).open(url)
        }
    }
}

Configure -> Configure Notifications cosmetic

package com.github.jk1.ytplugin.notifications

import com.github.jk1.ytplugin.whenActive
import com.intellij.icons.AllIcons
import com.intellij.ide.browsers.BrowserLauncher
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.DumbAware

class ConfigureNotificationsAction(private val notification: YouTrackNotification) :
        AnAction("Configure Notifications", "", AllIcons.General.Settings), DumbAware {

    override fun actionPerformed(event: AnActionEvent) {
        event.whenActive {
            // todo: user login or id instead of 'me'
            val url = "${notification.repoUrl}/users/me?tab=notifications"
            ServiceManager.getService(BrowserLauncher::class.java).open(url)
        }
    }
}


package org.koin.mp

import org.koin.core.logger.KOIN_TAG
import org.koin.core.logger.Level
import org.koin.core.logger.MESSAGE
import org.koin.core.state.jvmThreading
import kotlin.reflect.KClass

actual object PlatformTools {
    actual fun className(kClass: KClass<*>): String = kClass.java.simpleName
    actual fun printStackTrace(throwable: Throwable) {
        throwable.printStackTrace()
    }

    actual fun stackTrace(): List<String> = Thread.currentThread().stackTrace
            .takeWhile { !it.className.contains("sun.reflect") }
            .map { stackTraceElement -> stackTraceElement.toString() }

    actual fun printLog(level: Level, msg: MESSAGE) {
        val printer = if (level >= Level.ERROR) System.err else System.out
        printer.println("[$level] $KOIN_TAG $msg")
    }
}

internal actual fun Any.ensureNeverFrozen() {}

internal actual fun <R> mpsynchronized(lock: Any, block: () -> R): R = jvmThreading.mainOrSynchronized(lock, block)

Fix IllegalStateException after Android obfuscation

package org.koin.mp

import org.koin.core.logger.KOIN_TAG
import org.koin.core.logger.Level
import org.koin.core.logger.MESSAGE
import org.koin.core.state.jvmThreading
import kotlin.reflect.KClass

actual object PlatformTools {
    actual fun className(kClass: KClass<*>): String = kClass.java.name
    actual fun printStackTrace(throwable: Throwable) {
        throwable.printStackTrace()
    }

    actual fun stackTrace(): List<String> = Thread.currentThread().stackTrace
            .takeWhile { !it.className.contains("sun.reflect") }
            .map { stackTraceElement -> stackTraceElement.toString() }

    actual fun printLog(level: Level, msg: MESSAGE) {
        val printer = if (level >= Level.ERROR) System.err else System.out
        printer.println("[$level] $KOIN_TAG $msg")
    }
}

internal actual fun Any.ensureNeverFrozen() {}

internal actual fun <R> mpsynchronized(lock: Any, block: () -> R): R = jvmThreading.mainOrSynchronized(lock, block)


package jp.toastkid.yobidashi.libs.network

import android.app.DownloadManager
import android.content.Context
import android.net.Uri

/**
 * Method object of downloading.
 *
 * @author toastkidjp
 */
class DownloadAction(
        val context: Context,
        val url: String
) {
    fun invoke() {
        val request = DownloadManager.Request(Uri.parse(url))

        request.allowScanningByMediaScanner()
        request.setNotificationVisibility(
                DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        request.setVisibleInDownloadsUi(true)
        val dm = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
        dm.enqueue(request)
    }
}

Modify saving directory which save downloaded items.

package jp.toastkid.yobidashi.libs.network

import android.app.DownloadManager
import android.content.Context
import android.net.Uri
import android.os.Environment

/**
 * Method object of downloading.
 *
 * @author toastkidjp
 */
class DownloadAction(
        val context: Context,
        val url: String
) {
    fun invoke() {
        val uri = Uri.parse(url)
        val request = DownloadManager.Request(uri)

        request.allowScanningByMediaScanner()
        request.setNotificationVisibility(
                DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        request.setVisibleInDownloadsUi(true)
        request.setDestinationInExternalFilesDir(
                context, Environment.DIRECTORY_DOWNLOADS, uri.lastPathSegment)
        context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).mkdirs()
        val dm = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
        dm.enqueue(request)
    }
}


package com.sedsoftware.yaptalker.features.videodisplay

import com.arellomobile.mvp.InjectViewState
import com.sedsoftware.yaptalker.base.BasePresenter

@InjectViewState
class VideoDisplayPresenter : BasePresenter<VideoDisplayView>() {

  fun loadVideoContent() {
    viewState.displayWebViewContent()
  }

  override fun attachView(view: VideoDisplayView?) {
    super.attachView(view)
    viewState.initWebView()
  }

  override fun detachView(view: VideoDisplayView?) {
    super.detachView(view)
    viewState.clearWebView()
  }
}

Fix webView reset on view detach

package com.sedsoftware.yaptalker.features.videodisplay

import com.arellomobile.mvp.InjectViewState
import com.sedsoftware.yaptalker.base.BasePresenter

@InjectViewState
class VideoDisplayPresenter : BasePresenter<VideoDisplayView>() {

  fun loadVideoContent() {
    viewState.displayWebViewContent()
  }

  override fun attachView(view: VideoDisplayView?) {
    super.attachView(view)
    viewState.initWebView()
  }

  override fun detachView(view: VideoDisplayView?) {
    viewState.clearWebView()
    super.detachView(view)
  }
}


Add tests for dependency provision from a component

/*
 * Copyright 2020 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

import org.junit.Assert.assertEquals
import org.junit.Test
import javax.inject.Inject
import javax.inject.Named

class ComponentModuleTest {

  @Test
  fun testComponentWithoutModules() {
    val lightsaber = Lightsaber.Builder().build()
    val injector = lightsaber.createInjector(ComponentWithoutModules())
    val container = injector.getInstance<InjectionContainer>()

    assertEquals("Component", container.componentString)
    assertEquals("Module", container.moduleString)
  }

  @Test
  fun testComponentWithModules() {
    val lightsaber = Lightsaber.Builder().build()
    val injector = lightsaber.createInjector(ComponentWithModules())
    val container = injector.getInstance<InjectionContainer>()

    assertEquals("Component", container.componentString)
    assertEquals("Module", container.moduleString)
  }

  @Component
  class ComponentWithoutModules {

    @Provide
    private val componentString = "Component"

    @Provide
    @Named("Module")
    private fun provideModuleString() = "Module"
  }

  @Component
  class ComponentWithModules {

    @Provide
    private fun provideString() = "Component"

    @Import
    private fun importModule() = ComponentModule()
  }

  @Module
  class ComponentModule {

    @Provide
    @Named("Module")
    private fun provideString() = "Module"
  }

  @ProvidedBy(ComponentWithoutModules::class, ComponentWithModules::class)
  class InjectionContainer @Inject private constructor(
    @Inject
    val componentString: String,
    @Inject
    @field:Named("Module")
    val moduleString: String
  )
}


package com.satsumasoftware.timetable

import android.app.Activity
import android.app.Application
import android.util.Log

import com.jakewharton.threetenabp.AndroidThreeTen
import com.satsumasoftware.timetable.db.util.ClassUtils
import com.satsumasoftware.timetable.framework.Timetable

class TimetableApplication : Application() {

    private val LOG_TAG = "TimetableApplication"

    var currentTimetable: Timetable? = null
        set(value) {
            field = value
            value?.let {
                PrefUtils.setCurrentTimetable(this, field!!)
                Log.i(LOG_TAG, "Switched current timetable to that with id ${field!!.id}")
            }
        }

    override fun onCreate() {
        super.onCreate()

        AndroidThreeTen.init(this)

        currentTimetable = PrefUtils.getCurrentTimetable(this)
    }

    fun refreshAlarms(activity: Activity) {
        // Cancel alarms from all timetables and add alarms for the current one
        val alarmReceiver = AlarmReceiver()

        Log.i(LOG_TAG, "Cancelling ALL alarms")
        for (classTime in ClassUtils.getAllClassTimes(activity)) {
            alarmReceiver.cancelAlarm(activity, classTime.id)
        }

        Log.i(LOG_TAG, "Addiing alarms for the current timetable (id: ${currentTimetable!!.id})")
        for (classTime in ClassUtils.getAllClassTimes(activity, currentTimetable!!)) {
            ClassUtils.addAlarmsForClassTime(activity, classTime)
        }
    }

}

Fix spelling mistake in log message

package com.satsumasoftware.timetable

import android.app.Activity
import android.app.Application
import android.util.Log

import com.jakewharton.threetenabp.AndroidThreeTen
import com.satsumasoftware.timetable.db.util.ClassUtils
import com.satsumasoftware.timetable.framework.Timetable

class TimetableApplication : Application() {

    private val LOG_TAG = "TimetableApplication"

    var currentTimetable: Timetable? = null
        set(value) {
            field = value
            value?.let {
                PrefUtils.setCurrentTimetable(this, field!!)
                Log.i(LOG_TAG, "Switched current timetable to that with id ${field!!.id}")
            }
        }

    override fun onCreate() {
        super.onCreate()

        AndroidThreeTen.init(this)

        currentTimetable = PrefUtils.getCurrentTimetable(this)
    }

    fun refreshAlarms(activity: Activity) {
        // Cancel alarms from all timetables and add alarms for the current one
        val alarmReceiver = AlarmReceiver()

        Log.i(LOG_TAG, "Cancelling ALL alarms")
        for (classTime in ClassUtils.getAllClassTimes(activity)) {
            alarmReceiver.cancelAlarm(activity, classTime.id)
        }

        Log.i(LOG_TAG, "Adding alarms for the current timetable (id: ${currentTimetable!!.id})")
        for (classTime in ClassUtils.getAllClassTimes(activity, currentTimetable!!)) {
            ClassUtils.addAlarmsForClassTime(activity, classTime)
        }
    }

}


package me.echeung.moemoekyun.util.ext

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

fun launchUI(block: suspend CoroutineScope.() -> Unit): Job =
    GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT, block)

fun launchIO(block: suspend CoroutineScope.() -> Unit): Job =
    GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT, block)

@OptIn(ExperimentalCoroutinesApi::class)
fun launchNow(block: suspend CoroutineScope.() -> Unit): Job =
    GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED, block)

Fix crash when starting app without network

package me.echeung.moemoekyun.util.ext

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch

private val scope = CoroutineScope(SupervisorJob())

fun launchUI(block: suspend CoroutineScope.() -> Unit): Job =
    scope.launch(Dispatchers.Main, CoroutineStart.DEFAULT, block)

fun launchIO(block: suspend CoroutineScope.() -> Unit): Job =
    scope.launch(Dispatchers.IO, CoroutineStart.DEFAULT, block)

@OptIn(ExperimentalCoroutinesApi::class)
fun launchNow(block: suspend CoroutineScope.() -> Unit): Job =
    scope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED, block)


package com.doomspork.helloworld.resources

import com.doomspork.helloworld.core.Saying
import com.google.common.base.Optional
import org.junit.Test
import org.junit.Assert.*

class HelloWorldResourceTest {
    @Test
    fun testSayHello() {
        run {
            val resource=HelloWorldResource("Hello, %s!", "Stranger")
            val expected= Saying(id = 1, content = "Hello, Stranger!");
            assertEquals(resource.sayHello(Optional.absent()), expected)
        }
        run {
            val resource=HelloWorldResource("Hello, %s!", "Stranger")
            val expected= Saying(id = 1, content = "Hello, TEST!");
            assertEquals(resource.sayHello(Optional.of("TEST")), expected)
        }
    }

    @Test
    fun testGetTemplate() {
        val r=HelloWorldResource("a", "b")
        assertEquals(r.template, "a")
    }

    @Test
    fun testGetDefaultName() {
        val r=HelloWorldResource("a", "b")
        assertEquals(r.defaultName, "b")
    }
}


Add 1st class ConstraintLayout Guideline support

package splitties.views.dsl.constraintlayout

import android.widget.LinearLayout
import androidx.annotation.Px
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Guideline
import splitties.dimensions.dip
import splitties.views.dsl.core.add
import splitties.views.dsl.core.view
import splitties.views.dsl.core.wrapContent
import splitties.views.generateViewId

/**
 * Creates and adds a vertical [Guideline] to this [ConstraintLayout].
 * A value needs to be supplied for one and only one of the three parameters.
 * [begin] and [end] are in pixels (you can use [dip]).
 * [widthRatio] is a value between 0 and 1.
 */
fun ConstraintLayout.verticalGuideline(
    @Px begin: Int = -1,
    @Px end: Int = -1,
    widthRatio: Float = -1.0f
): Guideline = guideline(begin, end, widthRatio, vertical = true)

/**
 * Creates and adds a horizontal [Guideline] to this [ConstraintLayout].
 * A value needs to be supplied for one and only one of the three parameters.
 * [begin] and [end] are in pixels (you can use [dip]).
 * [heightRatio] is a value between 0 and 1.
 */
fun ConstraintLayout.horizontalGuideline(
    @Px begin: Int = -1,
    @Px end: Int = -1,
    heightRatio: Float = -1.0f
): Guideline = guideline(begin, end, heightRatio, vertical = false)

private fun ConstraintLayout.guideline(
    begin: Int,
    end: Int,
    sideRatio: Float,
    vertical: Boolean
): Guideline {
    require(when {
        begin != -1 -> end == -1 && sideRatio == -1.0f
        end != -1 -> begin == -1 && sideRatio == -1.0f
        sideRatio != -1f -> begin == -1 && end == -1 && sideRatio >= 0f && sideRatio <= 1f
        else -> false
    })
    return add(view(::Guideline) {
        id = generateViewId()
    }, lParams(wrapContent, wrapContent) {
        orientation = if (vertical) LinearLayout.VERTICAL else LinearLayout.HORIZONTAL
        guideBegin = begin
        guideEnd = end
        guidePercent = sideRatio
    })
}


plugins {
	`kotlin-dsl`
}

repositories {
	mavenCentral()
	gradlePluginPortal()
}

dependencies {
	implementation(kotlin("gradle-plugin"))
	implementation("de.marcphilipp.gradle:nexus-publish-plugin:0.4.0")
	implementation("biz.aQute.bnd:biz.aQute.bnd.gradle:5.1.0")
	implementation("com.github.jengelman.gradle.plugins:shadow:5.2.0")
}

Upgrade to Shadow plugin 6.0.0

plugins {
	`kotlin-dsl`
}

repositories {
	mavenCentral()
	gradlePluginPortal()
}

dependencies {
	implementation(kotlin("gradle-plugin"))
	implementation("de.marcphilipp.gradle:nexus-publish-plugin:0.4.0")
	implementation("biz.aQute.bnd:biz.aQute.bnd.gradle:5.1.0")
	implementation("com.github.jengelman.gradle.plugins:shadow:6.0.0")
}


/*
 * Copyright (C) 2019. Zac Sweers
 *
 * 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.sweers.catchup.app

import android.app.Application
import dagger.BindsInstance
import dagger.Component
import dagger.android.AndroidInjectionModule
import dagger.android.support.AndroidSupportInjectionModule
import io.sweers.catchup.data.DataModule
import io.sweers.catchup.ui.activity.ActivityBindingModule
import javax.inject.Singleton

@Singleton
@Component(modules = [
  ActivityBindingModule::class,
  AndroidSupportInjectionModule::class,
  AndroidInjectionModule::class,
  ApplicationModule::class,
  DataModule::class,
  ReleaseApplicationModule::class
])
interface ApplicationComponent {

  fun inject(application: CatchUpApplication)

  @Component.Factory
  interface Builder {
    fun create(@BindsInstance application: Application): ApplicationComponent
  }
}

Fix missing okhttp builder in release variant

/*
 * Copyright (C) 2019. Zac Sweers
 *
 * 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.sweers.catchup.app

import android.app.Application
import dagger.BindsInstance
import dagger.Component
import dagger.android.AndroidInjectionModule
import dagger.android.support.AndroidSupportInjectionModule
import io.sweers.catchup.data.DataModule
import io.sweers.catchup.data.InstanceBasedOkHttpLibraryGlideModule
import io.sweers.catchup.ui.activity.ActivityBindingModule
import javax.inject.Singleton

@Singleton
@Component(modules = [
  ActivityBindingModule::class,
  AndroidSupportInjectionModule::class,
  AndroidInjectionModule::class,
  ApplicationModule::class,
  DataModule::class,
  ReleaseApplicationModule::class
])
interface ApplicationComponent {

  fun okhttpGlideComponentBuilder(): InstanceBasedOkHttpLibraryGlideModule.Component.Builder

  fun inject(application: CatchUpApplication)

  @Component.Factory
  interface Builder {
    fun create(@BindsInstance application: Application): ApplicationComponent
  }
}


package org.brightify.reactant.core.component

import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import org.brightify.reactant.core.LifetimeDisposeBagContainer

/**
 *  @author Filip Dolnik
 */
interface Component<STATE, ACTION>: LifetimeDisposeBagContainer {
    val stateDisposeBag: CompositeDisposable

    val observableState: Observable<STATE>

    val previousComponentState: STATE?

    var componentState: STATE

    val action: Observable<ACTION>

    fun afterInit()

    fun needsUpdate(): Boolean

    fun update()

    fun perform(action: ACTION)
}

fun <STATE, ACTION> Component<STATE, ACTION>.setComponentState(state: STATE) {
    componentState = state
}

fun <STATE, ACTION> Component<STATE, ACTION>.withState(state: STATE): Component<STATE, ACTION> {
    setComponentState(state)
    return this
}

fun <STATE: MutableComponentState<STATE>>Component<STATE, *>.mutateState(mutation: STATE.() -> Unit) {
    val copy = componentState.clone()
    mutation(copy)
    setComponentState(copy)
}

Make `withState` return concrete type.

package org.brightify.reactant.core.component

import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import org.brightify.reactant.core.LifetimeDisposeBagContainer

/**
 *  @author Filip Dolnik
 */
interface Component<STATE, ACTION>: LifetimeDisposeBagContainer {
    val stateDisposeBag: CompositeDisposable

    val observableState: Observable<STATE>

    val previousComponentState: STATE?

    var componentState: STATE

    val action: Observable<ACTION>

    fun afterInit()

    fun needsUpdate(): Boolean

    fun update()

    fun perform(action: ACTION)
}

fun <STATE, ACTION> Component<STATE, ACTION>.setComponentState(state: STATE) {
    componentState = state
}

fun <STATE, ACTION, COMPONENT: Component<STATE, ACTION>> COMPONENT.withState(state: STATE): COMPONENT {
    setComponentState(state)
    return this
}

fun <STATE: MutableComponentState<STATE>>Component<STATE, *>.mutateState(mutation: STATE.() -> Unit) {
    val copy = componentState.clone()
    mutation(copy)
    setComponentState(copy)
}


import kotlinx.html.*
import kotlinx.html.stream.appendHTML
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class TestExceptions {
    @Test fun `default exception must result in empty tag`() {

        val sb = StringBuilder()

        var errorCaught = false

        try {
            sb.appendHTML(prettyPrint = false).html {
                body {
                    h1 {
                        +"empty"
                        throw IllegalStateException("testing errors")
                    }
                    h2 {
                        +"should NOT be written"
                    }
                }
            }
        } catch (err: IllegalStateException) {
            errorCaught = true
            assertEquals(err.message, "testing errors")
        }

        assertTrue(errorCaught, "Exception should be not re-thrown")

        assertEquals(
                "
empty
",
                sb.toString())
    }

    @Test fun `exception handler should add output`() {

        val sb = StringBuilder()
        TestExceptionConsumer(sb.appendHTML(prettyPrint = false)).html {
            body {
                h1 {
                    throw IllegalStateException("testing errors")
                }
                h2 {
                    +"should be present"
                }
            }
        }

        assertEquals(
                "

error was handled

should be present
",
                sb.toString())
    }
}

private class TestExceptionConsumer<R>(val underlying: TagConsumer<R>) : TagConsumer<R> by underlying {
    override fun onError(tag: Tag, exception: Exception) {

        div { +"error was handled" }

    }
}


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

import com.intellij.debugger.streams.ui.ValueWithPosition
import com.intellij.ui.JBColor
import java.awt.Graphics
import javax.swing.JPanel

/**
 * @author Vitaliy.Bibaev
 */
class MappingPane(private val beforeValues: List<ValueWithPosition>) : JPanel() {

  override fun paintComponent(g: Graphics?) {
    if (g == null) {
      return
    }

    val x1 = x
    val x2 = x + width
    for (value in beforeValues) {
      val position: Int = value.position
      for (nextValue in value.nextValues.filter { it.isVisible }) {
        g.color = JBColor.WHITE
        g.drawLine(x1, position, x2, nextValue.position)
      }
    }
  }
}

Add component which drawing a mapping between before and after values

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

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

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

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

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


package com.byoutline.secretsauce

import android.arch.lifecycle.ViewModelProvider
import android.content.Context
import android.support.annotation.IdRes

/**
 * Initializes some variables globally for SecretSauce.
 * As an alternative you usually can pass those values as method optional
 * parameter.
 *
 * @author Sebastian Kacprzak <nait at naitbit.com>
 */
object SecretSauceSettings {
    var DEBUG: Boolean = false
    var containerViewId: Int = 0
    var brViewModelId: Int = 0
    var logPrefix = "SecretS"
    var viewModelFactoryProvider: (ctx: Context) -> ViewModelProvider.Factory = {
        throw IllegalStateException("You must init viewModelFactoryProvider")
    }

    fun set(debug: Boolean = DEBUG,
            @IdRes containerViewId: Int = this.containerViewId,
            bindingViewModelId: Int = brViewModelId,
            viewModelFactoryProvider: (ctx: Context) -> ViewModelProvider.Factory = this.viewModelFactoryProvider) {
        DEBUG = debug
        this.containerViewId = containerViewId
        brViewModelId = bindingViewModelId
        this.viewModelFactoryProvider = viewModelFactoryProvider
        System.setProperty("org.joda.time.DateTimeZone.Provider", "com.byoutline.secretsauce.utils.JdkBasedTimeZoneProvider")
    }
}

Make Settings `containerViewId` `brViewModelId` internal

package com.byoutline.secretsauce

import android.arch.lifecycle.ViewModelProvider
import android.content.Context
import android.support.annotation.IdRes

/**
 * Initializes some variables globally for SecretSauce.
 * As an alternative you usually can pass those values as method optional
 * parameter.
 *
 * @author Sebastian Kacprzak <nait at naitbit.com>
 */
object SecretSauceSettings {
    var DEBUG: Boolean = false
    internal var containerViewId: Int = 0
    internal var brViewModelId: Int = 0
    var logPrefix = "SecretS"
    var viewModelFactoryProvider: (ctx: Context) -> ViewModelProvider.Factory = {
        throw IllegalStateException("You must init viewModelFactoryProvider")
    }

    fun set(debug: Boolean = DEBUG,
            @IdRes containerViewId: Int = this.containerViewId,
            bindingViewModelId: Int = brViewModelId,
            viewModelFactoryProvider: (ctx: Context) -> ViewModelProvider.Factory = this.viewModelFactoryProvider) {
        DEBUG = debug
        this.containerViewId = containerViewId
        brViewModelId = bindingViewModelId
        this.viewModelFactoryProvider = viewModelFactoryProvider
        System.setProperty("org.joda.time.DateTimeZone.Provider", "com.byoutline.secretsauce.utils.JdkBasedTimeZoneProvider")
    }
}


Add aliases for the different dispatchers

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

package com.guerinet.suitcase.coroutines

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

/**
 * Extensions / top level functions used for Kotlin Coroutines
 * @author Julien Guerinet
 * @since 4.7.0
 */

/** Convenience variable to get the Main Dispatcher */
val uiDispatcher: CoroutineDispatcher = Dispatchers.Main

/** Convenience variable to get the Default (i.e. background) Dispatcher */
val bgDispatcher: CoroutineDispatcher = Dispatchers.Default

/** Convenience variable to get the IO (i.e. background) Dispatcher */
val ioDispatcher: CoroutineDispatcher = Dispatchers.IO


/*
 * Copyright 2018 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.samples.apps.iosched.shared.util

import android.content.Context
import android.net.ConnectivityManager
import androidx.content.systemService
import javax.inject.Inject

/**
 * Checks if a network connection exists.
 */
open class NetworkUtils @Inject constructor(val context: Context) {

    open fun hasNetworkConnection(): Boolean {
        val connectivityManager: ConnectivityManager = context.systemService()
        val activeNetworkInfo = connectivityManager.activeNetworkInfo
        return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
    }
}

Fix the crash on Lollipop.

/*
 * Copyright 2018 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.samples.apps.iosched.shared.util

import android.content.Context
import android.content.Context.CONNECTIVITY_SERVICE
import android.net.ConnectivityManager
import javax.inject.Inject

/**
 * Checks if a network connection exists.
 */
open class NetworkUtils @Inject constructor(val context: Context) {

    open fun hasNetworkConnection(): Boolean {
        val connectivityManager= context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetworkInfo = connectivityManager.activeNetworkInfo
        return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
    }
}


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

import com.intellij.debugger.streams.trace.dsl.LambdaBody
import com.intellij.debugger.streams.trace.dsl.StatementFactory

/**
 * @author Vitaliy.Bibaev
 */
class JavaLambdaBody(statementFactory: StatementFactory, override val argName: String) : JavaCodeBlock(statementFactory), LambdaBody {
  override fun toCode(indent: Int): String = if (isExpression()) statements.first().toCode(0) else super.toCode(indent)

  fun isExpression(): Boolean = statements.size == 1
}

Use updated api of CodeBlockBase in LambdaBody

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

import com.intellij.debugger.streams.trace.dsl.LambdaBody
import com.intellij.debugger.streams.trace.dsl.StatementFactory

/**
 * @author Vitaliy.Bibaev
 */
class JavaLambdaBody(statementFactory: StatementFactory, override val argName: String) : JavaCodeBlock(statementFactory), LambdaBody {
  override fun toCode(indent: Int): String = if (isExpression()) getStatements().first().toCode() else super.toCode(indent)

  fun isExpression(): Boolean = size == 1
}


package org.http4k.security.oauth.server

import org.http4k.core.Uri
import java.time.Instant

/**
 * Provides a consistent way to manage authorization codes
 */
interface AuthorizationCodes {
    /**
     * Create new authorization code to be given to client after the user successfully authorize access
     */
    fun create(clientId: ClientId, redirectUri: Uri): AuthorizationCode

    /**
     * Retrieve the details of an authorization code
     */
    fun detailsFor(code: AuthorizationCode): AuthorizationCodeDetails

    /**
     * Destroys an authorization token after it's been used to generate an access token
     */
    fun destroy(authorizationCode: AuthorizationCode)
}

data class AuthorizationCodeDetails(
    val clientId: ClientId,
    val redirectUri: Uri,
    val expiresAt: Instant
)

Add doc note regarding authorization code generation

package org.http4k.security.oauth.server

import org.http4k.core.Uri
import java.time.Instant

/**
 * Provides a consistent way to manage authorization codes
 */
interface AuthorizationCodes {
    /**
     * Create new authorization code to be given to client after the user successfully authorize access
     * The generated authorization code needs to be associated with the clientId and redirectUri for later verification.
     * It should also be associated with a given expire date (recommended to be shorter than 10 minutes)
     */
    fun create(clientId: ClientId, redirectUri: Uri): AuthorizationCode

    /**
     * Retrieve the details of an authorization code
     */
    fun detailsFor(code: AuthorizationCode): AuthorizationCodeDetails

    /**
     * Destroys an authorization token after it's been used to generate an access token
     */
    fun destroy(authorizationCode: AuthorizationCode)
}

data class AuthorizationCodeDetails(
    val clientId: ClientId,
    val redirectUri: Uri,
    val expiresAt: Instant
)


package org.gradle.gradlebuild

import org.gradle.api.JavaVersion
import org.gradle.internal.os.OperatingSystem

object BuildEnvironment {
    val isCiServer = "CI" in System.getenv()
    val gradleKotlinDslVersion = "1.0.1"
    val jvm = org.gradle.internal.jvm.Jvm.current()
    val javaVersion = JavaVersion.current()
    val isWindows = OperatingSystem.current().isWindows
    val isSlowInternetConnection
        get() = System.getProperty("slow.internet.connection", "false").toBoolean()
    val agentNum: Int
        get() {
            if (System.getenv().containsKey("USERNAME")) {
                val agentNumEnv = System.getenv("USERNAME").replaceFirst("tcagent", "")
                if (Regex("""\d+""").containsMatchIn(agentNumEnv)) {
                    return agentNumEnv.toInt()
                }
            }
            return 1
        }
}

Upgrade Kotlin DSL to 1.0.2

package org.gradle.gradlebuild

import org.gradle.api.JavaVersion
import org.gradle.internal.os.OperatingSystem

object BuildEnvironment {
    val isCiServer = "CI" in System.getenv()
    val gradleKotlinDslVersion = "1.0.2"
    val jvm = org.gradle.internal.jvm.Jvm.current()
    val javaVersion = JavaVersion.current()
    val isWindows = OperatingSystem.current().isWindows
    val isSlowInternetConnection
        get() = System.getProperty("slow.internet.connection", "false").toBoolean()
    val agentNum: Int
        get() {
            if (System.getenv().containsKey("USERNAME")) {
                val agentNumEnv = System.getenv("USERNAME").replaceFirst("tcagent", "")
                if (Regex("""\d+""").containsMatchIn(agentNumEnv)) {
                    return agentNumEnv.toInt()
                }
            }
            return 1
        }
}


package com.satsumasoftware.timetable.framework

import org.threeten.bp.LocalTime
import java.util.*

/**
 * A data structure merely to group [ClassTime] objects with the same start and end dates as each
 * other.
 *
 * @property startTime The start time all `ClassTime`s in this group will have
 * @property endTime The end time all `ClassTime`s in this group will have
 */
class ClassTimeGroup(val startTime: LocalTime, val endTime: LocalTime) {

    val classTimes = ArrayList<ClassTime>()

    /**
     * Adds a [ClassTime] to this group.
     *
     * @param classTime The [ClassTime] to be added to this group. It must have the same start and
     *          end times as the ones specified in this class.
     * @see startTime
     * @see endTime
     */
    fun addClassTime(classTime: ClassTime) {
        if (!classTime.startTime.equals(startTime) || !classTime.endTime.equals(endTime)) {
            throw IllegalArgumentException("invalid class time - the start and end times must" +
                    "match the ones specified from this object's constructor")
        }
        classTimes.add(classTime)
    }

    /**
     * @return if the [classTime] can be added to the group (if it has the same start and end times)
     */
    fun canAdd(classTime: ClassTime) =
            classTime.startTime.equals(startTime) && classTime.endTime.equals(endTime)

}

Add a 'see' reference for ClassTime in the ClassTImeGroup doc

package com.satsumasoftware.timetable.framework

import org.threeten.bp.LocalTime
import java.util.*

/**
 * A data structure merely to group [ClassTime] objects with the same start and end dates as each
 * other.
 *
 * @property startTime The start time all `ClassTime`s in this group will have
 * @property endTime The end time all `ClassTime`s in this group will have
 *
 * @see ClassTime
 */
class ClassTimeGroup(val startTime: LocalTime, val endTime: LocalTime) {

    val classTimes = ArrayList<ClassTime>()

    /**
     * Adds a [ClassTime] to this group.
     *
     * @param classTime The [ClassTime] to be added to this group. It must have the same start and
     *          end times as the ones specified in this class.
     * @see startTime
     * @see endTime
     */
    fun addClassTime(classTime: ClassTime) {
        if (!classTime.startTime.equals(startTime) || !classTime.endTime.equals(endTime)) {
            throw IllegalArgumentException("invalid class time - the start and end times must" +
                    "match the ones specified from this object's constructor")
        }
        classTimes.add(classTime)
    }

    /**
     * @return if the [classTime] can be added to the group (if it has the same start and end times)
     */
    fun canAdd(classTime: ClassTime) =
            classTime.startTime.equals(startTime) && classTime.endTime.equals(endTime)

}


Add test code for PlaceholderAnimatedBrush

/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      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.accompanist.placeholder

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.test.junit4.createComposeRule
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class PlaceholderAnimatedBrushTest {
    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun fadeBrush_colorsDefault() {
        composeTestRule.setContent {
            fadeBrush()
        }
    }

    @Test
    fun shimmerBrush_colorsDefault() {
        composeTestRule.setContent {
            shimmerBrush()
        }
    }

    @Test
    fun fadeBrush_colorsCustom() {
        composeTestRule.setContent {
            fadeBrush(initialColor = Color.Red, targetColor = Color.Blue)
        }
    }

    @Test
    fun shimmerBrush_colorsCustom() {
        composeTestRule.setContent {
            shimmerBrush(color = Color.Red, highlightColor = Color.Blue)
        }
    }

    @Test
    fun fadeBrush_equalsDefault() {
        assertThat(fadeBrush()).isEqualTo(fadeBrush())
    }

    @Test
    fun shimmerBrush_equalsDefault() {
        assertThat(shimmerBrush()).isEqualTo(shimmerBrush())
    }

    @Test
    fun fadeBrush_equalsCustom() {
        assertThat(fadeBrush(initialColor = Color.Red, targetColor = Color.Blue))
            .isEqualTo(fadeBrush(initialColor = Color.Red, targetColor = Color.Blue))
    }

    @Test
    fun shimmerBrush_equalsCustom() {
        assertThat(shimmerBrush(color = Color.Red, highlightColor = Color.Blue))
            .isEqualTo(shimmerBrush(color = Color.Red, highlightColor = Color.Blue))
    }
}


package org.javacs.kt.codeaction.quickfix

import org.eclipse.lsp4j.CodeAction
import org.eclipse.lsp4j.Command
import org.eclipse.lsp4j.Diagnostic
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.jsonrpc.messages.Either
import org.javacs.kt.CompiledFile
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.diagnostics.Diagnostic as KotlinDiagnostic

interface QuickFix {
    // Computes the quickfix. Return null if the quickfix is not valid.
    fun compute(file: CompiledFile, range: Range, diagnostics: List<Diagnostic>): Either<Command, CodeAction>?
}

fun diagnosticMatch(diagnostic: Diagnostic, range: Range, diagnosticTypes: HashSet<String>): Boolean =
    diagnostic.range.equals(range) && diagnosticTypes.contains(diagnostic.code.left)

fun diagnosticMatch(diagnostic: KotlinDiagnostic, startCursor: Int, endCursor: Int, diagnosticTypes: HashSet<String>): Boolean =
    diagnostic.textRanges.any { it.startOffset == startCursor && it.endOffset == endCursor } && diagnosticTypes.contains(diagnostic.factory.name)

fun findDiagnosticMatch(diagnostics: List<Diagnostic>, range: Range, diagnosticTypes: HashSet<String>) =
    diagnostics.find { diagnosticMatch(it, range, diagnosticTypes) }

fun anyDiagnosticMatch(diagnostics: Diagnostics, startCursor: Int, endCursor: Int, diagnosticTypes: HashSet<String>) =
    diagnostics.any { diagnosticMatch(it, startCursor, endCursor, diagnosticTypes) }

Use Set instead of HashSet in diagnostic match helpers

package org.javacs.kt.codeaction.quickfix

import org.eclipse.lsp4j.CodeAction
import org.eclipse.lsp4j.Command
import org.eclipse.lsp4j.Diagnostic
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.jsonrpc.messages.Either
import org.javacs.kt.CompiledFile
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.diagnostics.Diagnostic as KotlinDiagnostic

interface QuickFix {
    // Computes the quickfix. Return null if the quickfix is not valid.
    fun compute(file: CompiledFile, range: Range, diagnostics: List<Diagnostic>): Either<Command, CodeAction>?
}

fun diagnosticMatch(diagnostic: Diagnostic, range: Range, diagnosticTypes: Set<String>): Boolean =
    diagnostic.range.equals(range) && diagnosticTypes.contains(diagnostic.code.left)

fun diagnosticMatch(diagnostic: KotlinDiagnostic, startCursor: Int, endCursor: Int, diagnosticTypes: Set<String>): Boolean =
    diagnostic.textRanges.any { it.startOffset == startCursor && it.endOffset == endCursor } && diagnosticTypes.contains(diagnostic.factory.name)

fun findDiagnosticMatch(diagnostics: List<Diagnostic>, range: Range, diagnosticTypes: Set<String>) =
    diagnostics.find { diagnosticMatch(it, range, diagnosticTypes) }

fun anyDiagnosticMatch(diagnostics: Diagnostics, startCursor: Int, endCursor: Int, diagnosticTypes: Set<String>) =
    diagnostics.any { diagnosticMatch(it, startCursor, endCursor, diagnosticTypes) }


/* Copyright 2016-present The KotlinNLP Authors. All Rights Reserved.
 *
 * 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 com.kotlinnlp.simplednn.core.optimizer

import com.kotlinnlp.simplednn.core.arrays.ParamsArray

/**
 * Generic params errors collector.
 */
class GenericParamsErrorsCollector {

  /**
   * The structure in which to accumulate the parameters errors.
   */
  private val paramsErrorsMap = mutableMapOf<String, ParamsArray.Errors<*>>()

  /**
   * Return the current errors of this parameters.
   */
  fun getErrors(params: ParamsArray) =
    this.paramsErrorsMap.getOrPut(params.uuid, defaultValue = { params.buildDenseErrors() } )

  /**
   * Clear the accumulated errors.
   */
  fun clear() = this.paramsErrorsMap.clear()
}

Add getAll() method and update documentation

/* Copyright 2016-present The KotlinNLP Authors. All Rights Reserved.
 *
 * 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 com.kotlinnlp.simplednn.core.optimizer

import com.kotlinnlp.simplednn.core.arrays.ParamsArray

/**
 * Generic params errors collector.
 */
class GenericParamsErrorsCollector {

  /**
   * The structure in which to accumulate the parameters errors.
   */
  private val paramsErrorsMap = mutableMapOf<String, ParamsArray.Errors<*>>()

  /**
   * @param params a parameters
   *
   * @return the current errors of the given parameters
   */
  fun getErrors(params: ParamsArray) =
    this.paramsErrorsMap.getOrPut(params.uuid, defaultValue = { params.buildDenseErrors() } )

  /**
   * @return all the collected params errors
   */
  fun getAll(): ParamsErrorsList = this.paramsErrorsMap.values.toList()

  /**
   * Clear the accumulated errors.
   */
  fun clear() = this.paramsErrorsMap.clear()
}


package org.stepik.android.remote.stories.service

import io.reactivex.Single
import org.stepik.android.remote.stories.model.StoryTemplatesResponse
import retrofit2.http.GET
import retrofit2.http.Query

interface StoryService {
    @GET("api/story-templates")
    fun getStoryTemplate(
        @Query("page") page: Int,
        @Query("is_published") isPublished: Boolean,
        @Query("language") language: String
    ): Single<StoryTemplatesResponse>
}

Add platform query parameter to stories

package org.stepik.android.remote.stories.service

import io.reactivex.Single
import org.stepik.android.remote.stories.model.StoryTemplatesResponse
import retrofit2.http.GET
import retrofit2.http.Query

interface StoryService {
    @GET("api/story-templates?platform=mobile,android")
    fun getStoryTemplate(
        @Query("page") page: Int,
        @Query("is_published") isPublished: Boolean,
        @Query("language") language: String
    ): Single<StoryTemplatesResponse>
}


package com.ageet.gradle.plugin.apkname

/**
 * @property format format of apk name.
 * @property projectName gradle project name.
 * @property applicationId android applicationId.
 * @property versionCode android versionCode.
 * @property versionName android versionName.
 * @property variantName android variantName.
 * @property buildType android buildType.
 * @property gitShortHash git short commit hash.
 */
open class ApkNameExtension {

    var format = "${projectName}_${versionName}_$gitShortHash"
    var releaseOnly = false

    val projectName: String
        get() = "#{projectName}"
    val applicationId: String
        get() = "#{applicationId}"
    val versionCode: String
        get() = "#{versionCode}"
    val versionName: String
        get() = "#{versionName}"
    val variantName: String
        get() = "#{variantName}"
    val flavorName: String
        get() = "#{flavorName}"
    val buildType: String
        get() = "#{buildType}"
    val gitShortHash: String
        get() = "#{gitShortHash}"
}

Change default value of releaseOnly

package com.ageet.gradle.plugin.apkname

/**
 * @property format format of apk name.
 * @property projectName gradle project name.
 * @property applicationId android applicationId.
 * @property versionCode android versionCode.
 * @property versionName android versionName.
 * @property variantName android variantName.
 * @property buildType android buildType.
 * @property gitShortHash git short commit hash.
 */
open class ApkNameExtension {

    var format = "${projectName}_${versionName}_$gitShortHash"
    var releaseOnly = true

    val projectName: String
        get() = "#{projectName}"
    val applicationId: String
        get() = "#{applicationId}"
    val versionCode: String
        get() = "#{versionCode}"
    val versionName: String
        get() = "#{versionName}"
    val variantName: String
        get() = "#{variantName}"
    val flavorName: String
        get() = "#{flavorName}"
    val buildType: String
        get() = "#{buildType}"
    val gitShortHash: String
        get() = "#{gitShortHash}"
}


package com.todoist.pojo

import java.util.regex.Pattern

object Sanitizers {
    const val PROJECT_NAME_INVALID_CHARACTERS = "#\""
    const val SECTION_NAME_INVALID_CHARACTERS = "/\""
    const val LABEL_NAME_INVALID_CHARACTERS = "@\"\\s"

    @JvmField
    val PROJECT_NAME_INVALID_PATTERN = Pattern.compile("[$PROJECT_NAME_INVALID_CHARACTERS]+")

    @JvmField
    val SECTION_NAME_INVALID_PATTERN = Pattern.compile("[$SECTION_NAME_INVALID_CHARACTERS]+")

    @JvmField
    val LABEL_NAME_INVALID_PATTERN = Pattern.compile("[$LABEL_NAME_INVALID_CHARACTERS]+")

    const val REPLACEMENT = "_"
}

Update name sanitizers and remove lint warnings

package com.todoist.pojo

import java.util.regex.Pattern

object Sanitizers {
    const val PROJECT_NAME_INVALID_CHARACTERS = "#\"()|&!,"
    const val SECTION_NAME_INVALID_CHARACTERS = "/\"()|&!,"
    const val LABEL_NAME_INVALID_CHARACTERS = "@\"\\s()|&!,"

    @JvmField
    val PROJECT_NAME_INVALID_PATTERN: Pattern = Pattern.compile("[$PROJECT_NAME_INVALID_CHARACTERS]+")

    @JvmField
    val SECTION_NAME_INVALID_PATTERN: Pattern = Pattern.compile("[$SECTION_NAME_INVALID_CHARACTERS]+")

    @JvmField
    val LABEL_NAME_INVALID_PATTERN: Pattern = Pattern.compile("[$LABEL_NAME_INVALID_CHARACTERS]+")

    const val REPLACEMENT = "_"
}


Add data class examle. Also getters/setters are wierd in Kotlin!

package codesample.kotlin.sandbox.classes

data class Dude(val name: String,
                val surname: String,
                val age: Int) {
    val someProp : String
        get() = "getter is called!"
}

fun main(args: Array<String>) {
    val ivan = Dude("Ivan", "Ivanov", 15)
    println(ivan.toString() + " ivans hash: " + ivan.hashCode())

    /* This may seem like accessing a public field... but it's not! This access actually
    * call a getter on some prop */
    println(ivan.someProp)
}


package net.perfectdreams.loritta.website.routes.api.v1.loritta

import com.github.salomonbrys.kotson.jsonObject
import com.mrpowergamerbr.loritta.threads.RaffleThread
import io.ktor.application.ApplicationCall
import net.perfectdreams.loritta.platform.discord.LorittaDiscord
import net.perfectdreams.loritta.website.routes.api.v1.RequiresAPIAuthenticationRoute
import net.perfectdreams.loritta.website.utils.extensions.respondJson

class GetRaffleStatusRoute(loritta: LorittaDiscord) : RequiresAPIAuthenticationRoute(loritta, "/api/v1/loritta/raffle") {
	override suspend fun onAuthenticatedRequest(call: ApplicationCall) {
		val jsonObject = jsonObject(
				"lastWinnerId" to RaffleThread.lastWinnerId,
				"lastWinnerPrize" to RaffleThread.lastWinnerPrize,
				"currentTickets" to RaffleThread.userIds.size,
				"usersParticipating" to RaffleThread.userIds.distinctBy { it }.size,
				"started" to RaffleThread.started
		)

		call.respondJson(jsonObject)
	}
}

Fix users participating in the raffle status route

package net.perfectdreams.loritta.website.routes.api.v1.loritta

import com.github.salomonbrys.kotson.jsonObject
import com.mrpowergamerbr.loritta.threads.RaffleThread
import io.ktor.application.*
import net.perfectdreams.loritta.platform.discord.LorittaDiscord
import net.perfectdreams.loritta.website.routes.api.v1.RequiresAPIAuthenticationRoute
import net.perfectdreams.loritta.website.utils.extensions.respondJson

class GetRaffleStatusRoute(loritta: LorittaDiscord) : RequiresAPIAuthenticationRoute(loritta, "/api/v1/loritta/raffle") {
	override suspend fun onAuthenticatedRequest(call: ApplicationCall) {
		val jsonObject = jsonObject(
				"lastWinnerId" to RaffleThread.lastWinnerId,
				"lastWinnerPrize" to RaffleThread.lastWinnerPrize,
				"currentTickets" to RaffleThread.userIds.size,
				"usersParticipating" to RaffleThread.userIds.distinctBy { it }.size,
				"started" to RaffleThread.started
		)

		call.respondJson(jsonObject)
	}
}


package com.tekinarslan.kotlinrxjavasample.network

import com.google.gson.GsonBuilder
import com.tekinarslan.kotlinrxjavasample.service.DataService
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

/**
 * Created by selimtekinarslan on 6/29/2017.
 */
class NetworkManager {

    private var client: OkHttpClient? = null
    var service: DataService? = null

    init {
        val retrofit = Retrofit.Builder()
                .baseUrl("https://jsonplaceholder.typicode.com")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
                .client(createOkHttpClient())
                .build()
        createServices(retrofit)
    }

    fun createServices(retrofit: Retrofit) {
        service = retrofit.create(DataService::class.java)
    }

    fun createOkHttpClient(): OkHttpClient {
        if (client == null) {
            client = OkHttpClient()
        }
        return client as OkHttpClient
    }

}

Use lateinit instead of null type.

package com.tekinarslan.kotlinrxjavasample.network

import com.google.gson.GsonBuilder
import com.tekinarslan.kotlinrxjavasample.service.DataService
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

/**
 * Created by selimtekinarslan on 6/29/2017.
 */
class NetworkManager {

    lateinit var service: DataService

    init {
        val retrofit = Retrofit.Builder()
                .baseUrl("https://jsonplaceholder.typicode.com")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
                .client(OkHttpClient())
                .build()
        createServices(retrofit)
    }

    fun createServices(retrofit: Retrofit) {
        service = retrofit.create(DataService::class.java)
    }
}


package com.livinglifetechway.k4kotlin

import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentTransaction

/**
 * Runs a FragmentTransaction, then calls commit().
 */
private inline fun FragmentManager.transact(function: FragmentTransaction.() -> Unit) {
    beginTransaction().apply {
        function()
    }.commit()
}

Fix transact function marked as private

package com.livinglifetechway.k4kotlin

import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentTransaction

/**
 * Runs a FragmentTransaction, then calls commit().
 */
inline fun FragmentManager.transact(function: FragmentTransaction.() -> Unit) {
    beginTransaction().apply {
        function()
    }.commit()
}


package io.gitlab.arturbosch.detekt.test

import java.net.URI
import java.nio.file.Files
import java.nio.file.Paths

internal object Resources

fun resource(name: String): URI {
	val explicitName = if (name.startsWith("/")) name else "/$name"
	val resource = Resources::class.java.getResource(explicitName)
	requireNotNull(resource) { "Make sure the resource '$name' exists!" }
	return resource.toURI()
}

fun resourcePath(name: String): String = resource(name).path

fun resourceAsString(name: String): String = String(Files.readAllBytes(Paths.get(resourcePath(name))))

Use uri instead of converting it to a string in paths

package io.gitlab.arturbosch.detekt.test

import java.net.URI
import java.nio.file.Files
import java.nio.file.Paths

internal object Resources

fun resource(name: String): URI {
	val explicitName = if (name.startsWith("/")) name else "/$name"
	val resource = Resources::class.java.getResource(explicitName)
	requireNotNull(resource) { "Make sure the resource '$name' exists!" }
	return resource.toURI()
}

fun resourceAsString(name: String): String = String(Files.readAllBytes(Paths.get(resource(name))))


Add top-level constants for service descriptor, method descriptor, etc.

package io.grpc.kotlin.generator

import com.google.protobuf.Descriptors
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.asTypeName
import io.grpc.MethodDescriptor
import io.grpc.ServiceDescriptor
import io.grpc.kotlin.generator.protoc.Declarations
import io.grpc.kotlin.generator.protoc.GeneratorConfig
import io.grpc.kotlin.generator.protoc.builder
import io.grpc.kotlin.generator.protoc.declarations
import io.grpc.kotlin.generator.protoc.methodName

class TopLevelConstantsGenerator(config: GeneratorConfig): ServiceCodeGenerator(config) {
  override fun generate(service: Descriptors.ServiceDescriptor): Declarations = declarations {
    addProperty(
      PropertySpec.builder("serviceDescriptor", ServiceDescriptor::class)
        .getter(
          FunSpec.getterBuilder()
            .addStatement("return %T.getServiceDescriptor()", service.grpcClass)
            .build()
        )
        .build()
    )

    with(config) {
      for (method in service.methods) {
        addProperty(
          PropertySpec
            .builder(
              method.methodName.toMemberSimpleName().withSuffix("Method"),
              MethodDescriptor::class.asTypeName().parameterizedBy(
                method.inputType.messageClass(),
                method.outputType.messageClass()
              )
            )
            .getter(
              FunSpec.getterBuilder()
                .addStatement("return %T.get%LMethod()", service.grpcClass, method.methodName)
                .build()
            )
            .build()
        )
      }
    }
  }
}


package com.github.pockethub.android.ui.item.news

import android.view.View
import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import com.github.pockethub.android.ui.view.OcticonTextView
import com.github.pockethub.android.util.AvatarLoader
import com.meisolsson.githubsdk.model.GitHubEvent
import com.meisolsson.githubsdk.model.payload.MemberPayload
import com.xwray.groupie.kotlinandroidextensions.ViewHolder
import kotlinx.android.synthetic.main.news_item.*

class MemberEventItem(
        avatarLoader: AvatarLoader,
        gitHubEvent: GitHubEvent
) : NewsItem(avatarLoader, gitHubEvent) {

    override fun bind(holder: ViewHolder, position: Int) {
        super.bind(holder, position)
        holder.tv_event_icon.text = OcticonTextView.ICON_ADD_MEMBER
        holder.tv_event.text = buildSpannedString {
            val context = holder.root.context
            val payload = gitHubEvent.payload() as MemberPayload?
            boldActor(context, this, gitHubEvent)
            append(" added ")
            bold {
                append(payload?.member()?.login())
            }
            append(" as a collaborator to ")
            boldRepo(context, this, gitHubEvent)
        }
        holder.tv_event_details.visibility = View.GONE
    }
}

Make person made collaborator in news title clickable

package com.github.pockethub.android.ui.item.news

import android.view.View
import androidx.core.text.buildSpannedString
import com.github.pockethub.android.ui.view.OcticonTextView
import com.github.pockethub.android.util.AvatarLoader
import com.meisolsson.githubsdk.model.GitHubEvent
import com.meisolsson.githubsdk.model.payload.MemberPayload
import com.xwray.groupie.kotlinandroidextensions.ViewHolder
import kotlinx.android.synthetic.main.news_item.*

class MemberEventItem(
        avatarLoader: AvatarLoader,
        gitHubEvent: GitHubEvent
) : NewsItem(avatarLoader, gitHubEvent) {

    override fun bind(holder: ViewHolder, position: Int) {
        super.bind(holder, position)
        holder.tv_event_icon.text = OcticonTextView.ICON_ADD_MEMBER
        holder.tv_event.text = buildSpannedString {
            val context = holder.root.context
            val payload = gitHubEvent.payload() as MemberPayload?
            boldActor(context, this, gitHubEvent)
            append(" added ")
            boldUser(context, this, payload?.member())
            append(" as a collaborator to ")
            boldRepo(context, this, gitHubEvent)
        }
        holder.tv_event_details.visibility = View.GONE
    }
}


package org.amshove.kluent.tests.mocking

import org.amshove.kluent.*
import org.amshove.kluent.tests.helpclasses.Database
import kotlin.test.Test
import kotlin.test.assertFails

class VerifyCalledOnceShould {

    @Test
    fun passWhenAMethodWasCalledOnlyOnce() {
        val mock = mock(Database::class)
        mock.getPerson(1)
        mock.getPerson(1)
        Verify times 2 on mock that mock.getPerson(1) was called
        assertFails { Verify on mock that mock.getPerson(1) was called }
    }

    @Test
    fun failWhenAMethodWasNotCalled() {
        val mock = mock(Database::class)
        mock.getPerson(1)
        Verify on mock that mock.getPerson(1) was called
        assertFails { Verify times 1 on mock that mock.getPerson(5) was called }
    }

    @Test
    fun failWhenTimesThatAMethodWasCalledDoesNotMatch() {
        val mock = mock(Database::class)
        mock.getPerson(1)
        Verify on mock that mock.getPerson(1) was called
        assertFails { Verify times 2 on mock that mock.getPerson(1) was called }
    }
}

Add unit tests for times verification mode

package org.amshove.kluent.tests.mocking

import org.amshove.kluent.*
import org.amshove.kluent.tests.helpclasses.Database
import kotlin.test.Test
import kotlin.test.assertFails

class VerifyUsingTimesShould {

    @Test
    fun passWhenAMethodWasCalledSpecifiedTimes() {
        val mock = mock(Database::class)
        mock.getPerson(1)
        mock.getPerson(5)
        Verify on mock that mock.getPerson(1) was called
        Verify on mock that mock.getPerson(5) was called
        Verify times 2 on mock that mock.getPerson(any()) was called
    }

    @Test
    fun failWhenAMethodWasNotCalled() {
        val mock = mock(Database::class)
        mock.getPerson(1)
        Verify on mock that mock.getPerson(1) was called
        assertFails { Verify times 1 on mock that mock.getPerson(5) was called }
    }

    @Test
    fun failWhenAMethodWasCalledLessThanSpecified() {
        val mock = mock(Database::class)
        mock.getPerson(1)
        Verify on mock that mock.getPerson(1) was called
        assertFails { Verify times 2 on mock that mock.getPerson(any()) was called }
    }

    @Test
    fun failWhenAMethodWasCalledMoreThanSpecified() {
        val mock = mock(Database::class)
        mock.getPerson(1)
        mock.getPerson(5)
        Verify on mock that mock.getPerson(1) was called
        Verify on mock that mock.getPerson(5) was called
        assertFails { Verify times 1 on mock that mock.getPerson(any()) was called }
    }
}


package jetbrains.buildServer.agent

import jetbrains.buildServer.util.pathMatcher.AntPatternFileCollector
import java.io.File

class AntPathMatcher : PathMatcher {
    override fun match(path: File, includeRules: List<String>): List<File> =
            AntPatternFileCollector.scanDir(path, includeRules.toTypedArray(), emptyArray(),
                    AntPatternFileCollector.ScanOption.PRIORITIZE_EXCLUDES, AntPatternFileCollector.ScanOption.ALLOW_EXTERNAL_SCAN)

}

Revert "Fix compilation error after common library method change"

package jetbrains.buildServer.agent

import jetbrains.buildServer.util.pathMatcher.AntPatternFileCollector
import java.io.File

class AntPathMatcher : PathMatcher {
    override fun match(path: File, includeRules: List<String>): List<File> =
            AntPatternFileCollector.scanDir(path, includeRules.toTypedArray(), emptyArray(), ScanOptions)

    companion object {
        private val ScanOptions = arrayOf(
                AntPatternFileCollector.ScanOption.PRIORITIZE_EXCLUDES,
                AntPatternFileCollector.ScanOption.ALLOW_EXTERNAL_SCAN)
    }
}


Add Breakpoint set node for displaying if shared or not

package com.github.shiraji.breakpointsmanager.model

data class BreakpointsSetNode(val name: String, var isShared: Boolean) {
    override fun toString(): String {
        if (isShared) {
            return "[Shared] $name"
        } else {
            return name
        }
    }
}


package com.satsumasoftware.timetable.framework

import org.threeten.bp.LocalTime
import java.util.*

class ClassTimeGroup(val startTime: LocalTime, val endTime: LocalTime) {

    val classTimes = ArrayList<ClassTime>()

    fun addClassTime(classTime: ClassTime) {
        if (!classTime.startTime.equals(startTime) || !classTime.endTime.equals(endTime)) {
            throw IllegalArgumentException("invalid class time - the start and end times must" +
                    "match the ones specified from this object's constructor")
        }
        classTimes.add(classTime)
    }

    fun canAdd(classTime: ClassTime) =
            classTime.startTime.equals(startTime) && classTime.endTime.equals(endTime)

}

Replace .equals() with == in kotlin

package com.satsumasoftware.timetable.framework

import org.threeten.bp.LocalTime
import java.util.*

class ClassTimeGroup(val startTime: LocalTime, val endTime: LocalTime) {

    val classTimes = ArrayList<ClassTime>()

    fun addClassTime(classTime: ClassTime) {
        if (classTime.startTime != startTime || classTime.endTime != endTime) {
            throw IllegalArgumentException("invalid class time - the start and end times must" +
                    "match the ones specified from this object's constructor")
        }
        classTimes.add(classTime)
    }

    fun canAdd(classTime: ClassTime) =
            classTime.startTime == startTime && classTime.endTime == endTime

}


package engineer.carrot.warren.warren.ssl

import org.slf4j.Logger
import org.slf4j.LoggerFactory

import javax.net.ssl.X509TrustManager
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.security.cert.CertificateException
import java.security.cert.X509Certificate

internal class DangerZoneTrustAllX509TrustManager() : X509TrustManager {
    private val LOGGER = LoggerFactory.getLogger(DangerZoneTrustAllX509TrustManager::class.java)

    @Throws(CertificateException::class)
    override fun checkClientTrusted(x509Certificates: Array<X509Certificate>, s: String) {
        throw CertificateException("Forcible Trust Manager is not made to verify client certificates")
    }

    @Throws(CertificateException::class)
    override fun checkServerTrusted(x509Certificates: Array<X509Certificate>, s: String) {
        LOGGER.warn("DANGER ZONE: forcefully trusting all presented X509 certificates. This is not secure.")
    }

    override fun getAcceptedIssuers(): Array<X509Certificate> {
        return emptyArray()
    }
}

Clean up danger zone trust manager

package engineer.carrot.warren.warren.ssl

import engineer.carrot.warren.warren.loggerFor
import javax.net.ssl.X509TrustManager
import java.security.cert.CertificateException
import java.security.cert.X509Certificate

internal class DangerZoneTrustAllX509TrustManager() : X509TrustManager {
    private val LOGGER = loggerFor<DangerZoneTrustAllX509TrustManager>()

    @Throws(CertificateException::class)
    override fun checkClientTrusted(x509Certificates: Array<X509Certificate>, s: String) {
        throw CertificateException("Forcible Trust Manager is not made to verify client certificates")
    }

    @Throws(CertificateException::class)
    override fun checkServerTrusted(x509Certificates: Array<X509Certificate>, s: String) {
        LOGGER.warn("DANGER ZONE: forcefully trusting all presented X509 certificates. This is not secure.")
    }

    override fun getAcceptedIssuers(): Array<X509Certificate> {
        return emptyArray()
    }
}


package nl.hannahsten.texifyidea.inspections.latex

import nl.hannahsten.texifyidea.inspections.TexifyInspectionTestBase

class LatexAvoidEqnarrayInspectionTest : TexifyInspectionTestBase(LatexAvoidEqnarrayInspection()) {
    fun `test eqnarray warning`() = testHighlighting("""
        \begin{<warning descr="Avoid using the 'eqnarray' environment">eqnarray</warning>}
            x
        \end{eqnarray}
    """.trimIndent())

    fun `test eqnarray* warning`() = testHighlighting("""
        \begin{<warning descr="Avoid using the 'eqnarray*' environment">eqnarray*</warning>}
            x
        \end{eqnarray*}
    """.trimIndent())

    fun `test no warning for other math environment`() = testHighlighting("""
        \begin{align}
            x
        \end{align}
    """.trimIndent())

    fun `test quick fix`() = testQuickFix(
            before = """
                \usepackage{amsmath}
                \begin{eqnarray*}
                    x
                \end{eqnarray*}
            """.trimIndent(),
            after = """
                \usepackage{amsmath}
                \begin{align*}
                    x
                \end{align*}
            """.trimIndent()
    )
}


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

package org.gradle.gradlebuild

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.*
import org.gradle.plugins.performance.determineCurrentBranch

/**
 * When a Ready for Nightly trigger build completes successfully on master/release, we publish a git tag
 * green-master/green-release to remote repository so that developers can checkout new branches from these tags.
 */
open class UpdateBranchStatus : DefaultTask() {
    @TaskAction
    fun publishBranchStatus() {
        when (project.determineCurrentBranch()) {
            "master" -> publishBranchStatus("master")
            "release" -> publishBranchStatus("release")
        }
    }

    private
    fun publishBranchStatus(branch: String) {
        project.execAndGetStdout("git", "tag", "-f", "green-$branch")
        project.execAndGetStdout("git", "push", "-f", "origin", "green-$branch")
    }
}

Use branch instead of tag for green branch

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

package org.gradle.gradlebuild

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.*
import org.gradle.plugins.performance.determineCurrentBranch

/**
 * When a Ready for Nightly trigger build completes successfully on master/release, we publish a git tag
 * green-master/green-release to remote repository so that developers can checkout new branches from these tags.
 */
open class UpdateBranchStatus : DefaultTask() {
    @TaskAction
    fun publishBranchStatus() {
        when (project.determineCurrentBranch()) {
            "master" -> publishBranchStatus("master")
            "release" -> publishBranchStatus("release")
        }
    }

    private
    fun publishBranchStatus(branch: String) {
        project.execAndGetStdout("git", "push", "origin", "$branch:green-$branch")
    }
}


package org.runestar.client.plugins.std.debug

import org.kxtra.swing.graphics2d.drawString
import org.runestar.client.game.api.live.LiveCanvas
import org.runestar.client.game.api.live.Players
import org.runestar.client.plugins.PluginSettings
import org.runestar.client.utils.ColorForm
import org.runestar.client.utils.DisposablePlugin
import org.runestar.client.utils.FontForm
import java.awt.Font

class HeadIconDebug : DisposablePlugin<HeadIconDebug.Settings>() {

    override val defaultSettings = Settings()

    override fun start() {
        super.start()

        add(LiveCanvas.repaints.subscribe { g ->
            g.font = settings.font.get()
            g.color = settings.color.get()

            Players.all.forEach { p ->
                val pos = p.position.copy(height = 0)
                if (!pos.isLoaded) return@forEach
                val pt = pos.toScreen() ?: return@forEach
                val string = "${p.headIconPk},${p.headIconPrayer}"
                g.drawString(string, pt)
            }
        })
    }

    class Settings : PluginSettings() {
        val font = FontForm(Font.SANS_SERIF, FontForm.BOLD, 15f)
        val color = ColorForm()
    }
}


Implement parsing of module-less bindings

/*
 * Copyright 2020 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.analysis

import io.michaelrocks.grip.Grip
import io.michaelrocks.grip.annotatedWith
import io.michaelrocks.grip.classes
import io.michaelrocks.grip.mirrors.ClassMirror
import io.michaelrocks.grip.mirrors.Type
import io.michaelrocks.grip.mirrors.signature.GenericType
import io.michaelrocks.lightsaber.processor.ErrorReporter
import io.michaelrocks.lightsaber.processor.commons.Types
import io.michaelrocks.lightsaber.processor.model.Binding
import io.michaelrocks.lightsaber.processor.model.Dependency
import java.io.File

interface BindingsAnalyzer {
  fun analyze(files: Collection<File>): BindingRegistry
}

class BindingsAnalyzerImpl(
  private val grip: Grip,
  private val analyzerHelper: AnalyzerHelper,
  private val errorReporter: ErrorReporter
) : BindingsAnalyzer {

  override fun analyze(files: Collection<File>): BindingRegistry {
    val bindingRegistry = BindingRegistryImpl()
    val bindingsQuery = grip select classes from files where annotatedWith(Types.PROVIDED_AS_TYPE)
    bindingsQuery.execute().classes.forEach { mirror ->
      createBindingForClass(mirror)?.also { binding ->
        bindingRegistry.registerBinding(binding)
      }
    }

    return bindingRegistry
  }

  private fun createBindingForClass(mirror: ClassMirror): Binding? {
    val ancestorType = extractAncestorTypeFromClass(mirror) ?: return null
    val dependency = Dependency(GenericType.Raw(mirror.type))
    val qualifier = analyzerHelper.findQualifier(mirror)
    val ancestor = Dependency(GenericType.Raw(ancestorType), qualifier)
    return Binding(dependency, ancestor)
  }

  private fun extractAncestorTypeFromClass(mirror: ClassMirror): Type.Object? {
    val providedAs = mirror.annotations[Types.PROVIDED_AS_TYPE] ?: return null

    @Suppress("UNCHECKED_CAST")
    val ancestorType = providedAs.values["value"] as Type? ?: return null
    if (ancestorType !is Type.Object) {
      error("Class ${mirror.type.className} has invalid type in its @ProvidedAs annotation: ${ancestorType.className}")
      return null
    }

    return ancestorType
  }

  private fun error(message: String) {
    errorReporter.reportError(message)
  }
}


Add a little program that generates the class code for the _SelectN classes.

/*
 * Copyright (c) 2016.
 *
 * This file is part of ProcessManager.
 *
 * This file is licenced to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You should have received a copy of the license with the source distribution.
 * Alternatively, 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.
 */

/**
 * Created by pdvrieze on 04/04/16.
 */

package gen

const val count=10

fun main(args:Array<String>) {
  for(n in 2..count) {
    println()
    print("class _Select$n<")
    for (m in 1..count) {
      print("\n        T$m:Any, S$m:IColumnType<T$m,S$m,C$m>, C$m: Column<T$m, S$m, C$m>")
      if (m<count) {print(',') }
    }
    print(">(")
    print((1..count).joinToString { m -> "col$m: C$m" })
    print("):\n      _BaseSelect(")
    print((1..count).joinToString { m -> "col$m" })
    println("){")
    println("    override fun WHERE(config: _Where.() -> WhereClause: Statement =")
    println("        _Statement$n(this, _Where().config())")

  }
}


package org.runestar.client.plugins.std.debug

import com.google.common.base.Splitter
import org.kxtra.slf4j.logger.info
import org.runestar.client.game.api.live.LiveCanvas
import org.runestar.client.game.raw.Client
import org.runestar.client.plugins.PluginSettings
import org.runestar.client.utils.DisposablePlugin

class VarpsChangeDebug : DisposablePlugin<PluginSettings>() {

    override val defaultSettings = PluginSettings()

    val varps = Client.accessor.varps

    @Volatile
    var old = varps.copyOf()

    override fun start() {
        super.start()

        add(LiveCanvas.repaints.subscribe { g ->
            val curr = varps.copyOf()
            for (i in old.indices) {
                val o = old[i]
                val c = curr[i]
                if (o != c) {
                    val changedBits = Integer.toBinaryString(o xor c).padStart(Integer.SIZE, '0')
                    val lastBitChanged = Integer.SIZE - changedBits.lastIndexOf('1') - 1
                    val firstBitChanged = Integer.SIZE - changedBits.indexOf('1') - 1

                    logger.info { "$i: $firstBitChanged - $lastBitChanged\n" +
                            "${intToString(o)} ->\n" +
                            "${intToString(c)}" }
                }
            }

            old = curr
        })
    }

    val splitter8 = Splitter.fixedLength(8)

    fun intToString(n: Int): String {
        val b = Integer.toBinaryString(n).padStart(Integer.SIZE, '0')
        return splitter8.splitToList(b).joinToString("'")
    }
}