Repository: 7mind/izumi
Pull request #777 (2019-12-07 23:56:27)

Move old testkit to distage-legacy-testkit
* move docker support to distage-docker
* restore distage-framework-api


Patch:
diff --git a/build.sbt b/build.sbt
index 54584a477..b7a07b5d2 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1040,12 +1040,96 @@ lazy val `distage-plugins` = project.in(file("distage/distage-plugins"))
   )
   .disablePlugins(AssemblyPlugin)
 
+lazy val `distage-framework-api` = project.in(file("distage/distage-framework-api"))
+  .dependsOn(
+    `distage-model` % "test->compile;compile->compile"
+  )
+  .settings(
+    libraryDependencies ++= Seq(
+      compilerPlugin("org.typelevel" % "kind-projector" % V.kind_projector cross CrossVersion.full),
+      "org.scala-lang.modules" %% "scala-collection-compat" % V.collection_compat,
+      "org.scalatest" %% "scalatest" % V.scalatest % Test
+    )
+  )
+  .settings(
+    organization := "io.7mind.izumi",
+    unmanagedSourceDirectories in Compile += baseDirectory.value / ".jvm/src/main/scala" ,
+    unmanagedResourceDirectories in Compile += baseDirectory.value / ".jvm/src/main/resources" ,
+    unmanagedSourceDirectories in Test += baseDirectory.value / ".jvm/src/test/scala" ,
+    unmanagedResourceDirectories in Test += baseDirectory.value / ".jvm/src/test/resources" ,
+    scalacOptions ++= Seq(
+      s"-Xmacro-settings:scala-version=${scalaVersion.value}",
+      s"-Xmacro-settings:scala-versions=${crossScalaVersions.value.mkString(":")}"
+    ),
+    testOptions in Test += Tests.Argument("-oDF"),
+    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {
+      case (_, "2.12.10") => Seq(
+        "-Xsource:2.13",
+        "-Ypartial-unification",
+        "-Yno-adapted-args",
+        "-Xlint:adapted-args",
+        "-Xlint:by-name-right-associative",
+        "-Xlint:constant",
+        "-Xlint:delayedinit-select",
+        "-Xlint:doc-detached",
+        "-Xlint:inaccessible",
+        "-Xlint:infer-any",
+        "-Xlint:missing-interpolator",
+        "-Xlint:nullary-override",
+        "-Xlint:nullary-unit",
+        "-Xlint:option-implicit",
+        "-Xlint:package-object-classes",
+        "-Xlint:poly-implicit-overload",
+        "-Xlint:private-shadow",
+        "-Xlint:stars-align",
+        "-Xlint:type-parameter-shadow",
+        "-Xlint:unsound-match",
+        "-opt-warnings:_",
+        "-Ywarn-extra-implicit",
+        "-Ywarn-unused:_",
+        "-Ywarn-adapted-args",
+        "-Ywarn-dead-code",
+        "-Ywarn-inaccessible",
+        "-Ywarn-infer-any",
+        "-Ywarn-nullary-override",
+        "-Ywarn-nullary-unit",
+        "-Ywarn-numeric-widen",
+        "-Ywarn-unused-import",
+        "-Ywarn-value-discard"
+      )
+      case (_, "2.13.1") => Seq(
+        "-Xlint:_,-eta-sam",
+        "-Wdead-code",
+        "-Wextra-implicit",
+        "-Wnumeric-widen",
+        "-Woctal-literal",
+        "-Wunused:_",
+        "-Wvalue-discard"
+      )
+      case (_, _) => Seq.empty
+    } },
+    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {
+      case (false, _) => Seq(
+        "-opt:l:inline",
+        "-opt-inline-from:izumi.**"
+      )
+      case (_, _) => Seq.empty
+    } },
+    scalaVersion := crossScalaVersions.value.head,
+    crossScalaVersions := Seq(
+      "2.12.10",
+      "2.13.1"
+    )
+  )
+  .disablePlugins(AssemblyPlugin)
+
 lazy val `distage-framework` = project.in(file("distage/distage-framework"))
   .dependsOn(
     `logstage-di` % "test->compile;compile->compile",
     `logstage-adapter-slf4j` % "test->compile;compile->compile",
     `logstage-rendering-circe` % "test->compile;compile->compile",
     `distage-core` % "test->test;compile->compile",
+    `distage-framework-api` % "test->test;compile->compile",
     `distage-plugins` % "test->test;compile->compile",
     `distage-config` % "test->test;compile->compile"
   )
@@ -1057,7 +1141,6 @@ lazy val `distage-framework` = project.in(file("distage/distage-framework"))
       "org.typelevel" %% "cats-core" % V.cats % Optional,
       "org.typelevel" %% "cats-effect" % V.cats_effect % Optional,
       "dev.zio" %% "zio" % V.zio % Optional,
-      "com.github.docker-java" % "docker-java" % V.docker_java,
       "org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided
     )
   )
@@ -1133,6 +1216,94 @@ lazy val `distage-framework` = project.in(file("distage/distage-framework"))
   )
   .disablePlugins(AssemblyPlugin)
 
