interface IrType {

}

interface TypeRemapper {
  abstract fun enterScope(irTypeParametersContainer: IrTypeParametersContainer)
  abstract fun remapType(type: IrType): IrType
  abstract fun leaveScope()

}

interface IrTypeParametersContainer : IrDeclaration, IrDeclarationParent {
  abstract var typeParameters: List<IrTypeParameter>
    abstract get
    abstract set

}

interface IrDeclaration {

}

interface IrTypeParameter : IrDeclaration {
  abstract val superTypes: MutableList<IrType>
    abstract get

}

interface IrDeclarationParent {

}

class DeepCopyIrTreeWithSymbols {
  constructor(typeRemapper: TypeRemapper) /* primary */ {
    super/*Any*/()
    /* <init>() */

  }

  private val typeRemapper: TypeRemapper
    field = typeRemapper
    private get

  private fun copyTypeParameter(declaration: IrTypeParameter): IrTypeParameter {
    return declaration
  }

  fun IrTypeParametersContainer.copyTypeParametersFrom(other: IrTypeParametersContainer) {
    <this>.<set-typeParameters>(<set-?> = other.<get-typeParameters>().map<IrTypeParameter, IrTypeParameter>(transform = local fun <anonymous>(it: IrTypeParameter): IrTypeParameter {
      return <this>.copyTypeParameter(declaration = it)
    }
))
    <this>.<get-typeRemapper>().withinScope<Unit>(irTypeParametersContainer = <this>, fn = local fun <anonymous>() {
      { // BLOCK
        val <iterator>: Iterator<Pair<IrTypeParameter, IrTypeParameter>> = <this>.<get-typeParameters>().zip<IrTypeParameter, IrTypeParameter>(other = other.<get-typeParameters>()).iterator()
        while (<iterator>.hasNext()) { // BLOCK
          val <destruct>: Pair<IrTypeParameter, IrTypeParameter> = <iterator>.next()
          val thisTypeParameter: IrTypeParameter = <destruct>.component1()
          val otherTypeParameter: IrTypeParameter = <destruct>.component2()
          otherTypeParameter.<get-superTypes>().mapTo<IrType, IrType, MutableList<IrType>>(destination = thisTypeParameter.<get-superTypes>(), transform = local fun <anonymous>(it: IrType): IrType {
            return <this>.<get-typeRemapper>().remapType(type = it)
          }
)
        }
      }
    }
)
  }

}

inline fun <T : Any?> TypeRemapper.withinScope(irTypeParametersContainer: IrTypeParametersContainer, fn: Function0<T>): T {
  <this>.enterScope(irTypeParametersContainer = irTypeParametersContainer)
  val result: T = fn.invoke()
  <this>.leaveScope()
  return result
}

