diff --git a/project/Build.scala b/project/Build.scala
index 3e53990cfd56..03e58d98f3f3 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -20,6 +20,8 @@ import sbt.Package.ManifestAttributes
 import sbt.PublishBinPlugin.autoImport._
 import dotty.tools.sbtplugin.RepublishPlugin
 import dotty.tools.sbtplugin.RepublishPlugin.autoImport._
+import dotty.tools.sbtplugin.ScalaLibraryPlugin
+
 import sbt.plugins.SbtPlugin
 import sbt.ScriptedPlugin.autoImport._
 import xerial.sbt.Sonatype.autoImport._
@@ -1207,6 +1209,7 @@ object Build {
    *  This version of the library is not (yet) TASTy/binary compatible with the Scala 2 compiled library.
    */
   lazy val `scala2-library-bootstrapped` = project.in(file("scala2-library-bootstrapped")).
+    enablePlugins(ScalaLibraryPlugin).
     withCommonSettings(Bootstrapped).
     dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test").
     settings(scala2LibraryBootstrappedSettings).
diff --git a/project/Scala2LibraryBootstrappedMiMaFilters.scala b/project/Scala2LibraryBootstrappedMiMaFilters.scala
index 301e0075ba7f..dd0a885731b2 100644
--- a/project/Scala2LibraryBootstrappedMiMaFilters.scala
+++ b/project/Scala2LibraryBootstrappedMiMaFilters.scala
@@ -4,83 +4,44 @@ import com.typesafe.tools.mima.core._
 object Scala2LibraryBootstrappedMiMaFilters {
 
   val BackwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map(
-    Build.stdlibBootstrappedVersion -> {
-      Seq(
-        // Files that are not compiled in the bootstrapped library
-        ProblemFilters.exclude[MissingClassProblem]("scala.AnyVal"),
-
-        // Scala language features
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language.<clinit>"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language#experimental.<clinit>"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.util.Properties.<clinit>"),
-        ProblemFilters.exclude[FinalClassProblem]("scala.language$experimental$"),
-        ProblemFilters.exclude[FinalClassProblem]("scala.languageFeature$*$"),
-
-        // Issue: https://github.com/scala/scala3/issues/22495
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.ArrayOps.scala$collection$ArrayOps$$elemTag$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.ArrayOps.iterateUntilEmpty$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.isLineBreak$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.isLineBreak2$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.linesSeparated$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.escape$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.toBooleanImpl$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.unwrapArg$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.iterateUntilEmpty$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple2Zipped.coll1$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple2Zipped.coll2$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple3Zipped.coll1$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple3Zipped.coll2$extension"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple3Zipped.coll3$extension"),
-
-        // Companion module class
-        ProblemFilters.exclude[FinalClassProblem]("scala.*$"),
-
-        // Scala 2 intrinsic macros
-        ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"),
-
-        // Specialization?
-        ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple1._1"), // field _1 in class scala.Tuple1 does not have a correspondent in current version
-        ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._1"), // field _1 in class scala.Tuple2 does not have a correspondent in current version
-        ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._2"), // field _2 in class scala.Tuple2 does not have a correspondent in current version
-
-        // Scala 2 specialization
-        ProblemFilters.exclude[MissingClassProblem]("scala.*$sp"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$sp"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*#*#sp.$init$"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.collection.DoubleStepper"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.DoubleVectorStepper"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.IntVectorStepper"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.LongVectorStepper"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.collection.IntStepper"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.collection.LongStepper"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.DoubleAccumulator"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.FunctionWrappers$*"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.IntAccumulator"),
-        ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.LongAccumulator"),
-        ProblemFilters.exclude[FinalClassProblem]("scala.collection.ArrayOps$ReverseIterator"),
-        ProblemFilters.exclude[FinalClassProblem]("scala.Tuple1"),
-        ProblemFilters.exclude[FinalClassProblem]("scala.Tuple2"),
-
-        // other
-        ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueOrdering"),
-        ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueSet"),
-        ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.NoPositioner"),
-        ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPosition"),
-        ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPositioner"),
-        ProblemFilters.exclude[MissingFieldProblem]("scala.collection.ArrayOps#ReverseIterator.xs"),
-        ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.NonLocalReturnControl.value"),
-
-        // Missing outer pointers in private classes (not a problem)
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.LinearSeqIterator#LazyCell.this"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.concurrent.BatchingExecutor#AbstractBatch.this"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.concurrent.Channel#LinkedList.this"),
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.IterableOnceOps#Maximized.this"),
-
-        ProblemFilters.exclude[DirectMissingMethodProblem]("scala.util.Sorting.scala$util$Sorting$$mergeSort$default$5"),
-
-      )
-    }
+    Build.stdlibBootstrappedVersion -> Seq(
+      // Scala language features (not really a problem)
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language.<clinit>"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language#experimental.<clinit>"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.util.Properties.<clinit>"),
+
+      // Companion module class (not really a problem)
+      ProblemFilters.exclude[FinalClassProblem]("scala.*$"),
+      ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.NoPositioner"),
+      ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPosition"),
+      ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPositioner"),
+      ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueOrdering"),
+      ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueSet"),
+      ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"),
+
+      // Issue: https://github.com/scala/scala3/issues/22495
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.ArrayOps.scala$collection$ArrayOps$$elemTag$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.ArrayOps.iterateUntilEmpty$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.isLineBreak$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.isLineBreak2$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.linesSeparated$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.escape$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.toBooleanImpl$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.unwrapArg$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.StringOps.iterateUntilEmpty$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple2Zipped.coll1$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple2Zipped.coll2$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple3Zipped.coll1$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple3Zipped.coll2$extension"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.Tuple3Zipped.coll3$extension"),
+
+      // Issue: Scala 3 doesn't always outer pointers (not really a problem here)
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.IterableOnceOps#Maximized.this"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.LinearSeqIterator#LazyCell.this"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.concurrent.BatchingExecutor#AbstractBatch.this"),
+      ProblemFilters.exclude[DirectMissingMethodProblem]("scala.concurrent.Channel#LinkedList.this"),
+    )
   )
 
   val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map(
diff --git a/project/ScalaLibraryPlugin.scala b/project/ScalaLibraryPlugin.scala
new file mode 100644
index 000000000000..2eac7271644a
--- /dev/null
+++ b/project/ScalaLibraryPlugin.scala
@@ -0,0 +1,108 @@
+package dotty.tools.sbtplugin
+
+import sbt.*
+import sbt.Keys.*
+import scala.jdk.CollectionConverters.*
+import java.nio.file.Files
+
+object ScalaLibraryPlugin extends AutoPlugin {
+
+  override def trigger = noTrigger
+
+  val fetchScala2ClassFiles = taskKey[(Set[File], File)]("Fetch the files to use that were compiled with Scala 2")
+  //val scala2LibraryVersion  = settingKey[String]("Version of the Scala 2 Standard Library")
+
+  override def projectSettings = Seq (
+    fetchScala2ClassFiles := {
+      val stream = streams.value
+      val cache  = stream.cacheDirectory
+      val target = cache / "scala-library-classes"
+      val report = update.value
+
+      val scalaLibraryBinaryJar = report.select(
+        configuration = configurationFilter(),
+        module = (_: ModuleID).name == "scala-library",
+        artifact = artifactFilter(`type` = "jar")).headOption.getOrElse {
+          sys.error(s"Could not fetch scala-library binary JAR")
+        }
+
+      if (!target.exists()) {
+        IO.createDirectory(target)
+      }
+
+      (FileFunction.cached(cache / "fetch-scala-library-classes", FilesInfo.lastModified, FilesInfo.exists) { _ =>
+        stream.log.info(s"Unpacking scala-library binaries to persistent directory: ${target.getAbsolutePath}")
+        IO.unzip(scalaLibraryBinaryJar, target)
+        (target ** "*.class").get.toSet
+      } (Set(scalaLibraryBinaryJar)), target)
+
+    },
+    (Compile / compile) := {
+      val stream = streams.value
+      val target = (Compile / classDirectory).value
+      val (files, reference) = fetchScala2ClassFiles.value;
+      val analysis = (Compile / compile).value
+      stream.log.info(s"Copying files from Scala 2 Standard Library to $target")
+      for (file <- files; id <- file.relativeTo(reference).map(_.toString())) {
+        if (filesToCopy(id)) {
+          stream.log.debug(s"Copying file '${id}' to ${target / id}")
+          IO.copyFile(file, target / id)
+        }
+      }
+
+      val overwrittenBinaries = Files.walk((Compile / classDirectory).value.toPath())
+        .iterator()
+        .asScala
+        .map(_.toFile)
+        .map(_.relativeTo((Compile / classDirectory).value).get)
+        .toSet
+      val diff = files.filterNot(_.relativeTo(reference).exists(overwrittenBinaries))
+
+      IO.copy(diff.map { file =>
+        file -> (Compile / classDirectory).value / file.relativeTo(reference).get.getPath
+      })
+
+      analysis
+    }
+  )
+
+  private lazy val filesToCopy = Set(
+    "scala/Tuple1.class",
+    "scala/Tuple2.class",
+    "scala/collection/DoubleStepper.class",
+    "scala/collection/IntStepper.class",
+    "scala/collection/LongStepper.class",
+    "scala/collection/immutable/DoubleVectorStepper.class",
+    "scala/collection/immutable/IntVectorStepper.class",
+    "scala/collection/immutable/LongVectorStepper.class",
+    "scala/jdk/DoubleAccumulator.class",
+    "scala/jdk/IntAccumulator.class",
+    "scala/jdk/LongAccumulator.class",
+    "scala/jdk/FunctionWrappers$FromJavaDoubleBinaryOperator.class",
+    "scala/jdk/FunctionWrappers$FromJavaBooleanSupplier.class",
+    "scala/jdk/FunctionWrappers$FromJavaDoubleConsumer.class",
+    "scala/jdk/FunctionWrappers$FromJavaDoublePredicate.class",
+    "scala/jdk/FunctionWrappers$FromJavaDoubleSupplier.class",
+    "scala/jdk/FunctionWrappers$FromJavaDoubleToIntFunction.class",
+    "scala/jdk/FunctionWrappers$FromJavaDoubleToLongFunction.class",
+    "scala/jdk/FunctionWrappers$FromJavaIntBinaryOperator.class",
+    "scala/jdk/FunctionWrappers$FromJavaDoubleUnaryOperator.class",
+    "scala/jdk/FunctionWrappers$FromJavaIntPredicate.class",
+    "scala/jdk/FunctionWrappers$FromJavaIntConsumer.class",
+    "scala/jdk/FunctionWrappers$FromJavaIntSupplier.class",
+    "scala/jdk/FunctionWrappers$FromJavaIntToDoubleFunction.class",
+    "scala/jdk/FunctionWrappers$FromJavaIntToLongFunction.class",
+    "scala/jdk/FunctionWrappers$FromJavaIntUnaryOperator.class",
+    "scala/jdk/FunctionWrappers$FromJavaLongBinaryOperator.class",
+    "scala/jdk/FunctionWrappers$FromJavaLongConsumer.class",
+    "scala/jdk/FunctionWrappers$FromJavaLongPredicate.class",
+    "scala/jdk/FunctionWrappers$FromJavaLongSupplier.class",
+    "scala/jdk/FunctionWrappers$FromJavaLongToDoubleFunction.class",
+    "scala/jdk/FunctionWrappers$FromJavaLongToIntFunction.class",
+    "scala/jdk/FunctionWrappers$FromJavaLongUnaryOperator.class",
+    "scala/collection/ArrayOps$ReverseIterator.class",
+    "scala/runtime/NonLocalReturnControl.class",
+    "scala/util/Sorting.class", "scala/util/Sorting$.class",  // Contains @specialized annotation
+    )
+
+}