+lazy val `distage-docker` = project.in(file("distage/distage-docker"))
+  .dependsOn(
+    `distage-core` % "test->compile;compile->compile",
+    `distage-config` % "test->compile;compile->compile",
+    `distage-framework-api` % "test->compile;compile->compile",
+    `logstage-di` % "test->compile;compile->compile",
+    `distage-testkit` % "test->compile"
+  )
+  .settings(
+    libraryDependencies ++= Seq(
+      compilerPlugin("org.typelevel" % "kind-projector" % V.kind_projector cross CrossVersion.full),
+      "org.scala-lang.modules" %% "scala-collection-compat" % V.collection_compat,
+      "org.scalatest" %% "scalatest" % V.scalatest % Test,
+      "com.github.docker-java" % "docker-java" % V.docker_java
+    )
+  )
+  .settings(
+    organization := "io.7mind.izumi",
+    unmanagedSourceDirectories in Compile += baseDirectory.value / ".jvm/src/main/scala" ,
+    unmanagedResourceDirectories in Compile += baseDirectory.value / ".jvm/src/main/resources" ,
+    unmanagedSourceDirectories in Test += baseDirectory.value / ".jvm/src/test/scala" ,
+    unmanagedResourceDirectories in Test += baseDirectory.value / ".jvm/src/test/resources" ,
+    scalacOptions ++= Seq(
+      s"-Xmacro-settings:scala-version=${scalaVersion.value}",
+      s"-Xmacro-settings:scala-versions=${crossScalaVersions.value.mkString(":")}"
+    ),
+    testOptions in Test += Tests.Argument("-oDF"),
+    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {
+      case (_, "2.12.10") => Seq(
+        "-Xsource:2.13",
+        "-Ypartial-unification",
+        "-Yno-adapted-args",
+        "-Xlint:adapted-args",
+        "-Xlint:by-name-right-associative",
+        "-Xlint:constant",
+        "-Xlint:delayedinit-select",
+        "-Xlint:doc-detached",
+        "-Xlint:inaccessible",
+        "-Xlint:infer-any",
+        "-Xlint:missing-interpolator",
+        "-Xlint:nullary-override",
+        "-Xlint:nullary-unit",
+        "-Xlint:option-implicit",
+        "-Xlint:package-object-classes",
+        "-Xlint:poly-implicit-overload",
+        "-Xlint:private-shadow",
+        "-Xlint:stars-align",
+        "-Xlint:type-parameter-shadow",
+        "-Xlint:unsound-match",
+        "-opt-warnings:_",
+        "-Ywarn-extra-implicit",
+        "-Ywarn-unused:_",
+        "-Ywarn-adapted-args",
+        "-Ywarn-dead-code",
+        "-Ywarn-inaccessible",
+        "-Ywarn-infer-any",
+        "-Ywarn-nullary-override",
+        "-Ywarn-nullary-unit",
+        "-Ywarn-numeric-widen",
+        "-Ywarn-unused-import",
+        "-Ywarn-value-discard"
+      )
+      case (_, "2.13.1") => Seq(
+        "-Xlint:_,-eta-sam",
+        "-Wdead-code",
+        "-Wextra-implicit",
+        "-Wnumeric-widen",
+        "-Woctal-literal",
+        "-Wunused:_",
+        "-Wvalue-discard"
+      )
+      case (_, _) => Seq.empty
+    } },
+    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {
+      case (false, _) => Seq(
+        "-opt:l:inline",
+        "-opt-inline-from:izumi.**"
+      )
+      case (_, _) => Seq.empty
+    } },
+    scalaVersion := crossScalaVersions.value.head,
+    crossScalaVersions := Seq(
+      "2.12.10",
+      "2.13.1"
+    )
+  )
+  .disablePlugins(AssemblyPlugin)
+
 lazy val `distage-testkit` = project.in(file("distage/distage-testkit"))
   .dependsOn(
     `distage-config` % "test->compile;compile->compile",
@@ -1146,10 +1317,102 @@ lazy val `distage-testkit` = project.in(file("distage/distage-testkit"))
       compilerPlugin("org.typelevel" % "kind-projector" % V.kind_projector cross CrossVersion.full),
       "org.scala-lang.modules" %% "scala-collection-compat" % V.collection_compat,
       "org.scalatest" %% "scalatest" % V.scalatest % Test,
-      "org.scalatest" %% "scalatest" % V.scalatest,
       "org.typelevel" %% "cats-core" % V.cats % Optional,
       "org.typelevel" %% "cats-effect" % V.cats_effect % Optional,
-      "dev.zio" %% "zio" % V.zio % Optional
+      "dev.zio" %% "zio" % V.zio % Optional,
+      "org.scalatest" %% "scalatest" % V.scalatest
+    )
+  )
+  .settings(
+    organization := "io.7mind.izumi",
+    unmanagedSourceDirectories in Compile += baseDirectory.value / ".jvm/src/main/scala" ,
+    unmanagedResourceDirectories in Compile += baseDirectory.value / ".jvm/src/main/resources" ,
+    unmanagedSourceDirectories in Test += baseDirectory.value / ".jvm/src/test/scala" ,
+    unmanagedResourceDirectories in Test += baseDirectory.value / ".jvm/src/test/resources" ,
+    classLoaderLayeringStrategy in Test := ClassLoaderLayeringStrategy.Flat,
+    scalacOptions ++= Seq(
+      s"-Xmacro-settings:scala-version=${scalaVersion.value}",
+      s"-Xmacro-settings:scala-versions=${crossScalaVersions.value.mkString(":")}"
+    ),
+    testOptions in Test += Tests.Argument("-oDF"),
+    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {
+      case (_, "2.12.10") => Seq(
+        "-Xsource:2.13",
+        "-Ypartial-unification",
+        "-Yno-adapted-args",
+        "-Xlint:adapted-args",
+        "-Xlint:by-name-right-associative",
+        "-Xlint:constant",
+        "-Xlint:delayedinit-select",
+        "-Xlint:doc-detached",
+        "-Xlint:inaccessible",
+        "-Xlint:infer-any",
+        "-Xlint:missing-interpolator",
+        "-Xlint:nullary-override",
+        "-Xlint:nullary-unit",
+        "-Xlint:option-implicit",
+        "-Xlint:package-object-classes",
+        "-Xlint:poly-implicit-overload",
+        "-Xlint:private-shadow",
+        "-Xlint:stars-align",
+        "-Xlint:type-parameter-shadow",
+        "-Xlint:unsound-match",
+        "-opt-warnings:_",
+        "-Ywarn-extra-implicit",
+        "-Ywarn-unused:_",
+        "-Ywarn-adapted-args",
+        "-Ywarn-dead-code",
+        "-Ywarn-inaccessible",
+        "-Ywarn-infer-any",
+        "-Ywarn-nullary-override",
+        "-Ywarn-nullary-unit",
+        "-Ywarn-numeric-widen",
+        "-Ywarn-unused-import",
+        "-Ywarn-value-discard"
+      )
+      case (_, "2.13.1") => Seq(
+        "-Xlint:_,-eta-sam",
+        "-Wdead-code",
+        "-Wextra-implicit",
+        "-Wnumeric-widen",
+        "-Woctal-literal",
+        "-Wunused:_",
+        "-Wvalue-discard"
+      )
+      case (_, _) => Seq.empty
+    } },
+    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {
+      case (false, _) => Seq(
+        "-opt:l:inline",
+        "-opt-inline-from:izumi.**"
+      )
+      case (_, _) => Seq.empty
+    } },
+    scalaVersion := crossScalaVersions.value.head,
+    crossScalaVersions := Seq(
+      "2.12.10",
+      "2.13.1"
+    )
+  )
+  .disablePlugins(AssemblyPlugin)
+
+lazy val `distage-legacy-testkit` = project.in(file("distage/distage-legacy-testkit"))
+  .dependsOn(
+    `distage-config` % "test->compile;compile->compile",
+    `distage-framework` % "test->compile;compile->compile",
+    `logstage-di` % "test->compile;compile->compile",
+    `distage-core` % "test->compile;compile->compile",
+    `distage-testkit` % "test->compile;compile->compile"
+  )
+  .settings(
+    libraryDependencies ++= Seq(
+      compilerPlugin("org.typelevel" % "kind-projector" % V.kind_projector cross CrossVersion.full),
+      "org.scala-lang.modules" %% "scala-collection-compat" % V.collection_compat,
+      "org.scalatest" %% "scalatest" % V.scalatest % Test,
+      "org.typelevel" %% "cats-core" % V.cats % Optional,
+      "org.typelevel" %% "cats-effect" % V.cats_effect % Optional,
+      "dev.zio" %% "zio" % V.zio % Optional,
+      "org.scalatest" %% "scalatest" % V.scalatest
     )
   )
   .settings(
@@ -2624,8 +2887,11 @@ lazy val `microsite` = project.in(file("doc/microsite"))
     `distage-core` % "test->compile;compile->compile",
     `distage-config` % "test->compile;compile->compile",
     `distage-plugins` % "test->compile;compile->compile",
+    `distage-framework-api` % "test->compile;compile->compile",
     `distage-framework` % "test->compile;compile->compile",
+    `distage-docker` % "test->compile;compile->compile",
     `distage-testkit` % "test->compile;compile->compile",
+    `distage-legacy-testkit` % "test->compile;compile->compile",
     `logstage-api` % "test->compile;compile->compile",
     `logstage-core` % "test->compile;compile->compile",
     `logstage-rendering-circe` % "test->compile;compile->compile",
@@ -2907,8 +3173,11 @@ lazy val `distage` = (project in file(".agg/distage-distage"))
     `distage-core`,
     `distage-config`,
     `distage-plugins`,
+    `distage-framework-api`,
     `distage-framework`,
-    `distage-testkit`
+    `distage-docker`,
+    `distage-testkit`,
+    `distage-legacy-testkit`
   )
 
 lazy val `distage-jvm` = (project in file(".agg/distage-distage-jvm"))
@@ -2927,8 +3196,11 @@ lazy val `distage-jvm` = (project in file(".agg/distage-distage-jvm"))
     `distage-core`,
     `distage-config`,
     `distage-plugins`,
+    `distage-framework-api`,
     `distage-framework`,
-    `distage-testkit`
+    `distage-docker`,
+    `distage-testkit`,
+    `distage-legacy-testkit`
   )
 
 lazy val `logstage` = (project in file(".agg/logstage-logstage"))
diff --git a/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapPlanningObserver.scala b/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapPlanningObserver.scala
index f093fd24f..a8b451c7f 100644
--- a/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapPlanningObserver.scala
+++ b/distage/distage-core/src/main/scala/izumi/distage/bootstrap/BootstrapPlanningObserver.scala
@@ -10,21 +10,10 @@ class BootstrapPlanningObserver(logger: TrivialLogger) extends PlanningObserver
     doLog("Next Plan", next.toString)
   }
 
