class DeepCopyIrTreeWithSymbols {
  private val typeRemapper: TypeRemapper
    field = typeRemapper
    private get

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

  }

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

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

}

interface IrDeclaration {
}

interface IrDeclarationParent {
}

interface IrType {
}

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

}

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

}

interface TypeRemapper {
  abstract fun enterScope(irTypeParametersContainer: IrTypeParametersContainer)

  abstract fun leaveScope()

  abstract fun remapType(type: IrType): IrType

}

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
}