-  override def onPhase00PlanCompleted(plan: PrePlan): Unit = {
-
-  }
-
-  override def onPhase05PreGC(plan: SemiPlan): Unit = {
-
-  }
-
-  override def onPhase10PostGC(plan: SemiPlan): Unit = {
-
-  }
-
-  override def onPhase20Customization(plan: SemiPlan): Unit = {
-
-  }
+  override def onPhase00PlanCompleted(plan: PrePlan): Unit = {}
+  override def onPhase05PreGC(plan: SemiPlan): Unit = {}
+  override def onPhase10PostGC(plan: SemiPlan): Unit = {}
+  override def onPhase20Customization(plan: SemiPlan): Unit = {}
 
   override def onPhase50PreForwarding(finalPlan: SemiPlan): Unit = {
     doLog("Resolved Plan", finalPlan.toString)
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/ContainerHealthCheck.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/ContainerHealthCheck.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/ContainerHealthCheck.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/ContainerHealthCheck.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/Docker.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/Docker.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/Docker.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/Docker.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/DockerCmdExecFactoryResource.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/DockerCmdExecFactoryResource.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/DockerCmdExecFactoryResource.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/DockerCmdExecFactoryResource.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/DockerContainer.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/DockerContainer.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/DockerContainer.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/DockerContainer.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/examples/DynamoDocker.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/examples/DynamoDocker.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/examples/DynamoDocker.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/examples/DynamoDocker.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/examples/PostgresDocker.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/examples/PostgresDocker.scala
similarity index 79%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/examples/PostgresDocker.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/examples/PostgresDocker.scala
index 657a8525f..f43b177b5 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/docker/examples/PostgresDocker.scala
+++ b/distage/distage-docker/src/main/scala/izumi/distage/docker/examples/PostgresDocker.scala
@@ -1,9 +1,9 @@
 package izumi.distage.docker.examples
 
-import izumi.distage.model.definition.ModuleDef
 import izumi.distage.docker.ContainerDef
 import izumi.distage.docker.Docker.{ContainerConfig, DockerPort}
-import zio.Task
+import izumi.distage.model.definition.ModuleDef
+import izumi.fundamentals.reflection.Tags.TagK
 
 object PostgresDocker extends ContainerDef {
   val primaryPort: DockerPort = DockerPort.TCP(5432)
@@ -17,8 +17,8 @@ object PostgresDocker extends ContainerDef {
   }
 }
 
-class PostgresDockerModule extends ModuleDef {
+class PostgresDockerModule[F[_]: TagK] extends ModuleDef {
   make[PostgresDocker.Container].fromResource {
-    PostgresDocker.make[Task]
+    PostgresDocker.make[F]
   }
 }
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/docker/modules/DockerContainerModule.scala b/distage/distage-docker/src/main/scala/izumi/distage/docker/modules/DockerContainerModule.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/docker/modules/DockerContainerModule.scala
rename to distage/distage-docker/src/main/scala/izumi/distage/docker/modules/DockerContainerModule.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/docker/DistageTestDockerBIO.scala b/distage/distage-docker/src/test/scala/izumi/distage/testkit/docker/DistageTestDockerBIO.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/docker/DistageTestDockerBIO.scala
rename to distage/distage-docker/src/test/scala/izumi/distage/testkit/docker/DistageTestDockerBIO.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala b/distage/distage-docker/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala
rename to distage/distage-docker/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala
diff --git a/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/ActivationInfo.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/ActivationInfo.scala
new file mode 100644
index 000000000..6c33d32b7
--- /dev/null
+++ b/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/ActivationInfo.scala
@@ -0,0 +1,6 @@
+package izumi.distage.framework.model
+
+import izumi.distage.model.definition.Axis
+import izumi.distage.model.definition.Axis.AxisValue
+
+final case class ActivationInfo(availableChoices: Map[Axis, Set[AxisValue]]) extends AnyVal
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/model/AbstractRole.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/AbstractRole.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/model/AbstractRole.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/AbstractRole.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/model/RoleDescriptor.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/RoleDescriptor.scala
similarity index 100%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/model/RoleDescriptor.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/RoleDescriptor.scala
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/model/DIAppBootstrapException.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/exceptions/DIAppBootstrapException.scala
similarity index 74%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/model/DIAppBootstrapException.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/exceptions/DIAppBootstrapException.scala
index 2d58d213a..4249fccec 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/model/DIAppBootstrapException.scala
+++ b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/exceptions/DIAppBootstrapException.scala
@@ -1,4 +1,4 @@
-package izumi.distage.roles.model
+package izumi.distage.roles.model.exceptions
 
 import izumi.distage.model.exceptions.DIException
 
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/LibraryReference.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/LibraryReference.scala
similarity index 65%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/meta/LibraryReference.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/LibraryReference.scala
index ce1ebe39a..1b313895e 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/LibraryReference.scala
+++ b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/LibraryReference.scala
@@ -1,3 +1,3 @@
-package izumi.distage.roles.meta
+package izumi.distage.roles.model.meta
 
 final case class LibraryReference(libraryName: String, clazz: Class[_])
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RoleArtifact.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RoleArtifact.scala
similarity index 61%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RoleArtifact.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RoleArtifact.scala
index 30f3e392d..6bbbff55d 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RoleArtifact.scala
+++ b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RoleArtifact.scala
@@ -1,3 +1,3 @@
-package izumi.distage.roles.meta
+package izumi.distage.roles.model.meta
 
 final case class RoleArtifact(name: String, version: String)
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RoleBinding.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RoleBinding.scala
similarity index 93%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RoleBinding.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RoleBinding.scala
index 4aa95096b..885fe9086 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RoleBinding.scala
+++ b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RoleBinding.scala
@@ -1,4 +1,4 @@
-package izumi.distage.roles.meta
+package izumi.distage.roles.model.meta
 
 import izumi.distage.model.definition.Binding
 import izumi.distage.model.reflection.universe.RuntimeDIUniverse._
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RolesInfo.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RolesInfo.scala
similarity index 92%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RolesInfo.scala
rename to distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RolesInfo.scala
index e27b9bc0d..158a6b780 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/meta/RolesInfo.scala
+++ b/distage/distage-framework-api/src/main/scala/izumi/distage/roles/model/meta/RolesInfo.scala
@@ -1,4 +1,4 @@
-package izumi.distage.roles.meta
+package izumi.distage.roles.model.meta
 
 import izumi.distage.model.reflection.universe.RuntimeDIUniverse.DIKey
 
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/model/ActivationInfo.scala b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ActivationInfoExtractor.scala
similarity index 85%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/model/ActivationInfo.scala
rename to distage/distage-framework/src/main/scala/izumi/distage/framework/services/ActivationInfoExtractor.scala
index 4194bf4b3..5c9d14d4b 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/model/ActivationInfo.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ActivationInfoExtractor.scala
@@ -1,14 +1,13 @@
-package izumi.distage.roles.model
+package izumi.distage.framework.services
 
 import distage.ModuleBase
-import izumi.distage.model.definition.Axis.AxisValue
+import izumi.distage.framework.model.ActivationInfo
 import izumi.distage.model.definition.{Axis, BindingTag}
+import izumi.distage.roles.model.exceptions.DIAppBootstrapException
 import izumi.fundamentals.platform.strings.IzString._
 import izumi.logstage.api.IzLogger
 
-final case class ActivationInfo(availableChoices: Map[Axis, Set[AxisValue]]) extends AnyVal
-
-object ActivationInfo {
+object ActivationInfoExtractor {
   def findAvailableChoices(logger: IzLogger, module: ModuleBase): ActivationInfo = {
     findAvailableChoices(module) match {
       case Left(badAxis) =>
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala
index dfc4ec16c..7b5fc0661 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala
@@ -7,7 +7,7 @@ import izumi.distage.model.Locator
 import izumi.distage.model.effect.DIEffect.syntax._
 import izumi.distage.model.effect.{DIEffect, DIEffectAsync}
 import izumi.distage.model.exceptions.DIException
-import izumi.distage.roles.model.DIAppBootstrapException
+import izumi.distage.roles.model.exceptions.DIAppBootstrapException
 import izumi.fundamentals.platform.integration.ResourceCheck
 import izumi.fundamentals.platform.strings.IzString._
 import izumi.logstage.api.IzLogger
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala
index 7e82a21a7..437b98020 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/ModuleProvider.scala
@@ -6,13 +6,14 @@ import izumi.distage.config.model.AppConfig
 import izumi.distage.effect.modules.IdentityDIEffectModule
 import izumi.distage.framework.activation.PruningPlanMergingPolicy
 import izumi.distage.framework.config.PlanningOptions
+import izumi.distage.framework.model.ActivationInfo
 import izumi.distage.framework.services.ResourceRewriter.RewriteRules
 import izumi.distage.model.definition.{Activation, BootstrapModuleDef, Module}
 import izumi.distage.model.planning.{PlanMergingPolicy, PlanningHook}
 import izumi.distage.planning.AutoSetModule
 import izumi.distage.planning.extensions.GraphDumpBootstrapModule
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.{AbstractRole, ActivationInfo}
+import izumi.distage.roles.model.meta.RolesInfo
+import izumi.distage.roles.model.AbstractRole
 import izumi.fundamentals.platform.cli.model.raw.RawAppArgs
 import izumi.logstage.api.IzLogger
 import izumi.logstage.distage.LogstageModule
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppLauncherImpl.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppLauncherImpl.scala
index b5d71b32b..3c4c07b0d 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppLauncherImpl.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/RoleAppLauncherImpl.scala
@@ -3,7 +3,7 @@ package izumi.distage.roles
 import distage._
 import izumi.distage.config.model.AppConfig
 import izumi.distage.framework.config.PlanningOptions
-import izumi.distage.framework.model.{AllLoadedPlugins, PluginSource}
+import izumi.distage.framework.model.{ActivationInfo, AllLoadedPlugins, PluginSource}
 import izumi.distage.framework.services.ResourceRewriter.RewriteRules
 import izumi.distage.framework.services.{ConfigLoader, IntegrationChecker, ModuleProvider, RoleAppPlanner}
 import izumi.distage.model.definition.{Activation, Axis}
@@ -12,8 +12,8 @@ import izumi.distage.model.definition.StandardAxis.{Env, ExternalApi, Repo}
 import izumi.distage.model.effect.DIEffect
 import izumi.distage.plugins.merge.{PluginMergeStrategy, SimplePluginMergeStrategy}
 import izumi.distage.roles.RoleAppLauncher.Options
-import izumi.distage.roles.meta.{LibraryReference, RolesInfo}
-import izumi.distage.roles.model.{ActivationInfo, DIAppBootstrapException}
+import izumi.distage.roles.model.meta.{LibraryReference, RolesInfo}
+import izumi.distage.roles.model.exceptions.DIAppBootstrapException
 import izumi.distage.roles.services.StartupPlanExecutor.Filters
 import izumi.distage.roles.services.{RoleAppActivationParser, _}
 import izumi.fundamentals.platform.cli.model.raw.RawAppArgs
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/internal/ConfigWriter.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/examples/ConfigWriter.scala
similarity index 98%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/internal/ConfigWriter.scala
rename to distage/distage-framework/src/main/scala/izumi/distage/roles/examples/ConfigWriter.scala
index 460865f07..d738d7013 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/internal/ConfigWriter.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/examples/ConfigWriter.scala
@@ -1,4 +1,4 @@
-package izumi.distage.roles.internal
+package izumi.distage.roles.examples
 
 import java.nio.charset.StandardCharsets
 import java.nio.file.{Files, Paths}
@@ -12,8 +12,8 @@ import izumi.distage.model.effect.DIEffect
 import izumi.distage.model.plan.ExecutableOp.WiringOp
 import izumi.distage.model.plan.OrderedPlan
 import izumi.distage.model.reflection.universe.RuntimeDIUniverse.Wiring.SingletonWiring.Instance
-import izumi.distage.roles.internal.ConfigWriter.{ConfigurableComponent, WriteReference}
-import izumi.distage.roles.meta.{RoleBinding, RolesInfo}
+import izumi.distage.roles.examples.ConfigWriter.{ConfigurableComponent, WriteReference}
+import izumi.distage.roles.model.meta.{RoleBinding, RolesInfo}
 import izumi.distage.roles.model.{RoleDescriptor, RoleTask}
 import izumi.fundamentals.platform.cli.model.raw.RawEntrypointParams
 import izumi.fundamentals.platform.cli.model.schema.{ParserDef, RoleParserSchema}
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/internal/Help.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/examples/Help.scala
similarity index 90%
rename from distage/distage-framework/src/main/scala/izumi/distage/roles/internal/Help.scala
rename to distage/distage-framework/src/main/scala/izumi/distage/roles/examples/Help.scala
index 9ddb4c317..96e02cc79 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/internal/Help.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/examples/Help.scala
@@ -1,9 +1,10 @@
-package izumi.distage.roles.internal
+package izumi.distage.roles.examples
 
+import izumi.distage.framework.model.ActivationInfo
 import izumi.distage.model.effect.DIEffect
 import izumi.distage.roles.RoleAppLauncher.Options
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.{ActivationInfo, RoleDescriptor, RoleTask}
+import izumi.distage.roles.model.meta.RolesInfo
+import izumi.distage.roles.model.{RoleDescriptor, RoleTask}
 import izumi.fundamentals.platform.cli.model.raw.RawEntrypointParams
 import izumi.fundamentals.platform.cli.model.schema._
 import izumi.fundamentals.platform.language.unused
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppActivationParser.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppActivationParser.scala
index e650a753b..4827c2238 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppActivationParser.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppActivationParser.scala
@@ -1,10 +1,12 @@
 package izumi.distage.roles.services
 
 import distage.ModuleBase
+import izumi.distage.framework.model.ActivationInfo
+import izumi.distage.framework.services.ActivationInfoExtractor
 import izumi.distage.model.definition.Axis.AxisValue
 import izumi.distage.model.definition.{Activation, Axis}
 import izumi.distage.roles.RoleAppLauncher.Options
-import izumi.distage.roles.model.{ActivationInfo, DIAppBootstrapException}
+import izumi.distage.roles.model.exceptions.DIAppBootstrapException
 import izumi.fundamentals.platform.cli.model.raw.RawAppArgs
 import izumi.fundamentals.platform.strings.IzString._
 import izumi.logstage.api.IzLogger
@@ -17,7 +19,7 @@ class RoleAppActivationParser {
                        defaultActivations: Map[Axis, AxisValue],
                      ): (ActivationInfo, Activation) = {
     val uses = parameters.globalParameters.findValues(Options.use)
-    val availableUses = ActivationInfo.findAvailableChoices(logger, appModule)
+    val availableUses = ActivationInfoExtractor.findAvailableChoices(logger, appModule)
 
     def options: String = {
       availableUses.availableChoices.map {
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppExecutor.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppExecutor.scala
index cf43984a0..fde144247 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppExecutor.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleAppExecutor.scala
@@ -6,8 +6,9 @@ import izumi.distage.model.Locator
 import izumi.distage.model.effect.DIEffect
 import izumi.distage.model.effect.DIEffect.syntax._
 import izumi.distage.roles._
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.{AbstractRole, DIAppBootstrapException, RoleService, RoleTask}
+import izumi.distage.roles.model.meta.RolesInfo
+import izumi.distage.roles.model.exceptions.DIAppBootstrapException
+import izumi.distage.roles.model.{AbstractRole, RoleService, RoleTask}
 import izumi.distage.roles.services.StartupPlanExecutor.Filters
 import izumi.fundamentals.platform.cli.model.raw.RawAppArgs
 import izumi.logstage.api.IzLogger
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleProvider.scala b/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleProvider.scala
index 0da06be17..691e67f09 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleProvider.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/roles/services/RoleProvider.scala
@@ -4,8 +4,8 @@ import distage._
 import izumi.distage.model.definition.Binding
 import izumi.distage.model.definition.Binding.ImplBinding
 import izumi.distage.model.reflection.universe.RuntimeDIUniverse.SafeType
-import izumi.distage.roles.meta
-import izumi.distage.roles.meta.{RoleBinding, RolesInfo}
+import izumi.distage.roles.model.meta
+import izumi.distage.roles.model.meta.{RoleBinding, RolesInfo}
 import izumi.distage.roles.model.{AbstractRole, RoleDescriptor}
 import izumi.fundamentals.platform.resources.IzManifest
 import izumi.logstage.api.IzLogger
diff --git a/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIAssociation.scala b/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIAssociation.scala
index fa42516ed..8a113527e 100644
--- a/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIAssociation.scala
+++ b/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIAssociation.scala
@@ -1,12 +1,11 @@
 package izumi.distage.model.plan.operations
 
 import izumi.distage.model.references.WithDIKey
-import izumi.distage.model.reflection.universe.{DIUniverseBase, WithDICallable, WithDISafeType, WithDISymbolInfo}
+import izumi.distage.model.reflection.universe.{DIUniverseBase, WithDISafeType, WithDISymbolInfo}
 
 trait WithDIAssociation {
   this:  DIUniverseBase
     with WithDISafeType
-    with WithDICallable
     with WithDIKey
     with WithDISymbolInfo
   =>
diff --git a/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIWiring.scala b/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIWiring.scala
index be395b2b3..60eadef38 100644
--- a/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIWiring.scala
+++ b/distage/distage-model/src/main/scala/izumi/distage/model/plan/operations/WithDIWiring.scala
@@ -1,13 +1,12 @@
 package izumi.distage.model.plan.operations
 
 import izumi.distage.model.references.WithDIKey
-import izumi.distage.model.reflection.universe.{DIUniverseBase, WithDICallable, WithDISafeType, WithDISymbolInfo}
+import izumi.distage.model.reflection.universe.{DIUniverseBase, WithDISafeType, WithDISymbolInfo}
 import izumi.fundamentals.platform.language.Quirks._
 
 trait WithDIWiring {
   this: DIUniverseBase
     with WithDISafeType
-    with WithDICallable
     with WithDIKey
     with WithDIAssociation
     with WithDISymbolInfo
diff --git a/distage/distage-model/src/main/scala/izumi/distage/model/references/WithDITypedRef.scala b/distage/distage-model/src/main/scala/izumi/distage/model/references/WithDITypedRef.scala
deleted file mode 100644
index 523ddc271..000000000
--- a/distage/distage-model/src/main/scala/izumi/distage/model/references/WithDITypedRef.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-package izumi.distage.model.references
-
-import izumi.distage.model.reflection.universe.{DIUniverseBase, WithDISafeType}
-
-trait WithDITypedRef {
-  this: DIUniverseBase
-    with WithDISafeType =>
-//
-//  case class TypedRef[+T](private val v: T, symbol: SafeType) {
-//    def value: T = v match {
-//      case d: ByNameWrapper => d.apply().asInstanceOf[T]
-//      case o => o
-//    }
-//  }
-//  object TypedRef {
-//    def apply[T: Tag](value: T): TypedRef[T] = TypedRef(value, SafeType.get[T])
-//    def byName[T: Tag](value: => T): TypedRef[T] = TypedRef((() => value).asInstanceOf[T], SafeType.get[T])
-//  }
-
-}
diff --git a/distage/distage-model/src/main/scala/izumi/distage/model/reflection/universe/DIUniverse.scala b/distage/distage-model/src/main/scala/izumi/distage/model/reflection/universe/DIUniverse.scala
index e17fd1a7d..8abc29335 100644
--- a/distage/distage-model/src/main/scala/izumi/distage/model/reflection/universe/DIUniverse.scala
+++ b/distage/distage-model/src/main/scala/izumi/distage/model/reflection/universe/DIUniverse.scala
@@ -7,8 +7,6 @@ trait DIUniverse
   extends DIUniverseBase
     with WithDISafeType
     with WithDISymbolInfo
-    with WithDITypedRef
-    with WithDICallable
     with WithDIKey
     with WithDIAssociation
     with WithDIWiring
diff --git a/distage/distage-model/src/main/scala/izumi/distage/model/reflection/universe/WithDICallable.scala b/distage/distage-model/src/main/scala/izumi/distage/model/reflection/universe/WithDICallable.scala
deleted file mode 100644
index 165484f9a..000000000
--- a/distage/distage-model/src/main/scala/izumi/distage/model/reflection/universe/WithDICallable.scala
+++ /dev/null
@@ -1,137 +0,0 @@
-package izumi.distage.model.reflection.universe
-
-import izumi.distage.model.exceptions.DIException
-import izumi.distage.model.plan.operations.{WithDIAssociation, WithDIWiring}
-import izumi.distage.model.references.{WithDIKey, WithDITypedRef}
-
-trait WithDICallable {
-  this: DIUniverseBase
-    with WithDISafeType
-    with WithDITypedRef
-    with WithDIKey
-    with WithDISymbolInfo
-    with WithDIAssociation
-    with WithDIWiring =>
-//
-//  trait DIFunction {
-//    def associations: Seq[Association.Parameter]
-//    def argTypes: Seq[SafeType]
-//    def diKeys: Seq[DIKey]
-//
-//    def ret: SafeType
-//
-//    def fun: Seq[Any] => Any
-//    def arity: Int
-//
-//    def isGenerated: Boolean
-//
-//    def unsafeApply(refs: TypedRef[_]*): Any = {
-//      val args = verifyArgs(refs)
-//      fun(args)
-//    }
-//
-//    private[this] def verifyArgs(refs: Seq[TypedRef[_]]): Seq[Any] = {
-//      val countOk = refs.size == argTypes.size
-//
-//      val typesOk = argTypes.zip(refs).forall {
-//        case (tpe, arg) =>
-//          arg.symbol <:< tpe
-//      }
-//
-//      val (args, types) = refs.map { case TypedRef(v, t) => (v, t) }.unzip
-//
-//      if (countOk && typesOk) {
-//        args
-//      } else {
-//        throw new UnsafeCallArgsMismatched(
-//          message =
-//            s"""Mismatched arguments for unsafe call:
-//               | ${if (!typesOk) "Wrong types!" else ""}
-//               | ${if (!countOk) s"Expected number of arguments ${argTypes.size}, but got ${refs.size}" else ""}
-//               |Expected types [${argTypes.mkString(",")}], got types [${types.mkString(",")}], values: (${args.mkString(",")})""".stripMargin,
-//          expected = argTypes,
-//          actual = types,
-//          actualValues = args,
-//        )
-//      }
-//    }
-//  }
-//
-//
-//  trait Provider extends DIFunction {
-//    def unsafeMap(newRet: SafeType, f: Any => _): Provider
-//    def unsafeZip(newRet: SafeType, that: Provider): Provider
-//
-//    override final val diKeys: Seq[DIKey] = associations.map(_.key)
-//    override final val argTypes: Seq[SafeType] = associations.map(_.key.tpe)
-//    override final val arity: Int = argTypes.size
-//
-//    private def eqField: AnyRef = if (isGenerated) ret else fun
-//    override final def equals(obj: Any): Boolean = {
-//      obj match {
-//        case that: Provider =>
-//          eqField == that.eqField
-//        case _ =>
-//          false
-//      }
-//    }
-//    override final def hashCode(): Int = eqField.hashCode()
-//    override final def toString: String = s"$fun(${argTypes.mkString(", ")}): $ret"
-//  }
-//
-//  object Provider {
-//
-//    case class ProviderImpl[+A](
-//                                 associations: Seq[Association.Parameter],
-//                                 ret: SafeType,
-//                                 fun: Seq[Any] => Any,
-//                                 isGenerated: Boolean,
-//                               ) extends Provider {
-//
-//      override final def unsafeApply(refs: TypedRef[_]*): A =
-//        super.unsafeApply(refs: _*).asInstanceOf[A]
-//
-//      override final def unsafeMap(newRet: SafeType, f: Any => _): ProviderImpl[_] =
-//        copy(ret = newRet, fun = xs => f.apply(fun(xs)))
-//
-//      override final def unsafeZip(newRet: SafeType, that: Provider): Provider =
-//        ProviderImpl(
-//          associations ++ that.associations,
-//          newRet,
-//          { args0 =>
-//            val (args1, args2) = args0.splitAt(arity)
-//            fun(args1) -> that.fun(args2)
-//          },
-//          isGenerated
-//        )
-//    }
-//
-//    trait FactoryProvider extends Provider {
-//      def factoryIndex: Map[Int, Wiring.FactoryFunction.FactoryMethod]
-//    }
-//
-//    object FactoryProvider {
-//      case class FactoryProviderImpl(provider: Provider, factoryIndex: Map[Int, Wiring.FactoryFunction.FactoryMethod], isGenerated: Boolean) extends FactoryProvider {
-//        override final def associations: Seq[Association.Parameter] = provider.associations
-//        override final def ret: SafeType = provider.ret
-//        override final def fun: Seq[Any] => Any = provider.fun
-//
-//        override final def unsafeMap(newRet: SafeType, f: Any => _): FactoryProviderImpl =
-//          copy(provider = provider.unsafeMap(newRet, f))
-//
-//        override final def unsafeZip(newRet: SafeType, that: Provider): FactoryProviderImpl = {
-//          that match {
-//            case that: FactoryProviderImpl =>
-//              throw new FactoryProvidersCannotBeCombined(s"Impossible operation: two factory providers cannot be zipped. this=$this that=$that", this, that)
-//            case _ =>
-//              copy(provider = provider.unsafeZip(newRet, that))
-//          }
-//        }
-//      }
-//    }
-//  }
-//
-//  class UnsafeCallArgsMismatched(message: String, val expected: Seq[SafeType], val actual: Seq[SafeType], val actualValues: Seq[Any]) extends DIException(message)
-//
-//  class FactoryProvidersCannotBeCombined(message: String, val provider1: Provider.FactoryProvider, val provider2: Provider.FactoryProvider) extends DIException(message)
-}
diff --git a/doc/microsite/src/main/tut/distage/00_distage.md b/doc/microsite/src/main/tut/distage/00_distage.md
index bdc14a659..69f0ac578 100644
--- a/doc/microsite/src/main/tut/distage/00_distage.md
+++ b/doc/microsite/src/main/tut/distage/00_distage.md
@@ -71,6 +71,7 @@ Further reading
 - @ref[Advanced features](advanced-features.md)
 - @ref[Debugging](debugging.md)
 - @ref[distage-config](distage-config.md)
+- @ref[distage-docker](distage-docker.md)
 - @ref[distage-framework](distage-framework.md)
 - @ref[distage-testkit](distage-testkit.md)
 - @ref[Syntax summary](reference.md)
@@ -81,6 +82,7 @@ Further reading
 * [Advanced features](advanced-features.md)
 * [Debugging](debugging.md)
 * [distage-config](distage-config.md)
+* [distage-docker](distage-docker.md)
 * [distage-framework](distage-framework.md)
 * [distage-testkit](distage-testkit.md)
 * [Syntax summary](reference.md)
diff --git a/doc/microsite/src/main/tut/distage/distage-docker.md b/doc/microsite/src/main/tut/distage/distage-docker.md
new file mode 100644
index 000000000..5c588d2df
--- /dev/null
+++ b/doc/microsite/src/main/tut/distage/distage-docker.md
@@ -0,0 +1,11 @@
+distage-docker
+=======================
+
+@@toc { depth=2 }
+
+### Docker Test Resources
+
+There is some documentation in the [release notes for 0.9.13](https://github.com/7mind/izumi/releases/tag/v0.9.13)
+and there's an [example PR](https://github.com/7mind/distage-livecode/pull/2/files) showing how to use them. 
+
+Further documentation TBD: [Issue #761](https://github.com/7mind/izumi/issues/761)
diff --git a/doc/microsite/src/main/tut/distage/distage-framework.md b/doc/microsite/src/main/tut/distage/distage-framework.md
index e7da7c6a4..7c7e701f6 100644
--- a/doc/microsite/src/main/tut/distage/distage-framework.md
+++ b/doc/microsite/src/main/tut/distage/distage-framework.md
@@ -21,6 +21,8 @@ libraryDependencies += "io.7mind.izumi" %% "distage-framework" % "$izumi.version
 With default `RoleLauncher` implementation, roles to be launched are chosen by command-line parameters: `./launcher role1 role2 role3`.
 Only the components required by the chosen roles will be created, everything else will be pruned. (see: @ref[GC](advanced-features.md#garbage-collection))
 
+There are 2 bundled roles: @scaladoc[Help](izumi.distage.roles.examples.Help) and @scaladoc[ConfigWriter](izumi.distage.roles.examples.ConfigWriter).
+
 Further reading: [Roles: a viable alternative to Microservices](https://github.com/7mind/slides/blob/master/02-roles/target/roles.pdf)
 
 ### Plugins
diff --git a/project/Deps.sc b/project/Deps.sc
index dfed23e0b..ba5cce972 100644
--- a/project/Deps.sc
+++ b/project/Deps.sc
@@ -269,8 +269,11 @@ object Izumi {
       final lazy val core = ArtifactId("distage-core")
       final lazy val config = ArtifactId("distage-config")
       final lazy val plugins = ArtifactId("distage-plugins")
+      final lazy val docker = ArtifactId("distage-docker")
+      final lazy val frameworkApi = ArtifactId("distage-framework-api")
       final lazy val framework = ArtifactId("distage-framework")
       final lazy val testkit = ArtifactId("distage-testkit")
+      final lazy val legacyTestkit = ArtifactId("distage-legacy-testkit")
     }
 
     object logstage {
@@ -433,15 +436,26 @@ object Izumi {
           Seq(Projects.distage.core).map(_ tin Scope.Test.all) ++
           Seq(Projects.distage.config, Projects.logstage.core).map(_ in Scope.Test.all),
       ),
+      Artifact(
+        name = Projects.distage.frameworkApi,
+        libs = Seq.empty,
+        depends = Seq(Projects.distage.model).map(_ in Scope.Compile.all),
+      ),
       Artifact(
         name = Projects.distage.framework,
-        libs = allMonadsOptional ++ Seq(docker_java in Scope.Compile.jvm) ++ Seq(scala_reflect in Scope.Provided.all),
+        libs = allMonadsOptional ++ Seq(scala_reflect in Scope.Provided.all),
         depends = Seq(Projects.logstage.di, Projects.logstage.adapterSlf4j, Projects.logstage.renderingCirce).map(_ in Scope.Compile.all) ++
-          Seq(Projects.distage.core, Projects.distage.plugins, Projects.distage.config).map(_ tin Scope.Compile.all),
+          Seq(Projects.distage.core, Projects.distage.frameworkApi, Projects.distage.plugins, Projects.distage.config).map(_ tin Scope.Compile.all),
+      ),
+      Artifact(
+        name = Projects.distage.docker,
+        libs = Seq(docker_java in Scope.Compile.jvm),
+        depends = Seq(Projects.distage.core, Projects.distage.config, Projects.distage.frameworkApi, Projects.logstage.di).map(_ in Scope.Compile.all) ++
+          Seq(Projects.distage.testkit in Scope.Test.all),
       ),
       Artifact(
         name = Projects.distage.testkit,
-        libs = Seq(scalatest.dependency).map(_ in Scope.Compile.all) ++ allMonadsOptional,
+        libs = allMonadsOptional ++ Seq(scalatest.dependency).map(_ in Scope.Compile.all),
         depends =
           Seq(Projects.distage.config, Projects.distage.framework, Projects.logstage.di).map(_ in Scope.Compile.all) ++
             Seq(Projects.distage.core, Projects.distage.plugins).map(_ tin Scope.Compile.all),
@@ -449,6 +463,16 @@ object Izumi {
           "classLoaderLayeringStrategy" in SettingScope.Test := "ClassLoaderLayeringStrategy.Flat".raw,
         ),
       ),
+      Artifact(
+        name = Projects.distage.legacyTestkit,
+        libs = allMonadsOptional ++ Seq(scalatest.dependency).map(_ in Scope.Compile.all),
+        depends =
+          Seq(Projects.distage.config, Projects.distage.framework, Projects.logstage.di).map(_ in Scope.Compile.all) ++
+            Seq(Projects.distage.core, Projects.distage.testkit).map(_ in Scope.Compile.all),
+        settings = Seq(
+          "classLoaderLayeringStrategy" in SettingScope.Test := "ClassLoaderLayeringStrategy.Flat".raw,
+        ),
+      ),
     ),
     pathPrefix = Projects.distage.basePath,
     defaultPlatforms = Targets.jvm,


Test patch:
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala
index a7b4ec18a..a6a07eee2 100644
--- a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala
@@ -5,7 +5,7 @@ import izumi.distage.config.ConfigModuleDef
 import izumi.distage.model.definition.StandardAxis._
 import izumi.distage.effect.modules.CatsDIEffectModule
 import izumi.distage.plugins.PluginDef
-import izumi.distage.roles.internal.{ConfigWriter, Help}
+import izumi.distage.roles.examples.{ConfigWriter, Help}
 import izumi.distage.roles.test.fixtures.Fixture._
 import izumi.distage.roles.test.fixtures.TestPlugin.{InheritedCloseable, NotCloseable}
 import izumi.distage.roles.test.fixtures.TestRole00.{IntegrationOnlyCfg, TestRole00Resource, TestRole00ResourceIntegrationCheck}
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/DistageBioSpec.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/DistageBioSpec.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/DistageBioSpec.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/DistageBioSpec.scala
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/DistageSpec.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/DistageSpec.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/DistageSpec.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/DistageSpec.scala
index a39fe28d7..1531a69ef 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/DistageSpec.scala
+++ b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/DistageSpec.scala
@@ -1,7 +1,7 @@
 package izumi.distage.testkit
 
-import izumi.fundamentals.reflection.Tags.TagK
 import izumi.distage.testkit.services.scalatest.adapter.DistageTestSupport
+import izumi.fundamentals.reflection.Tags.TagK
 import org.scalatest.{ScalatestSuite, WordSpecLike}
 
 @deprecated("Use dstest", "2019/Jul/18")
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntax.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntax.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntax.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntax.scala
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntaxBIO.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntaxBIO.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntaxBIO.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DISyntaxBIO.scala
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistagePluginTestSupport.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistagePluginTestSupport.scala
similarity index 86%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistagePluginTestSupport.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistagePluginTestSupport.scala
index 2745f6d47..e63f4c584 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistagePluginTestSupport.scala
+++ b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistagePluginTestSupport.scala
@@ -2,18 +2,18 @@ package izumi.distage.testkit.services.scalatest.adapter
 
 import distage.SafeType
 import izumi.distage.framework.activation.PruningPlanMergingPolicy
-import izumi.distage.framework.model.{BootstrapConfig, PluginSource}
+import izumi.distage.framework.model.{ActivationInfo, BootstrapConfig, PluginSource}
+import izumi.distage.framework.services.ActivationInfoExtractor
 import izumi.distage.model.definition.StandardAxis._
 import izumi.distage.model.definition.{Activation, BootstrapModuleDef}
 import izumi.distage.model.planning.PlanMergingPolicy
 import izumi.distage.plugins.load.PluginLoader.PluginConfig
 import izumi.distage.plugins.merge.{PluginMergeStrategy, SimplePluginMergeStrategy}
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.ActivationInfo
+import izumi.distage.roles.model.meta.RolesInfo
 import izumi.distage.testkit.services.PluginsCache
 import izumi.distage.testkit.services.PluginsCache.{CacheKey, CacheValue}
 import izumi.distage.testkit.services.dstest.TestEnvironment
-import izumi.fundamentals.platform.language.Quirks
+import izumi.fundamentals.platform.language.unused
 import izumi.fundamentals.reflection.Tags.TagK
 import izumi.logstage.api.IzLogger
 
@@ -45,7 +45,7 @@ abstract class DistagePluginTestSupport[F[_] : TagK] extends DistageTestSupport[
       val mergeStrategy = makeMergeStrategy(logger)
       val defApp = mergeStrategy.merge(plugins.app)
       val bootstrap = mergeStrategy.merge(plugins.bootstrap)
-      val availableActivations = ActivationInfo.findAvailableChoices(logger, defApp)
+      val availableActivations = ActivationInfoExtractor.findAvailableChoices(logger, defApp)
       CacheValue(plugins, bootstrap, defApp, availableActivations)
     }
 
@@ -82,20 +82,20 @@ abstract class DistagePluginTestSupport[F[_] : TagK] extends DistageTestSupport[
       .asBoolean(true)
   }
 
-  protected def loadRoles(logger: IzLogger): RolesInfo = {
-    Quirks.discard(logger)
+  protected def loadRoles(@unused logger: IzLogger): RolesInfo = {
     // For all normal scenarios we don't need roles to setup a test
     RolesInfo(Set.empty, Seq.empty, Seq.empty, Seq.empty, Set.empty)
   }
 
-  protected def activation: Activation = Activation(Env -> Env.Test)
+  protected def activation: Activation = {
+    Activation(Env -> Env.Test)
+  }
 
   protected def memoizationContextId: MemoizationContextId = {
     MemoizationContextId.PerRuntimeAndActivationAndBsconfig[F](bootstrapConfig, activation, SafeType.getK[F])
   }
 
-  protected def makeMergeStrategy(lateLogger: IzLogger): PluginMergeStrategy = {
-    Quirks.discard(lateLogger)
+  protected def makeMergeStrategy(@unused lateLogger: IzLogger): PluginMergeStrategy = {
     SimplePluginMergeStrategy
   }
 
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistageTestSupport.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistageTestSupport.scala
similarity index 98%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistageTestSupport.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistageTestSupport.scala
index 6c79ad694..3f6af3324 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistageTestSupport.scala
+++ b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/DistageTestSupport.scala
@@ -3,6 +3,7 @@ package izumi.distage.testkit.services.scalatest.adapter
 import distage.config.AppConfig
 import distage.{DIKey, Injector, ModuleBase}
 import izumi.distage.framework.config.PlanningOptions
+import izumi.distage.framework.model.ActivationInfo
 import izumi.distage.framework.services.IntegrationChecker.IntegrationCheckException
 import izumi.distage.framework.services.{ConfigLoader, IntegrationChecker, ModuleProvider, RoleAppPlanner}
 import izumi.distage.model.Locator
@@ -11,8 +12,7 @@ import izumi.distage.model.definition.{Activation, Binding, BootstrapModule, Imp
 import izumi.distage.model.effect.DIEffect
 import izumi.distage.model.effect.DIEffect.syntax._
 import izumi.distage.model.providers.ProviderMagnet
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.ActivationInfo
+import izumi.distage.roles.model.meta.RolesInfo
 import izumi.distage.roles.services.StartupPlanExecutor.Filters
 import izumi.distage.roles.services._
 import izumi.distage.testkit.services.dstest.TestEnvironment
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/ExternalResourceProvider.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/ExternalResourceProvider.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/ExternalResourceProvider.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/ExternalResourceProvider.scala
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/IgnoreSupport.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/IgnoreSupport.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/IgnoreSupport.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/IgnoreSupport.scala
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/MemoizationContextId.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/MemoizationContextId.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/MemoizationContextId.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/MemoizationContextId.scala
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/SuppressionSupport.scala b/distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/SuppressionSupport.scala
similarity index 100%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/SuppressionSupport.scala
rename to distage/distage-legacy-testkit/src/main/scala/izumi/distage/testkit/services/scalatest/adapter/SuppressionSupport.scala
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/scalatest/adapter/specs/DistagePluginBioSpec.scala b/distage/distage-legacy-testkit/src/main/scala/scalatest/adapter/specs/DistagePluginBioSpec.scala
similarity index 77%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/scalatest/adapter/specs/DistagePluginBioSpec.scala
rename to distage/distage-legacy-testkit/src/main/scala/scalatest/adapter/specs/DistagePluginBioSpec.scala
index fc860d700..e25d0aa70 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/scalatest/adapter/specs/DistagePluginBioSpec.scala
+++ b/distage/distage-legacy-testkit/src/main/scala/scalatest/adapter/specs/DistagePluginBioSpec.scala
@@ -1,4 +1,4 @@
-package izumi.distage.testkit.scalatest.adapter.specs
+package scalatest.adapter.specs
 
 import distage.TagKK
 
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/scalatest/adapter/specs/DistagePluginSpec.scala b/distage/distage-legacy-testkit/src/main/scala/scalatest/adapter/specs/DistagePluginSpec.scala
similarity index 88%
rename from distage/distage-testkit/src/main/scala/izumi/distage/testkit/scalatest/adapter/specs/DistagePluginSpec.scala
rename to distage/distage-legacy-testkit/src/main/scala/scalatest/adapter/specs/DistagePluginSpec.scala
index d600a52bd..24fd2e400 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/scalatest/adapter/specs/DistagePluginSpec.scala
+++ b/distage/distage-legacy-testkit/src/main/scala/scalatest/adapter/specs/DistagePluginSpec.scala
@@ -1,7 +1,7 @@
-package izumi.distage.testkit.scalatest.adapter.specs
+package scalatest.adapter.specs
 
-import izumi.fundamentals.reflection.Tags.TagK
 import izumi.distage.testkit.services.scalatest.adapter.DistagePluginTestSupport
+import izumi.fundamentals.reflection.Tags.TagK
 import org.scalatest.{ScalatestSuite, WordSpecLike}
 
 @deprecated("Use dstest", "2019/Jul/18")
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitBIOTest.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitBIOTest.scala
similarity index 91%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitBIOTest.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitBIOTest.scala
index a07c8dc33..a5f17ad91 100644
--- a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitBIOTest.scala
+++ b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitBIOTest.scala
@@ -3,8 +3,8 @@ package izumi.distage.testkit.scalatest
 import distage.{ModuleBase, TagKK}
 import izumi.distage.model.definition.ModuleDef
 import izumi.distage.testkit.services.scalatest.adapter.DISyntaxBIO
-import izumi.distage.testkit.scalatest.adapter.specs.DistagePluginBioSpec
 import izumi.functional.bio.{BIO, BIOError, F}
+import scalatest.adapter.specs.DistagePluginBioSpec
 
 abstract class TestkitBIOTest[F[+_, +_]: BIO: TagKK] extends DistagePluginBioSpec[F]
   with DISyntaxBIO[F] {
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIgnoredTest.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIgnoredTest.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIgnoredTest.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIgnoredTest.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIntegrationCheckTest.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIntegrationCheckTest.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIntegrationCheckTest.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitIntegrationCheckTest.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitMemoizationTest.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitMemoizationTest.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitMemoizationTest.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitMemoizationTest.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitSuppressionTest.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitSuppressionTest.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitSuppressionTest.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitSuppressionTest.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitTest.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitTest.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitTest.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/TestkitTest.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/Fixtures.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/Fixtures.scala
similarity index 100%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/Fixtures.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/Fixtures.scala
diff --git a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/TestkitSelftest.scala b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/TestkitSelftest.scala
similarity index 75%
rename from distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/TestkitSelftest.scala
rename to distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/TestkitSelftest.scala
index 837a5f3db..e3ece95a6 100644
--- a/distage/distage-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/TestkitSelftest.scala
+++ b/distage/distage-legacy-testkit/src/test/scala/izumi/distage/testkit/scalatest/fixtures/TestkitSelftest.scala
@@ -1,7 +1,7 @@
 package izumi.distage.testkit.scalatest.fixtures
 
-import izumi.distage.testkit.scalatest.adapter.specs.DistagePluginSpec
 import distage.TagK
+import scalatest.adapter.specs.DistagePluginSpec
 
 abstract class TestkitSelftest[F[_]: TagK] extends DistagePluginSpec[F]{
   override protected def pluginPackages: Seq[String] = thisPackage
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/PluginsCache.scala b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/PluginsCache.scala
index 9cb0c38ed..c10ee0648 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/PluginsCache.scala
+++ b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/PluginsCache.scala
@@ -1,8 +1,7 @@
 package izumi.distage.testkit.services
 
-import izumi.distage.framework.model.{AllLoadedPlugins, BootstrapConfig}
+import izumi.distage.framework.model.{ActivationInfo, AllLoadedPlugins, BootstrapConfig}
 import izumi.distage.model.definition.ModuleBase
-import izumi.distage.roles.model.ActivationInfo
 
 object PluginsCache {
   final case class CacheKey(config: BootstrapConfig)
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/SpecEnvironment.scala b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/SpecEnvironment.scala
index eb85a0aee..c84e777da 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/SpecEnvironment.scala
+++ b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/SpecEnvironment.scala
@@ -3,10 +3,10 @@ package izumi.distage.testkit.services.dstest
 import distage.ModuleBase
 import distage.config.AppConfig
 import izumi.distage.framework.config.PlanningOptions
+import izumi.distage.framework.model.ActivationInfo
 import izumi.distage.framework.services.{ConfigLoader, ModuleProvider}
 import izumi.distage.model.definition.{Activation, BootstrapModule}
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.ActivationInfo
+import izumi.distage.roles.model.meta.RolesInfo
 import izumi.fundamentals.platform.cli.model.raw.RawAppArgs
 import izumi.fundamentals.reflection.Tags.TagK
 import izumi.logstage.api.{IzLogger, Log}
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironment.scala b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironment.scala
index dabac2291..fb8c3c2eb 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironment.scala
+++ b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironment.scala
@@ -2,10 +2,10 @@ package izumi.distage.testkit.services.dstest
 
 import distage._
 import izumi.distage.framework.activation.PruningPlanMergingPolicy
+import izumi.distage.framework.model.ActivationInfo
 import izumi.distage.model.definition.Activation
 import izumi.distage.model.planning.PlanMergingPolicy
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.ActivationInfo
+import izumi.distage.roles.model.meta.RolesInfo
 
 final case class TestEnvironment(
                                   private val baseBsModule: ModuleBase,
diff --git a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironmentProvider.scala b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironmentProvider.scala
index 19931d55c..6dbf30511 100644
--- a/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironmentProvider.scala
+++ b/distage/distage-testkit/src/main/scala/izumi/distage/testkit/services/dstest/TestEnvironmentProvider.scala
@@ -2,10 +2,10 @@ package izumi.distage.testkit.services.dstest
 
 import distage.DIKey
 import izumi.distage.framework.model.PluginSource
+import izumi.distage.framework.services.ActivationInfoExtractor
 import izumi.distage.model.definition.{Activation, BootstrapModule, ModuleBase}
 import izumi.distage.plugins.merge.{PluginMergeStrategy, SimplePluginMergeStrategy}
-import izumi.distage.roles.meta.RolesInfo
-import izumi.distage.roles.model.ActivationInfo
+import izumi.distage.roles.model.meta.RolesInfo
 import izumi.distage.testkit.services.PluginsCache
 import izumi.distage.testkit.services.PluginsCache.{CacheKey, CacheValue}
 import izumi.fundamentals.platform.language.Quirks
@@ -37,7 +37,7 @@ object TestEnvironmentProvider {
         val mergeStrategy = makeMergeStrategy(logger)
         val defApp = mergeStrategy.merge(plugins.app)
         val bootstrap = mergeStrategy.merge(plugins.bootstrap)
-        val availableActivations = ActivationInfo.findAvailableChoices(logger, defApp)
+        val availableActivations = ActivationInfoExtractor.findAvailableChoices(logger, defApp)
         CacheValue(plugins, bootstrap, defApp, availableActivations)
       }
 
diff --git a/doc/microsite/src/main/tut/distage/distage-testkit.md b/doc/microsite/src/main/tut/distage/distage-testkit.md
index 5080143c9..eb80d1145 100644
--- a/doc/microsite/src/main/tut/distage/distage-testkit.md
+++ b/doc/microsite/src/main/tut/distage/distage-testkit.md
@@ -90,17 +90,10 @@ class LadderTest extends LivecodeTest with DummyTest {
 }
 ```
 
-### Docker Test Resources
-
-There is some documentation in the [release notes for 0.9.13](https://github.com/7mind/izumi/releases/tag/v0.9.13)
-and there's an [example PR](https://github.com/7mind/distage-livecode/pull/2/files) showing how to use them. 
-
-Further documentation TBD: [Issue #761](https://github.com/7mind/izumi/issues/761)
-
 ### Integration Checks
 
 Implementation classes that inherit from `izumi.distage.roles.model.IntegrationCheck` can specify a `resourceCheck()` method
-that will be called before test instantiation to check if **external test dependencies** (such as docker containers above)
+that will be called before test instantiation to check if **external test dependencies** (such as docker containers in @ref[distage-docker](distage-docker.md#docker-test-resources))
 are available for the test or role. If not, the test will be canceled/ignored.
 
 This feature allows you to e.g. selectively run only the fast in-memory tests that have no external dependencies if you have