diff --git a/src/main/java/eu/mulk/aendggner/AendGgner.java b/src/main/java/eu/mulk/aendggner/AendGgner.java
index c4efd45..f7e6bf7 100644
--- a/src/main/java/eu/mulk/aendggner/AendGgner.java
+++ b/src/main/java/eu/mulk/aendggner/AendGgner.java
@@ -1,24 +1,24 @@
 package eu.mulk.aendggner;
 
-import java.io.BufferedReader;
+import eu.mulk.aendggner.aenderung.parse.AenderungsgesetzParser;
+import eu.mulk.aendggner.aenderung.parse.PatchTextExtraktor;
+import eu.mulk.aendggner.aenderung.parse.TextBereiniger;
+import eu.mulk.aendggner.anwendung.BefehlAnwender;
+import eu.mulk.aendggner.gesetz.gii.GiiXmlLoader;
+import eu.mulk.aendggner.synopse.HtmlRenderer;
+import eu.mulk.aendggner.synopse.SynopseBuilder;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.logging.LogManager;
-import org.apache.tika.config.TikaConfig;
-import org.apache.tika.exception.TikaException;
-import org.apache.tika.io.TikaInputStream;
-import org.apache.tika.metadata.Metadata;
-import org.apache.tika.parser.AutoDetectParser;
-import org.apache.tika.parser.ParseContext;
-import org.apache.tika.parser.Parser;
-import org.apache.tika.parser.ParsingReader;
 import org.jboss.logging.Logger;
-import org.xml.sax.SAXException;
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
 import picocli.CommandLine.Parameters;
 
 @Command(
@@ -30,55 +30,194 @@
 
   private static final Logger log = Logger.getLogger(AendGgner.class);
 
-  @Parameters(index = "0", description = "The base text to modify.")
+  @Parameters(index = "0", description = "The base law (gii-norm XML from gesetze-im-internet.de).")
   private Path baseFile;
 
-  @Parameters(arity = "*", description = "The diff relative to the base text.")
+  @Parameters(
+      index = "1..*",
+      arity = "*",
+      description = "The amendment act(s) to apply (BGBl PDF or plain text).")
   private List<Path> patches;
 
+  @Option(
+      names = {"-o", "--output"},
+      paramLabel = "<file>",
+      description =
+          "Output file for the HTML synopsis (default: ${DEFAULT-VALUE}; \"-\" = stdout).",
+      defaultValue = "synopse.html")
+  private String output;
+
+  @Option(names = "--vollstaendig", description = "Include unchanged provisions in the synopsis.")
+  private boolean vollstaendig;
+
+  @Option(
+      names = "--format",
+      paramLabel = "<format>",
+      description = "Output format (currently only: html).",
+      defaultValue = "html")
+  private String format;
+
+  @Option(
+      names = "--dump-gesetz",
+      hidden = true,
+      description = "Debug: dump the parsed base law structure and exit.")
+  private boolean dumpGesetz;
+
+  @Option(
+      names = "--extract-only",
+      description =
+          "Print the cleaned linear text of the amendment act and exit. "
+              + "Useful for inspecting and hand-correcting PDF extraction; "
+              + "the corrected text can be fed back in as a plain-text patch file.")
+  private boolean extractOnly;
+
+  @Option(
+      names = "--raw",
+      hidden = true,
+      description = "Debug: with --extract-only, skip text cleanup.")
+  private boolean raw;
+
+  @Option(
+      names = "--dump-befehle",
+      hidden = true,
+      description = "Debug: dump the parsed amendment commands and exit.")
+  private boolean dumpBefehle;
+
+  @Option(
+      names = "--artikel",
+      paramLabel = "<n>",
+      description =
+          "Only apply this article of the amendment act "
+              + "(default: all articles whose introduction names the base law).")
+  private String artikel;
+
   public static void main(String... args) {
     int exitCode = new CommandLine(new AendGgner()).execute(args);
     System.exit(exitCode);
   }
 
   @Override
-  public final Integer call() throws TikaException, IOException, SAXException {
+  public final Integer call() throws Exception {
     setupLogging();
 
     log.debugf("Logging configured.");
 
-    TikaConfig tika;
-    try (var configResource =
-        this.getClass().getResourceAsStream("/eu/mulk/aendggner/tika-config.xml")) {
-      tika = new TikaConfig(configResource);
+    if (dumpGesetz) {
+      var gesetz = new GiiXmlLoader().load(baseFile);
+      System.out.printf(
+          "%s — %s (%d Normen)%n", gesetz.jurabk(), gesetz.langue(), gesetz.normen().size());
+      for (var norm : gesetz.normen()) {
+        System.out.printf(
+            "  %s%s — %d Absätze%s%n",
+            norm.enbez(),
+            norm.titel() == null ? "" : " (" + norm.titel() + ")",
+            norm.absaetze().size(),
+            norm.weggefallen() ? " [weggefallen]" : "");
+      }
+      return 0;
     }
 
+    if (extractOnly) {
+      var extraktor = new PatchTextExtraktor();
+      for (var file : patches) {
+        var text = extraktor.extrahiere(file);
+        System.out.println(raw ? text : TextBereiniger.bereinige(text));
+      }
+      return 0;
+    }
+
+    if (dumpBefehle) {
+      var gesetz = new GiiXmlLoader().load(baseFile);
+      var extraktor = new PatchTextExtraktor();
+      var parser = new AenderungsgesetzParser();
+      for (var file : patches) {
+        var text = TextBereiniger.bereinige(extraktor.extrahiere(file));
+        var ergebnis = parser.parse(text, gesetz, artikel);
+        System.out.printf(
+            "%s: %d Befehle aus Artikel %s%n",
+            file.getFileName(), ergebnis.befehle().size(), ergebnis.artikel());
+        for (var warnung : ergebnis.warnungen()) {
+          System.err.println("WARNUNG: " + warnung);
+        }
+        var anwendung = BefehlAnwender.anwenden(gesetz, ergebnis.befehle());
+        for (var eintrag : anwendung.protokoll()) {
+          var befehl = eintrag.befehl();
+          System.out.printf(
+              "  [%s] %s @ %s → %s%s%n      %s%n",
+              befehl.getClass().getSimpleName(),
+              befehl.provenienz().anzeigeText(),
+              befehl.stelle().anzeigeText(),
+              eintrag.status(),
+              eintrag.begruendung().isEmpty() ? "" : " (" + eintrag.begruendung() + ")",
+              kuerze(befehl.provenienz().originalText()));
+        }
+        System.out.printf(
+            "Angewandt: %d, manuell prüfen: %d%n",
+            anwendung.anzahlAngewandt(), anwendung.anzahlManuell());
+        gesetz = anwendung.neu();
+      }
+      return 0;
+    }
+
+    if (patches == null || patches.isEmpty()) {
+      System.err.println("Fehler: mindestens ein Änderungsgesetz muss angegeben werden.");
+      return 1;
+    }
+    if (!format.equals("html")) {
+      System.err.println("Fehler: unbekanntes Ausgabeformat „" + format + "“ (unterstützt: html).");
+      return 1;
+    }
+
+    // Pipeline: Stammgesetz laden → Befehle parsen → anwenden → Synopse rendern.
+    var altesGesetz = new GiiXmlLoader().load(baseFile);
+    var extraktor = new PatchTextExtraktor();
+    var parser = new AenderungsgesetzParser();
+
+    var gesetz = altesGesetz;
+    var protokoll = new ArrayList<BefehlAnwender.AngewandteAenderung>();
+    var warnungen = new ArrayList<String>();
+    var quellen = new ArrayList<String>();
+
     for (var file : patches) {
-      var metadata = new Metadata();
-      metadata.set(Metadata.RESOURCE_NAME_KEY, file.getFileName().toString());
-
-      try (var is = TikaInputStream.get(file)) {
-        var mimetype = tika.getDetector().detect(TikaInputStream.get(file), metadata);
-        log.infof("File %s is %s.", file, mimetype);
+      var text = TextBereiniger.bereinige(extraktor.extrahiere(file));
+      var parseErgebnis = parser.parse(text, gesetz, artikel);
+      if (parseErgebnis.befehle().isEmpty()) {
+        System.err.printf(
+            "Warnung: in %s wurde kein auf %s anwendbarer Artikel gefunden.%n",
+            file, gesetz.jurabk());
       }
-
-      var parser = new AutoDetectParser(tika);
-      try (var in = Files.newInputStream(file);
-          var reader =
-              new BufferedReader(
-                  new ParsingReader(parser, in, metadata, makeParseContext(parser)))) {
-        log.infof("%s: %d lines of text.", file, reader.lines().count());
-        // reader.lines().forEachOrdered(x -> log.infof("%s: %s", file, x));
-      }
+      var anwendung = BefehlAnwender.anwenden(gesetz, parseErgebnis.befehle());
+      gesetz = anwendung.neu();
+      protokoll.addAll(anwendung.protokoll());
+      warnungen.addAll(parseErgebnis.warnungen());
+      quellen.add(
+          file.getFileName() + " (Artikel " + String.join(", ", parseErgebnis.artikel()) + ")");
     }
 
-    return 0;
+    var gesamtErgebnis = new BefehlAnwender.AnwendungsErgebnis(gesetz, protokoll);
+    var synopse = SynopseBuilder.baue(altesGesetz, gesamtErgebnis, warnungen, vollstaendig);
+    var quelle = baseFile.getFileName() + " + " + String.join(" + ", quellen);
+    var html = HtmlRenderer.rendere(synopse, quelle);
+
+    if (output.equals("-")) {
+      System.out.println(html);
+    } else {
+      Files.writeString(Path.of(output), html, StandardCharsets.UTF_8);
+      log.infof("Synopse nach %s geschrieben.", output);
+    }
+
+    System.err.printf(
+        "%d Befehle angewandt, %d manuell zu prüfen, %d geänderte Normen.%n",
+        gesamtErgebnis.anzahlAngewandt(),
+        gesamtErgebnis.anzahlManuell(),
+        synopse.eintraege().size());
+
+    return gesamtErgebnis.anzahlAngewandt() == 0 && !protokoll.isEmpty() ? 2 : 0;
   }
 
-  private static ParseContext makeParseContext(Parser parser) {
-    var parseContext = new ParseContext();
-    parseContext.set(Parser.class, parser);
-    return parseContext;
+  private static String kuerze(String text) {
+    var einzeilig = text.replaceAll("\\s+", " ");
+    return einzeilig.length() <= 160 ? einzeilig : einzeilig.substring(0, 157) + "…";
   }
 
   private static void setupLogging() throws IOException {
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java b/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java
new file mode 100644
index 0000000..c44cfcf
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/Aenderungsbefehl.java
@@ -0,0 +1,87 @@
+package eu.mulk.aendggner.aenderung;
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Ein einzelner Änderungsbefehl eines Änderungsgesetzes, wie er im Handbuch der Rechtsförmlichkeit
+ * vorgesehen ist. Nicht erkannte Befehle landen als {@link UnbekannterBefehl} im Ergebnis — sie
+ * werden nie stillschweigend verworfen.
+ */
+public sealed interface Aenderungsbefehl {
+
+  /** Die betroffene Stelle im Stammgesetz. */
+  Stelle stelle();
+
+  /** Herkunft des Befehls im Änderungsgesetz. */
+  Provenienz provenienz();
+
+  /** Strukturelle Ebene eines eingefügten oder angefügten Elements. */
+  enum Ebene {
+    PARAGRAPH,
+    ABSATZ,
+    SATZ,
+    NUMMER,
+    BUCHSTABE
+  }
+
+  /** Anker für Wörter-Einfügungen innerhalb eines Textbereichs. */
+  sealed interface WortAnker {
+    record NachWoertern(String woerter) implements WortAnker {}
+
+    record VorWoertern(String woerter) implements WortAnker {}
+
+    record AmEnde() implements WortAnker {}
+
+    record VorKommaAmEnde() implements WortAnker {}
+  }
+
+  /** „… werden die Wörter „A“ durch die Wörter „B“ ersetzt.“ */
+  record Ersetzung(
+      Stelle stelle, String alt, String neu, boolean jeweils, boolean amEnde, Provenienz provenienz)
+      implements Aenderungsbefehl {}
+
+  /** „§ X wird wie folgt gefasst: „…““ */
+  record Neufassung(Stelle stelle, String neuerText, Provenienz provenienz)
+      implements Aenderungsbefehl {}
+
+  /** „… werden nach dem Wort „A“ die Wörter „B“ eingefügt.“ */
+  record WoerterEinfuegung(Stelle stelle, WortAnker anker, String woerter, Provenienz provenienz)
+      implements Aenderungsbefehl {}
+
+  /**
+   * „Nach § 28 wird folgender § 28a eingefügt: „…““
+   *
+   * @param stelle die Ankerstelle, relativ zu der eingefügt wird.
+   * @param vorher {@code true} bei „Vor …“, {@code false} bei „Nach …“.
+   * @param bezeichnung die Bezeichnung des neuen Elements (z.B. „28a“, „5a“); {@code null}, wenn
+   *     der Befehl keine nennt (z.B. „folgender Satz“).
+   */
+  record StrukturEinfuegung(
+      Stelle stelle,
+      boolean vorher,
+      Ebene ebene,
+      @Nullable String bezeichnung,
+      String text,
+      Provenienz provenienz)
+      implements Aenderungsbefehl {}
+
+  /** „Folgender Absatz 9 wird angefügt: „…““ / „Dem Absatz 3 wird folgender Satz angefügt: …“ */
+  record Anfuegung(
+      Stelle stelle, Ebene ebene, @Nullable String bezeichnung, String text, Provenienz provenienz)
+      implements Aenderungsbefehl {}
+
+  /** „§ X / Absatz Y wird aufgehoben.“ */
+  record Aufhebung(Stelle stelle, Provenienz provenienz) implements Aenderungsbefehl {}
+
+  /** „… werden die Wörter „A“ gestrichen.“ */
+  record Streichung(Stelle stelle, String woerter, Provenienz provenienz)
+      implements Aenderungsbefehl {}
+
+  /** „Der bisherige Absatz 2 wird Absatz 3.“ */
+  record Umnummerierung(Stelle stelle, Stelle neu, Provenienz provenienz)
+      implements Aenderungsbefehl {}
+
+  /** Fallback für alles, was der Parser nicht versteht — muss manuell geprüft werden. */
+  record UnbekannterBefehl(Stelle stelle, String originalText, Provenienz provenienz)
+      implements Aenderungsbefehl {}
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/Provenienz.java b/src/main/java/eu/mulk/aendggner/aenderung/Provenienz.java
new file mode 100644
index 0000000..07a1087
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/Provenienz.java
@@ -0,0 +1,17 @@
+package eu.mulk.aendggner.aenderung;
+
+/**
+ * Herkunft eines Änderungsbefehls im Änderungsgesetz.
+ *
+ * @param artikel die Artikelbezeichnung, z.B. „1“ oder „2a“.
+ * @param gliederungsPfad der Pfad der Gliederungspunkte, z.B. „7. a) aa)“.
+ * @param originalText der ursprüngliche Befehlstext (mit Zitaten).
+ */
+public record Provenienz(String artikel, String gliederungsPfad, String originalText) {
+
+  public String anzeigeText() {
+    return gliederungsPfad.isEmpty()
+        ? "Artikel " + artikel
+        : "Artikel " + artikel + " " + gliederungsPfad;
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/Stelle.java b/src/main/java/eu/mulk/aendggner/aenderung/Stelle.java
new file mode 100644
index 0000000..0bcceb6
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/Stelle.java
@@ -0,0 +1,100 @@
+package eu.mulk.aendggner.aenderung;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Eine Fundstelle im Stammgesetz, als Stapel immer feinerer Komponenten (z.B. „§ 5 Absatz 2 Satz
+ * 1“). Verschachtelte Änderungsbefehle konkatenieren ihre Stellen mit {@link #plus}.
+ */
+public record Stelle(List<Komponente> komponenten) {
+
+  public static final Stelle LEER = new Stelle(List.of());
+
+  public Stelle {
+    komponenten = List.copyOf(komponenten);
+  }
+
+  public sealed interface Komponente
+      permits Paragraph, AbsatzNr, SatzNr, NummerNr, BuchstabeNr, Ueberschrift, Inhaltsuebersicht {}
+
+  /** „§ 5“, „§ 28a“ — die Paragraphennummer ohne „§ “. */
+  public record Paragraph(String nummer) implements Komponente {}
+
+  /** „Absatz 2“ */
+  public record AbsatzNr(String nummer) implements Komponente {}
+
+  /** „Satz 1“ */
+  public record SatzNr(String nummer) implements Komponente {}
+
+  /** „Nummer 4“ */
+  public record NummerNr(String nummer) implements Komponente {}
+
+  /** „Buchstabe c“ (auch Doppelbuchstabe „aa“) */
+  public record BuchstabeNr(String kennung) implements Komponente {}
+
+  /** „Die Überschrift“ */
+  public record Ueberschrift() implements Komponente {}
+
+  /** „In der Inhaltsübersicht“ */
+  public record Inhaltsuebersicht() implements Komponente {}
+
+  public boolean istLeer() {
+    return komponenten.isEmpty();
+  }
+
+  public Stelle plus(Stelle feiner) {
+    if (feiner.istLeer()) {
+      return this;
+    }
+    var neu = new ArrayList<>(komponenten);
+    neu.addAll(feiner.komponenten);
+    return new Stelle(neu);
+  }
+
+  public Optional<Paragraph> paragraph() {
+    return komponenten.stream()
+        .filter(Paragraph.class::isInstance)
+        .map(Paragraph.class::cast)
+        .findFirst();
+  }
+
+  public Optional<AbsatzNr> absatz() {
+    return komponenten.stream()
+        .filter(AbsatzNr.class::isInstance)
+        .map(AbsatzNr.class::cast)
+        .findFirst();
+  }
+
+  public boolean betrifftInhaltsuebersicht() {
+    return komponenten.stream().anyMatch(Inhaltsuebersicht.class::isInstance);
+  }
+
+  public boolean betrifftUeberschrift() {
+    return komponenten.stream().anyMatch(Ueberschrift.class::isInstance);
+  }
+
+  public String anzeigeText() {
+    if (komponenten.isEmpty()) {
+      return "(gesamtes Gesetz)";
+    }
+    var sb = new StringBuilder();
+    for (var komponente : komponenten) {
+      if (sb.length() > 0) {
+        sb.append(' ');
+      }
+      sb.append(
+          switch (komponente) {
+            case Paragraph p -> "§ " + p.nummer();
+            case AbsatzNr a -> "Absatz " + a.nummer();
+            case SatzNr s -> "Satz " + s.nummer();
+            case NummerNr n -> "Nummer " + n.nummer();
+            case BuchstabeNr b -> "Buchstabe " + b.kennung();
+            case Ueberschrift u -> "Überschrift";
+            case Inhaltsuebersicht i -> "Inhaltsübersicht";
+          });
+    }
+    return sb.toString();
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/AenderungsgesetzParser.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/AenderungsgesetzParser.java
new file mode 100644
index 0000000..085da2a
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/AenderungsgesetzParser.java
@@ -0,0 +1,150 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.UnbekannterBefehl;
+import eu.mulk.aendggner.aenderung.Provenienz;
+import eu.mulk.aendggner.aenderung.Stelle;
+import eu.mulk.aendggner.gesetz.Gesetz;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+import org.jboss.logging.Logger;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Parst den bereinigten Lineartext eines Änderungsgesetzes zu einer Liste von Änderungsbefehlen.
+ *
+ * <p>Es werden nur Artikel berücksichtigt, deren Einleitung das Zielgesetz nennt (per {@code
+ * artikelFilter} übersteuerbar). Nicht erkannte Befehle erscheinen als {@link UnbekannterBefehl} im
+ * Ergebnis.
+ */
+public final class AenderungsgesetzParser {
+
+  private static final Logger log = Logger.getLogger(AenderungsgesetzParser.class);
+
+  private static final Pattern ARTIKEL_UEBERSCHRIFT = Pattern.compile("^Artikel\\s+(\\d+[a-z]?)$");
+
+  public record ParseErgebnis(
+      List<Aenderungsbefehl> befehle, List<String> artikel, List<String> warnungen) {}
+
+  /**
+   * @param text der bereinigte Lineartext des Änderungsgesetzes.
+   * @param ziel das Stammgesetz, dessen Änderungsartikel angewandt werden sollen.
+   * @param artikelFilter nur diesen Artikel berücksichtigen (z.B. „1“); {@code null} = alle
+   *     Artikel, deren Einleitung das Zielgesetz nennt.
+   */
+  public ParseErgebnis parse(String text, Gesetz ziel, @Nullable String artikelFilter) {
+    var zitate = ZitatExtraktor.extrahiere(text);
+    var artikelBloecke = teileInArtikel(zitate.text());
+
+    var befehle = new ArrayList<Aenderungsbefehl>();
+    var betroffeneArtikel = new ArrayList<String>();
+
+    for (var artikel : artikelBloecke) {
+      var relevant =
+          artikelFilter != null
+              ? artikel.label.equals(artikelFilter)
+              : betrifft(artikel, ziel, zitate);
+      if (!relevant) {
+        continue;
+      }
+      log.infof("Artikel %s betrifft %s.", artikel.label, ziel.jurabk());
+      betroffeneArtikel.add(artikel.label);
+
+      var scan = GliederungsScanner.scanne(artikel.zeilen);
+      if (scan.punkte().isEmpty()) {
+        befehle.add(
+            new UnbekannterBefehl(
+                Stelle.LEER,
+                zitate.stelleZitateWiederHer(scan.vorspann()),
+                new Provenienz(artikel.label, "", zitate.stelleZitateWiederHer(scan.vorspann()))));
+        continue;
+      }
+      for (var punkt : scan.punkte()) {
+        verarbeitePunkt(punkt, Stelle.LEER, artikel.label, "", zitate, befehle);
+      }
+    }
+
+    return new ParseErgebnis(befehle, betroffeneArtikel, zitate.warnungen());
+  }
+
+  private static void verarbeitePunkt(
+      GliederungsScanner.GliederungsPunkt punkt,
+      Stelle kontext,
+      String artikelLabel,
+      String pfad,
+      ZitatExtraktor.Ergebnis zitate,
+      List<Aenderungsbefehl> befehle) {
+
+    var eigenerPfad = pfad.isEmpty() ? markerText(punkt) : pfad + " " + markerText(punkt);
+    var text = punkt.text().replaceAll("\\s+", " ").strip();
+    var provenienz = new Provenienz(artikelLabel, eigenerPfad, zitate.stelleZitateWiederHer(text));
+
+    if (!punkt.kinder().isEmpty()) {
+      // Ein Punkt mit Unterpunkten muss ein Kontextrahmen sein („§ X wird wie folgt geändert:“).
+      var rahmen = BefehlErkenner.kontextRahmen(text);
+      var neuerKontext = kontext;
+      if (rahmen.isPresent()) {
+        neuerKontext = kontext.plus(rahmen.get());
+      } else {
+        befehle.add(new UnbekannterBefehl(kontext, provenienz.originalText(), provenienz));
+      }
+      for (var kind : punkt.kinder()) {
+        verarbeitePunkt(kind, neuerKontext, artikelLabel, eigenerPfad, zitate, befehle);
+      }
+      return;
+    }
+
+    // Blattpunkt: einzelner Befehl.
+    var befehl = BefehlErkenner.erkenne(text, kontext, zitate, provenienz);
+    befehle.add(
+        befehl.orElseGet(
+            () -> new UnbekannterBefehl(kontext, provenienz.originalText(), provenienz)));
+  }
+
+  private static String markerText(GliederungsScanner.GliederungsPunkt punkt) {
+    return punkt.label().matches("\\d+[a-z]?") ? punkt.label() + "." : punkt.label() + ")";
+  }
+
+  private record ArtikelBlock(String label, List<String> zeilen) {}
+
+  private static List<ArtikelBlock> teileInArtikel(String platzhalterText) {
+    var bloecke = new ArrayList<ArtikelBlock>();
+    String aktuellesLabel = null;
+    var aktuelleZeilen = new ArrayList<String>();
+
+    for (var zeile : platzhalterText.split("\n", -1)) {
+      var matcher = ARTIKEL_UEBERSCHRIFT.matcher(zeile.strip());
+      if (matcher.matches()) {
+        if (aktuellesLabel != null) {
+          bloecke.add(new ArtikelBlock(aktuellesLabel, List.copyOf(aktuelleZeilen)));
+        }
+        aktuellesLabel = matcher.group(1);
+        aktuelleZeilen.clear();
+      } else if (aktuellesLabel != null) {
+        aktuelleZeilen.add(zeile);
+      }
+    }
+    if (aktuellesLabel != null) {
+      bloecke.add(new ArtikelBlock(aktuellesLabel, List.copyOf(aktuelleZeilen)));
+    }
+    return bloecke;
+  }
+
+  /**
+   * Ein Artikel betrifft das Zielgesetz, wenn seine Einleitung (Text vor dem ersten
+   * Gliederungspunkt) den Namen oder die Abkürzung des Gesetzes zusammen mit der Änderungsformel
+   * nennt.
+   */
+  private static boolean betrifft(
+      ArtikelBlock artikel, Gesetz ziel, ZitatExtraktor.Ergebnis zitate) {
+    var scan = GliederungsScanner.scanne(artikel.zeilen);
+    var vorspann = scan.vorspann().replaceAll("\\s+", " ");
+    if (!vorspann.contains("wird wie folgt geändert")) {
+      return false;
+    }
+    return (ziel.kurzue() != null && vorspann.contains(ziel.kurzue()))
+        || (ziel.langue() != null && vorspann.contains(ziel.langue()))
+        || vorspann.matches(".*\\b" + Pattern.quote(ziel.jurabk()) + "\\b.*");
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java
new file mode 100644
index 0000000..55155dd
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/BefehlErkenner.java
@@ -0,0 +1,355 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Anfuegung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Aufhebung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ebene;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ersetzung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Neufassung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Streichung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturEinfuegung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Umnummerierung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WoerterEinfuegung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortAnker;
+import eu.mulk.aendggner.aenderung.Provenienz;
+import eu.mulk.aendggner.aenderung.Stelle;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Erkennt einzelne Änderungsbefehle in platzhalter-substituiertem Text (siehe {@link
+ * ZitatExtraktor}; «n» steht für das n-te Zitat).
+ *
+ * <p>Die Muster folgen den Formulierungen des Handbuchs der Rechtsförmlichkeit. Was hier nicht
+ * erkannt wird, stuft der Aufrufer als {@link Aenderungsbefehl.UnbekannterBefehl} ein.
+ */
+final class BefehlErkenner {
+
+  // Wiederkehrende Bausteine.
+  private static final String WOERTER = "(?:die Wörter|das Wort|die Angabe|die Zahl)";
+  private static final String Z = "«(\\d+)»";
+
+  private static final Pattern KONTEXT =
+      Pattern.compile("^(?:In )?(.+?) (?:wird|werden) wie folgt geändert:$");
+
+  private static final Pattern NEUFASSUNG =
+      Pattern.compile("^(.+?) (?:wird|werden) wie folgt gefasst: " + Z + "\\.?$");
+
+  private static final Pattern ERSETZUNG =
+      Pattern.compile(
+          "^(?:In )?(.+?) (?:wird|werden) (jeweils )?"
+              + WOERTER
+              + " "
+              + Z
+              + " (?:jeweils )?durch "
+              + WOERTER
+              + " "
+              + Z
+              + " ersetzt\\.$");
+
+  private static final Pattern ERSETZUNG_OHNE_STELLE =
+      Pattern.compile(
+          "^(?:Die Wörter|Das Wort|Die Angabe|Die Zahl) "
+              + Z
+              + " (?:wird|werden) (jeweils )?durch "
+              + WOERTER
+              + " "
+              + Z
+              + " ersetzt\\.$");
+
+  private static final Pattern SATZZEICHEN_ERSETZUNG =
+      Pattern.compile(
+          "^(?:In )?(.+?) (?:wird|werden) (der Punkt|das Komma|das Semikolon) am Ende durch "
+              + "(ein Komma|einen Punkt|ein Semikolon|"
+              + WOERTER
+              + " "
+              + Z
+              + ") ersetzt\\.$");
+
+  private static final Pattern WOERTER_EINFUEGUNG =
+      Pattern.compile(
+          "^(?:In )?(.+?) (?:wird|werden) (nach|vor) (?:dem Wort|den Wörtern|der Angabe|der Zahl) "
+              + Z
+              + " "
+              + WOERTER
+              + " "
+              + Z
+              + " eingefügt\\.$");
+
+  private static final Pattern WOERTER_EINFUEGUNG_VOR_KOMMA =
+      Pattern.compile(
+          "^(?:In )?(.+?) (?:wird|werden) vor dem Komma am Ende "
+              + WOERTER
+              + " "
+              + Z
+              + " eingefügt\\.$");
+
+  private static final Pattern WOERTER_ANFUEGUNG =
+      Pattern.compile(
+          "^(?:In |Dem |Der )?(.+?) (?:wird|werden) " + WOERTER + " " + Z + " angefügt\\.$");
+
+  private static final Pattern STRUKTUR_EINFUEGUNG =
+      Pattern.compile(
+          "^(Nach|Vor) (.+?) (?:wird|werden) (?:der |die |das )?folgende[rs]? (.+?) eingefügt: "
+              + Z
+              + "\\.?$");
+
+  private static final Pattern STRUKTUR_ANFUEGUNG_MIT_STELLE =
+      Pattern.compile(
+          "^(?:Dem|Der) (.+?) (?:wird|werden) (?:der |die |das )?folgende[rs]? (.+?) angefügt: "
+              + Z
+              + "\\.?$");
+
+  private static final Pattern STRUKTUR_ANFUEGUNG =
+      Pattern.compile(
+          "^(?:Der |Die |Das )?[Ff]olgende[rs]? (.+?) (?:wird|werden) angefügt: " + Z + "\\.?$");
+
+  private static final Pattern AUFHEBUNG = Pattern.compile("^(.+?) (?:wird|werden) aufgehoben\\.$");
+
+  private static final Pattern STREICHUNG =
+      Pattern.compile("^(?:In )?(.+?) (?:wird|werden) " + WOERTER + " " + Z + " gestrichen\\.$");
+
+  private static final Pattern UMNUMMERIERUNG =
+      Pattern.compile("^(?:Der bisherige )?(.+?) wird (Absatz|Satz) (\\d+[a-z]?)\\.$");
+
+  private static final Pattern INHALTSUEBERSICHT_EINFUEGUNG =
+      Pattern.compile(
+          "^In der Inhaltsübersicht (?:wird|werden) (nach|vor) der Angabe zu (§ \\S+?) "
+              + "(?:die |der |das )?folgende Angabe(?:n)? eingefügt: "
+              + Z
+              + "\\.?$");
+
+  private static final Pattern EBENE_BEZEICHNUNG =
+      Pattern.compile(
+          "^(?:§ (\\d+[a-z]?)|Absatz (\\d+[a-z]?)|Satz(?: (\\d+[a-z]?))?|Sätze"
+              + "|Nummer (\\d+[a-z]?)|Buchstabe ([a-z]{1,3}))$");
+
+  private BefehlErkenner() {}
+
+  /** Prüft, ob der Text ein Kontextrahmen („§ X wird wie folgt geändert:“) ist. */
+  static Optional<Stelle> kontextRahmen(String text) {
+    var matcher = KONTEXT.matcher(text);
+    if (!matcher.matches()) {
+      return Optional.empty();
+    }
+    return StellenParser.parse(matcher.group(1));
+  }
+
+  /**
+   * Versucht, den Text als Änderungsbefehl zu erkennen.
+   *
+   * @param text platzhalter-substituierter, whitespace-normalisierter Befehlstext.
+   * @param kontext die aus umgebenden Kontextrahmen geerbte Stelle.
+   * @param zitate die extrahierten Zitate zur Auflösung der Platzhalter.
+   * @param provenienz Herkunftsangabe für den Befehl.
+   */
+  static Optional<Aenderungsbefehl> erkenne(
+      String text, Stelle kontext, ZitatExtraktor.Ergebnis zitate, Provenienz provenienz) {
+
+    Matcher m;
+
+    if ((m = NEUFASSUNG.matcher(text)).matches()) {
+      var neuerText = zitat(zitate, m.group(2));
+      return StellenParser.parse(m.group(1))
+          .map(s -> new Neufassung(kontext.plus(s), neuerText, provenienz));
+    }
+
+    if ((m = ERSETZUNG.matcher(text)).matches()) {
+      var jeweils = m.group(2) != null || text.contains(" jeweils durch ");
+      var alt = wortZitat(zitate, m.group(3));
+      var neu = wortZitat(zitate, m.group(4));
+      var stelle = StellenParser.parse(m.group(1));
+      var effektivesJeweils = jeweils;
+      return stelle.map(
+          s -> new Ersetzung(kontext.plus(s), alt, neu, effektivesJeweils, false, provenienz));
+    }
+
+    if ((m = ERSETZUNG_OHNE_STELLE.matcher(text)).matches()) {
+      var jeweils = m.group(2) != null;
+      return Optional.of(
+          new Ersetzung(
+              kontext,
+              wortZitat(zitate, m.group(1)),
+              wortZitat(zitate, m.group(3)),
+              jeweils,
+              false,
+              provenienz));
+    }
+
+    if ((m = SATZZEICHEN_ERSETZUNG.matcher(text)).matches()) {
+      var alt = satzzeichen(m.group(2));
+      var neu = m.group(4) != null ? wortZitat(zitate, m.group(4)) : satzzeichen(m.group(3));
+      var neuText = neu;
+      return StellenParser.parse(m.group(1))
+          .map(s -> new Ersetzung(kontext.plus(s), alt, neuText, false, true, provenienz));
+    }
+
+    if ((m = WOERTER_EINFUEGUNG.matcher(text)).matches()) {
+      var ankerWoerter = wortZitat(zitate, m.group(3));
+      var anker =
+          m.group(2).equals("nach")
+              ? new WortAnker.NachWoertern(ankerWoerter)
+              : new WortAnker.VorWoertern(ankerWoerter);
+      var woerter = wortZitat(zitate, m.group(4));
+      return StellenParser.parse(m.group(1))
+          .map(s -> new WoerterEinfuegung(kontext.plus(s), anker, woerter, provenienz));
+    }
+
+    if ((m = WOERTER_EINFUEGUNG_VOR_KOMMA.matcher(text)).matches()) {
+      var woerter = wortZitat(zitate, m.group(2));
+      return StellenParser.parse(m.group(1))
+          .map(
+              s ->
+                  new WoerterEinfuegung(
+                      kontext.plus(s), new WortAnker.VorKommaAmEnde(), woerter, provenienz));
+    }
+
+    if ((m = INHALTSUEBERSICHT_EINFUEGUNG.matcher(text)).matches()) {
+      var anker =
+          m.group(1).equals("nach")
+              ? new WortAnker.NachWoertern("Angabe zu " + m.group(2))
+              : new WortAnker.VorWoertern("Angabe zu " + m.group(2));
+      return Optional.of(
+          new WoerterEinfuegung(
+              kontext.plus(new Stelle(java.util.List.of(new Stelle.Inhaltsuebersicht()))),
+              anker,
+              wortZitat(zitate, m.group(3)),
+              provenienz));
+    }
+
+    if ((m = STRUKTUR_EINFUEGUNG.matcher(text)).matches()) {
+      var vorher = m.group(1).equals("Vor");
+      var stelle = StellenParser.parse(m.group(2));
+      var ebeneBez = ebeneUndBezeichnung(m.group(3));
+      var textInhalt = zitat(zitate, m.group(4));
+      if (stelle.isEmpty() || ebeneBez.isEmpty()) {
+        return Optional.empty();
+      }
+      return Optional.of(
+          new StrukturEinfuegung(
+              kontext.plus(stelle.get()),
+              vorher,
+              ebeneBez.get().ebene(),
+              ebeneBez.get().bezeichnung(),
+              textInhalt,
+              provenienz));
+    }
+
+    if ((m = STRUKTUR_ANFUEGUNG_MIT_STELLE.matcher(text)).matches()) {
+      var stelle = StellenParser.parse(m.group(1));
+      var ebeneBez = ebeneUndBezeichnung(m.group(2));
+      var textInhalt = zitat(zitate, m.group(3));
+      if (stelle.isEmpty() || ebeneBez.isEmpty()) {
+        return Optional.empty();
+      }
+      return Optional.of(
+          new Anfuegung(
+              kontext.plus(stelle.get()),
+              ebeneBez.get().ebene(),
+              ebeneBez.get().bezeichnung(),
+              textInhalt,
+              provenienz));
+    }
+
+    if ((m = STRUKTUR_ANFUEGUNG.matcher(text)).matches()) {
+      var ebeneBez = ebeneUndBezeichnung(m.group(1));
+      var textInhalt = zitat(zitate, m.group(2));
+      if (ebeneBez.isEmpty()) {
+        return Optional.empty();
+      }
+      return Optional.of(
+          new Anfuegung(
+              kontext,
+              ebeneBez.get().ebene(),
+              ebeneBez.get().bezeichnung(),
+              textInhalt,
+              provenienz));
+    }
+
+    if ((m = WOERTER_ANFUEGUNG.matcher(text)).matches()) {
+      var woerter = wortZitat(zitate, m.group(2));
+      return StellenParser.parse(m.group(1))
+          .map(
+              s ->
+                  new WoerterEinfuegung(
+                      kontext.plus(s), new WortAnker.AmEnde(), woerter, provenienz));
+    }
+
+    if ((m = AUFHEBUNG.matcher(text)).matches()) {
+      return StellenParser.parse(m.group(1)).map(s -> new Aufhebung(kontext.plus(s), provenienz));
+    }
+
+    if ((m = STREICHUNG.matcher(text)).matches()) {
+      var woerter = wortZitat(zitate, m.group(2));
+      return StellenParser.parse(m.group(1))
+          .map(s -> new Streichung(kontext.plus(s), woerter, provenienz));
+    }
+
+    if ((m = UMNUMMERIERUNG.matcher(text)).matches()) {
+      var neu = komponenteFuer(m.group(2), m.group(3));
+      return StellenParser.parse(m.group(1))
+          .map(
+              alt ->
+                  new Umnummerierung(
+                      kontext.plus(alt),
+                      kontext.plus(new Stelle(java.util.List.of(neu))),
+                      provenienz));
+    }
+
+    return Optional.empty();
+  }
+
+  private record EbeneBezeichnung(Ebene ebene, String bezeichnung) {}
+
+  private static Optional<EbeneBezeichnung> ebeneUndBezeichnung(String phrase) {
+    var m = EBENE_BEZEICHNUNG.matcher(phrase.strip());
+    if (!m.matches()) {
+      return Optional.empty();
+    }
+    if (m.group(1) != null) {
+      return Optional.of(new EbeneBezeichnung(Ebene.PARAGRAPH, m.group(1)));
+    }
+    if (m.group(2) != null) {
+      return Optional.of(new EbeneBezeichnung(Ebene.ABSATZ, m.group(2)));
+    }
+    if (m.group(4) != null) {
+      return Optional.of(new EbeneBezeichnung(Ebene.NUMMER, m.group(4)));
+    }
+    if (m.group(5) != null) {
+      return Optional.of(new EbeneBezeichnung(Ebene.BUCHSTABE, m.group(5)));
+    }
+    // „Satz“, „Satz 3“ oder „Sätze“.
+    return Optional.of(new EbeneBezeichnung(Ebene.SATZ, m.group(3)));
+  }
+
+  private static Stelle.Komponente komponenteFuer(String ebene, String nummer) {
+    return switch (ebene) {
+      case "Absatz" -> new Stelle.AbsatzNr(nummer);
+      case "Satz" -> new Stelle.SatzNr(nummer);
+      default -> throw new IllegalArgumentException("Unbekannte Ebene: " + ebene);
+    };
+  }
+
+  /** Zitat für Textblöcke (Neufassung, Einfügung ganzer Einheiten): Zeilenstruktur erhalten. */
+  private static String zitat(ZitatExtraktor.Ergebnis zitate, String index) {
+    return zitate.zitat(Integer.parseInt(index));
+  }
+
+  /**
+   * Zitat für wortweise Operationen (alt/neu-Wörter, Anker): Whitespace normalisieren, denn im PDF
+   * umbrochene Zitate enthalten Zeilenumbrüche, der Stammgesetztext aber nicht.
+   */
+  private static String wortZitat(ZitatExtraktor.Ergebnis zitate, String index) {
+    return zitat(zitate, index).replaceAll("\\s+", " ").strip();
+  }
+
+  private static String satzzeichen(String phrase) {
+    return switch (phrase) {
+      case "der Punkt", "einen Punkt" -> ".";
+      case "das Komma", "ein Komma" -> ",";
+      case "das Semikolon", "ein Semikolon" -> ";";
+      default -> throw new IllegalArgumentException("Unbekanntes Satzzeichen: " + phrase);
+    };
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/GliederungsScanner.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/GliederungsScanner.java
new file mode 100644
index 0000000..02024f9
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/GliederungsScanner.java
@@ -0,0 +1,159 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Zerlegt den Rumpf eines Artikels in einen Baum von Gliederungspunkten (1. → a) → aa)).
+ *
+ * <p>Arbeitet auf platzhalter-substituiertem Text (siehe {@link ZitatExtraktor}), sodass
+ * Gliederungsmarker innerhalb von Zitaten nicht stören können. Ein Marker am Zeilenanfang wird nur
+ * akzeptiert, wenn er entweder eine neue Ebene eröffnet („1.“, „a)“, „aa)“) oder der Nachfolger des
+ * letzten Markers seiner Ebene ist — sonst gilt die Zeile als Fortsetzungstext (das fängt z.B.
+ * Datumsangaben wie „18. November“ am Zeilenanfang ab).
+ */
+final class GliederungsScanner {
+
+  /** Ein Gliederungspunkt mit Marker-Label, Text und Unterpunkten. */
+  record GliederungsPunkt(String label, String text, List<GliederungsPunkt> kinder) {}
+
+  /** Ergebnis: Text vor dem ersten Gliederungspunkt (Einleitungssatz) und die Punkte selbst. */
+  record ScanErgebnis(String vorspann, List<GliederungsPunkt> punkte) {}
+
+  // Eingeschobene Punkte tragen Suffixe: „2a.“, „a1)“, „aa1)“.
+  private static final Pattern NUMMER_MARKER = Pattern.compile("^(\\d+[a-z]?)\\.\\s+(.*)$");
+  private static final Pattern BUCHSTABE_MARKER = Pattern.compile("^([a-z]\\d*)\\)\\s+(.*)$");
+  private static final Pattern DOPPELBUCHSTABE_MARKER =
+      Pattern.compile("^(([a-z])\\2\\d*)\\)\\s+(.*)$");
+
+  private GliederungsScanner() {}
+
+  static ScanErgebnis scanne(List<String> zeilen) {
+    var vorspann = new StringBuilder();
+    var wurzeln = new ArrayList<MutablerPunkt>();
+    var stapel = new ArrayDeque<MutablerPunkt>(); // offene Punkte, äußerster zuerst
+
+    for (var zeile : zeilen) {
+      var gestutzt = zeile.strip();
+      var marker = erkenneMarker(gestutzt);
+
+      if (marker != null && istAkzeptabel(marker, stapel)) {
+        // Tiefere offene Ebenen schließen.
+        while (!stapel.isEmpty() && stapel.peekLast().ebene >= marker.ebene) {
+          stapel.removeLast();
+        }
+        var punkt = new MutablerPunkt(marker.label, marker.ebene);
+        punkt.text.append(marker.rest);
+        if (stapel.isEmpty()) {
+          wurzeln.add(punkt);
+        } else {
+          stapel.peekLast().kinder.add(punkt);
+        }
+        stapel.addLast(punkt);
+      } else if (stapel.isEmpty()) {
+        vorspann.append(gestutzt).append('\n');
+      } else {
+        stapel.peekLast().text.append('\n').append(gestutzt);
+      }
+    }
+
+    return new ScanErgebnis(
+        vorspann.toString().strip(), wurzeln.stream().map(MutablerPunkt::zuRecord).toList());
+  }
+
+  private record Marker(String label, int ebene, String rest) {}
+
+  private static Marker erkenneMarker(String zeile) {
+    var doppel = DOPPELBUCHSTABE_MARKER.matcher(zeile);
+    if (doppel.matches()) {
+      return new Marker(doppel.group(1), 3, doppel.group(3));
+    }
+    var buchstabe = BUCHSTABE_MARKER.matcher(zeile);
+    if (buchstabe.matches()) {
+      return new Marker(buchstabe.group(1), 2, buchstabe.group(2));
+    }
+    var nummer = NUMMER_MARKER.matcher(zeile);
+    if (nummer.matches()) {
+      return new Marker(nummer.group(1), 1, nummer.group(2));
+    }
+    return null;
+  }
+
+  private static boolean istAkzeptabel(Marker marker, ArrayDeque<MutablerPunkt> stapel) {
+    // Nachfolger eines offenen Punkts derselben Ebene?
+    for (var offen : stapel) {
+      if (offen.ebene == marker.ebene) {
+        return istNachfolger(offen.label, marker.label);
+      }
+    }
+    // Sonst: nur ein Eröffnungslabel einer tieferen Ebene ist zulässig.
+    int aktuelleTiefe = stapel.isEmpty() ? 0 : stapel.peekLast().ebene;
+    return marker.ebene == aktuelleTiefe + 1 && istEroeffnung(marker);
+  }
+
+  private static boolean istEroeffnung(Marker marker) {
+    return switch (marker.ebene) {
+      case 1 -> marker.label.equals("1");
+      case 2 -> marker.label.equals("a");
+      case 3 -> marker.label.equals("aa");
+      default -> false;
+    };
+  }
+
+  private static boolean istNachfolger(String vorher, String nachher) {
+    if (vorher.matches("\\d+[a-z]?") && nachher.matches("\\d+[a-z]?")) {
+      var vorherZahl = Integer.parseInt(vorher.replaceAll("[a-z]$", ""));
+      var vorherSuffix = vorher.replaceAll("^\\d+", "");
+      var nachherZahl = Integer.parseInt(nachher.replaceAll("[a-z]$", ""));
+      var nachherSuffix = nachher.replaceAll("^\\d+", "");
+      // „2.“ → „3.“, „2.“ → „2a.“, „2a.“ → „2b.“, „2a.“ → „3.“
+      return (nachherZahl == vorherZahl + 1 && nachherSuffix.isEmpty())
+          || (nachherZahl == vorherZahl
+              && !nachherSuffix.isEmpty()
+              && (vorherSuffix.isEmpty()
+                  ? nachherSuffix.equals("a")
+                  : nachherSuffix.charAt(0) == vorherSuffix.charAt(0) + 1));
+    }
+    if (vorher.matches("[a-z]+\\d*") && nachher.matches("[a-z]+\\d*")) {
+      var vorherBasis = vorher.replaceAll("\\d+$", "");
+      var vorherSuffix = vorher.substring(vorherBasis.length());
+      var nachherBasis = nachher.replaceAll("\\d+$", "");
+      var nachherSuffix = nachher.substring(nachherBasis.length());
+      // „a)“ → „b)“, „a)“ → „a1)“, „a1)“ → „a2)“, „a1)“ → „b)“; analog „aa)“ → „bb)“ etc.
+      if (nachherBasis.equals(basisNachfolger(vorherBasis)) && nachherSuffix.isEmpty()) {
+        return true;
+      }
+      return nachherBasis.equals(vorherBasis)
+          && !nachherSuffix.isEmpty()
+          && (vorherSuffix.isEmpty()
+              ? nachherSuffix.equals("1")
+              : Integer.parseInt(nachherSuffix) == Integer.parseInt(vorherSuffix) + 1);
+    }
+    return false;
+  }
+
+  /** „a“ → „b“, „aa“ → „bb“. */
+  private static String basisNachfolger(String basis) {
+    var naechster = (char) (basis.charAt(0) + 1);
+    return String.valueOf(naechster).repeat(basis.length());
+  }
+
+  private static final class MutablerPunkt {
+    final String label;
+    final int ebene;
+    final StringBuilder text = new StringBuilder();
+    final List<MutablerPunkt> kinder = new ArrayList<>();
+
+    MutablerPunkt(String label, int ebene) {
+      this.label = label;
+      this.ebene = ebene;
+    }
+
+    GliederungsPunkt zuRecord() {
+      return new GliederungsPunkt(
+          label, text.toString().strip(), kinder.stream().map(MutablerPunkt::zuRecord).toList());
+    }
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/PatchTextExtraktor.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/PatchTextExtraktor.java
new file mode 100644
index 0000000..1b07d40
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/PatchTextExtraktor.java
@@ -0,0 +1,49 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.apache.pdfbox.Loader;
+import org.apache.pdfbox.text.PDFTextStripper;
+import org.apache.tika.Tika;
+import org.jboss.logging.Logger;
+
+/**
+ * Extrahiert den linearen Text eines Änderungsgesetzes aus einer Eingabedatei.
+ *
+ * <p>Klartextdateien werden wörtlich übernommen (der dokumentierte Ausweg, wenn die PDF-Extraktion
+ * versagt). PDFs werden mit PDFBox in Content-Stream-Reihenfolge extrahiert — BGBl-PDFs zeichnen
+ * ihren Text spaltenweise, sodass die Stream-Reihenfolge in der Regel der Lesereihenfolge
+ * entspricht, während Positionssortierung die beiden Spalten verschränken würde.
+ */
+public final class PatchTextExtraktor {
+
+  private static final Logger log = Logger.getLogger(PatchTextExtraktor.class);
+
+  private final Tika tika = new Tika();
+
+  public String extrahiere(Path datei) throws IOException {
+    var mimeType = tika.detect(datei);
+    log.infof("Datei %s hat Typ %s.", datei, mimeType);
+
+    return switch (mimeType) {
+      case "application/pdf" -> extrahierePdf(datei);
+      case "text/plain" -> Files.readString(datei, StandardCharsets.UTF_8);
+      default ->
+          throw new IOException(
+              "Nicht unterstützter Dateityp %s für %s (unterstützt: PDF, Klartext)"
+                  .formatted(mimeType, datei));
+    };
+  }
+
+  private static String extrahierePdf(Path datei) throws IOException {
+    try (var dokument = Loader.loadPDF(datei.toFile())) {
+      var stripper = new PDFTextStripper();
+      stripper.setSortByPosition(false);
+      stripper.setLineSeparator("\n");
+      stripper.setParagraphEnd("\n");
+      return stripper.getText(dokument);
+    }
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java
new file mode 100644
index 0000000..777b2d5
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/StellenParser.java
@@ -0,0 +1,105 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import eu.mulk.aendggner.aenderung.Stelle;
+import java.util.ArrayList;
+import java.util.Optional;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * Parst Stellenangaben wie „§ 5a Absatz 2 Satz 1 Nummer 4 Buchstabe c“, „der Inhaltsübersicht“ oder
+ * „Die Überschrift“.
+ *
+ * <p>Die gesamte Phrase muss aus bekannten Komponenten und Füllwörtern bestehen; andernfalls wird
+ * {@link Optional#empty()} geliefert (und der aufrufende Parser stuft den Befehl als unbekannt
+ * ein). Insbesondere fallen Bereichs- und Mehrfachangaben („Sätze 2 bis 4“, „Absatz 1 und 2“)
+ * absichtlich durch.
+ */
+public final class StellenParser {
+
+  private static final Set<String> FUELLWOERTER =
+      Set.of("in", "der", "die", "das", "dem", "den", "des");
+
+  private static final Pattern PARAGRAPH = Pattern.compile("§");
+  private static final Pattern NUMMER_WERT = Pattern.compile("\\d+[a-z]?");
+  private static final Pattern BUCHSTABE_WERT = Pattern.compile("[a-z]{1,3}");
+
+  private StellenParser() {}
+
+  public static Optional<Stelle> parse(String phrase) {
+    var woerter = phrase.strip().split("\\s+");
+    var komponenten = new ArrayList<Stelle.Komponente>();
+
+    for (int i = 0; i < woerter.length; i++) {
+      var wort = entfernePunktuation(woerter[i]);
+      if (wort.isEmpty() || FUELLWOERTER.contains(wort.toLowerCase())) {
+        continue;
+      }
+      switch (wort) {
+        case "§" -> {
+          var wert = naechstesWort(woerter, i);
+          if (wert == null || !NUMMER_WERT.matcher(wert).matches()) {
+            return Optional.empty();
+          }
+          komponenten.add(new Stelle.Paragraph(wert));
+          i++;
+        }
+        case "Absatz", "Abs." -> {
+          var wert = naechstesWort(woerter, i);
+          if (wert == null || !NUMMER_WERT.matcher(wert).matches()) {
+            return Optional.empty();
+          }
+          komponenten.add(new Stelle.AbsatzNr(wert));
+          i++;
+        }
+        case "Satz" -> {
+          var wert = naechstesWort(woerter, i);
+          if (wert == null || !NUMMER_WERT.matcher(wert).matches()) {
+            return Optional.empty();
+          }
+          komponenten.add(new Stelle.SatzNr(wert));
+          i++;
+        }
+        case "Nummer", "Nr." -> {
+          var wert = naechstesWort(woerter, i);
+          if (wert == null || !NUMMER_WERT.matcher(wert).matches()) {
+            return Optional.empty();
+          }
+          komponenten.add(new Stelle.NummerNr(wert));
+          i++;
+        }
+        case "Buchstabe", "Buchst.", "Doppelbuchstabe" -> {
+          var wert = naechstesWort(woerter, i);
+          if (wert == null || !BUCHSTABE_WERT.matcher(wert).matches()) {
+            return Optional.empty();
+          }
+          komponenten.add(new Stelle.BuchstabeNr(wert));
+          i++;
+        }
+        case "Inhaltsübersicht" -> komponenten.add(new Stelle.Inhaltsuebersicht());
+        case "Überschrift" -> komponenten.add(new Stelle.Ueberschrift());
+        default -> {
+          return Optional.empty();
+        }
+      }
+    }
+
+    if (komponenten.isEmpty()) {
+      return Optional.empty();
+    }
+    return Optional.of(new Stelle(komponenten));
+  }
+
+  private static String naechstesWort(String[] woerter, int i) {
+    return i + 1 < woerter.length ? entfernePunktuation(woerter[i + 1]) : null;
+  }
+
+  /** Entfernt anhängende Satzzeichen („§ 28,“ → „§ 28“), nicht aber den Punkt in „Abs.“/„Nr.“. */
+  private static String entfernePunktuation(String wort) {
+    var ergebnis = wort.strip();
+    while (!ergebnis.isEmpty() && ",;:".indexOf(ergebnis.charAt(ergebnis.length() - 1)) >= 0) {
+      ergebnis = ergebnis.substring(0, ergebnis.length() - 1);
+    }
+    return ergebnis;
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
new file mode 100644
index 0000000..3fd6a8c
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java
@@ -0,0 +1,104 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+/**
+ * Bereinigt aus PDFs extrahierten Rohtext eines Änderungsgesetzes: entfernt Kolumnentitel und
+ * Seitenzahlen des Bundesgesetzblatts, zieht Silbentrennungen am Zeilenende zusammen und
+ * normalisiert Anführungszeichen-Glyphen.
+ */
+public final class TextBereiniger {
+
+  private static final Pattern KOPFZEILE =
+      Pattern.compile("^\\s*(\\d{1,5}\\s+)?Bundesgesetzblatt Jahrgang \\d{4}.*$");
+  private static final Pattern SEITENZAHL = Pattern.compile("^\\s*\\d{1,5}\\s*$");
+  private static final Pattern BUNDESANZEIGER =
+      Pattern.compile(
+          "^\\s*(Das Bundesgesetzblatt im Internet:|Ein Service des Bundesanzeiger).*$");
+
+  private TextBereiniger() {}
+
+  public static String bereinige(String rohText) {
+    var text = normalisiereAnfuehrungszeichen(rohText);
+    var zeilen = entferneKolumnentitel(text);
+    return verbindeSilbentrennung(zeilen);
+  }
+
+  /**
+   * PDF-Extraktoren liefern je nach Schriftart unterschiedliche Glyphen für die deutschen
+   * Anführungszeichen; der Parser verlässt sich auf {@code „}/{@code “}.
+   */
+  private static String normalisiereAnfuehrungszeichen(String text) {
+    return text
+        // Doppelte Low-9- und gerade Anführungszeichen am Wortanfang → „
+        .replace('‚', '‘') // ‚ bleibt einfaches öffnendes Zitat
+        .replace("‟", "“") // ‟ → “
+        .replace("«", "„") // « → „ (selten, aus Fremdsatz)
+        .replace("»", "“"); // » → “
+  }
+
+  private static ArrayList<String> entferneKolumnentitel(String text) {
+    var ergebnis = new ArrayList<String>();
+    for (var zeile : text.split("\n", -1)) {
+      if (KOPFZEILE.matcher(zeile).matches()
+          || SEITENZAHL.matcher(zeile).matches()
+          || BUNDESANZEIGER.matcher(zeile).matches()) {
+        continue;
+      }
+      ergebnis.add(zeile.stripTrailing());
+    }
+    return ergebnis;
+  }
+
+  /** Konjunktionen, die typischerweise auf einen Suspensivstrich folgen („Wirk- und …“). */
+  private static final Pattern KONJUNKTION =
+      Pattern.compile("^(und|oder|sowie|bzw\\.|beziehungsweise)\\b.*");
+
+  /**
+   * Zieht Silbentrennung am Zeilenende zusammen. Beginnt die Folgezeile mit einem Kleinbuchstaben,
+   * wird der Trennstrich entfernt („Bundes-“ + „regierung“ → „Bundesregierung“) — außer vor
+   * Konjunktionen, die auf einen Suspensivstrich hindeuten („Ausgangs- und Hilfsstoffe“). Beginnt
+   * sie mit Großbuchstabe oder Ziffer, handelt es sich um ein umbrochenes Kompositum; der
+   * Bindestrich bleibt erhalten („Coronavirus-“ + „Krankheit-2019“ → „Coronavirus-Krankheit-2019“).
+   */
+  private static String verbindeSilbentrennung(ArrayList<String> zeilen) {
+    var sb = new StringBuilder();
+    for (int i = 0; i < zeilen.size(); i++) {
+      var zeile = zeilen.get(i);
+      if (sb.length() > 0) {
+        sb.append('\n');
+      }
+      while (endetMitSilbentrennung(zeile)) {
+        // Leerzeilen (z.B. an Spalten-/Seitenumbrüchen) überspringen.
+        int j = i + 1;
+        while (j < zeilen.size() && zeilen.get(j).isBlank()) {
+          j++;
+        }
+        if (j >= zeilen.size()) {
+          break;
+        }
+        var naechste = zeilen.get(j).stripLeading();
+        int erstesZeichen = naechste.codePointAt(0);
+        if (Character.isLowerCase(erstesZeichen) && !KONJUNKTION.matcher(naechste).matches()) {
+          zeile = zeile.substring(0, zeile.length() - 1) + naechste;
+        } else if (Character.isUpperCase(erstesZeichen) || Character.isDigit(erstesZeichen)) {
+          zeile = zeile + naechste;
+        } else {
+          break;
+        }
+        i = j;
+      }
+      sb.append(zeile);
+    }
+    return sb.toString();
+  }
+
+  private static boolean endetMitSilbentrennung(String zeile) {
+    if (!zeile.endsWith("-") || zeile.length() < 2) {
+      return false;
+    }
+    // Vor dem Bindestrich muss ein Buchstabe stehen („und -gestaltung“ nicht zusammenziehen).
+    return Character.isLetter(zeile.charAt(zeile.length() - 2));
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java b/src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java
new file mode 100644
index 0000000..c24a1dc
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/aenderung/parse/ZitatExtraktor.java
@@ -0,0 +1,114 @@
+package eu.mulk.aendggner.aenderung.parse;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Ersetzt in deutschem Gesetzestext alle auf oberster Ebene mit „…“ zitierten Passagen durch
+ * indizierte Platzhalter («0», «1», …).
+ *
+ * <p>Das ist der zentrale Trick des Befehlsparsers: Zitierter Inhalt (der seitenlang sein und
+ * eigene Gliederungsmarker, Sätze und geschachtelte Zitate enthalten kann) kann die Befehls-Regexes
+ * nicht verwirren. Geschachtelte „…“ werden per Tiefenzählung dem äußersten Zitat zugeschlagen;
+ * einfache Zitate ‚…‘ bleiben unangetastet.
+ *
+ * <p>Unbalancierte Anführungszeichen kommen in echten BGBl-Texten vor (Satzfehler oder
+ * Extraktionsartefakte). Der Extraktor bricht deshalb nicht ab: Ein schließendes Anführungszeichen
+ * ohne offenes Zitat wird als Literal übernommen, am Textende offene Zitate werden dort geschlossen
+ * — beides wird als Warnung gemeldet und darf nicht stillschweigend untergehen.
+ */
+public final class ZitatExtraktor {
+
+  static final char OEFFNEND = '„'; // „
+  static final char SCHLIESSEND = '“'; // “
+  private static final Pattern PLATZHALTER = Pattern.compile("«(\\d+)»");
+
+  /**
+   * @param text der Text mit Platzhaltern.
+   * @param zitate die extrahierten Zitatinhalte (ohne die äußeren Anführungszeichen), indiziert
+   *     durch die Platzhalternummern.
+   * @param warnungen Auffälligkeiten (unbalancierte Anführungszeichen), die der Nutzer prüfen
+   *     sollte.
+   */
+  public record Ergebnis(String text, List<String> zitate, List<String> warnungen) {
+
+    /** Liefert den Zitatinhalt zum Platzhalter «index». */
+    public String zitat(int index) {
+      return zitate.get(index);
+    }
+
+    /** Setzt in {@code textMitPlatzhaltern} alle Platzhalter wieder in Zitatform ein. */
+    public String stelleZitateWiederHer(String textMitPlatzhaltern) {
+      var matcher = PLATZHALTER.matcher(textMitPlatzhaltern);
+      var sb = new StringBuilder();
+      while (matcher.find()) {
+        var zitatText = zitate.get(Integer.parseInt(matcher.group(1)));
+        matcher.appendReplacement(sb, Matcher.quoteReplacement(OEFFNEND + zitatText + SCHLIESSEND));
+      }
+      matcher.appendTail(sb);
+      return sb.toString();
+    }
+  }
+
+  public static Ergebnis extrahiere(String text) {
+    var ausgabe = new StringBuilder();
+    var zitate = new ArrayList<String>();
+    var warnungen = new ArrayList<String>();
+    var aktuellesZitat = new StringBuilder();
+    int tiefe = 0;
+
+    for (int i = 0; i < text.length(); i++) {
+      char c = text.charAt(i);
+      if (c == OEFFNEND) {
+        if (tiefe == 0) {
+          aktuellesZitat.setLength(0);
+        } else {
+          aktuellesZitat.append(c);
+        }
+        tiefe++;
+      } else if (c == SCHLIESSEND) {
+        if (tiefe == 0) {
+          warnungen.add(
+              "Schließendes Anführungszeichen ohne öffnendes: …"
+                  + kontextAuszug(text, i)
+                  + "… — als Literal übernommen.");
+          ausgabe.append(c);
+          continue;
+        }
+        tiefe--;
+        if (tiefe == 0) {
+          ausgabe.append('«').append(zitate.size()).append('»');
+          zitate.add(aktuellesZitat.toString());
+        } else {
+          aktuellesZitat.append(c);
+        }
+      } else if (tiefe > 0) {
+        aktuellesZitat.append(c);
+      } else {
+        ausgabe.append(c);
+      }
+    }
+
+    if (tiefe > 0) {
+      warnungen.add(
+          "Am Textende sind noch "
+              + tiefe
+              + " Zitat(e) offen: …"
+              + kontextAuszug(text, text.length() - 1)
+              + " — am Textende geschlossen.");
+      ausgabe.append('«').append(zitate.size()).append('»');
+      zitate.add(aktuellesZitat.toString());
+    }
+    return new Ergebnis(ausgabe.toString(), zitate, warnungen);
+  }
+
+  private static String kontextAuszug(String text, int position) {
+    var von = Math.max(0, position - 60);
+    var bis = Math.min(text.length(), position + 20);
+    return text.substring(von, bis).replaceAll("\\s+", " ");
+  }
+
+  private ZitatExtraktor() {}
+}
diff --git a/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java b/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java
new file mode 100644
index 0000000..3d36575
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java
@@ -0,0 +1,689 @@
+package eu.mulk.aendggner.anwendung;
+
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Anfuegung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Aufhebung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Ersetzung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Neufassung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Streichung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.StrukturEinfuegung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.Umnummerierung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.UnbekannterBefehl;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WoerterEinfuegung;
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.WortAnker;
+import eu.mulk.aendggner.aenderung.Stelle;
+import eu.mulk.aendggner.gesetz.Absatz;
+import eu.mulk.aendggner.gesetz.Gesetz;
+import eu.mulk.aendggner.gesetz.Norm;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Wendet Änderungsbefehle nacheinander auf ein Stammgesetz an (die Reihenfolge im Änderungsgesetz
+ * ist maßgeblich). Jeder Befehl erhält einen Protokolleintrag; was nicht sicher angewandt werden
+ * kann, wird mit Begründung als „manuell prüfen“ markiert — niemals stillschweigend verworfen.
+ */
+public final class BefehlAnwender {
+
+  public enum Status {
+    ANGEWANDT,
+    MANUELL_PRUEFEN
+  }
+
+  public record AngewandteAenderung(
+      Aenderungsbefehl befehl, Status status, String begruendung, Set<String> betroffeneEnbez) {}
+
+  public record AnwendungsErgebnis(Gesetz neu, List<AngewandteAenderung> protokoll) {
+
+    public long anzahlAngewandt() {
+      return protokoll.stream().filter(a -> a.status() == Status.ANGEWANDT).count();
+    }
+
+    public long anzahlManuell() {
+      return protokoll.stream().filter(a -> a.status() == Status.MANUELL_PRUEFEN).count();
+    }
+  }
+
+  // Absatzmarker in Zitaten: „(1) “ am Zeilenanfang oder nach Leerraum (PDF-Umbrüche verwischen
+  // die Zeilenstruktur).
+  private static final Pattern ABSATZ_MARKER =
+      Pattern.compile("(?m)(?:^|(?<=\\s))\\((\\d+[a-z]?)\\)\\s+");
+
+  private BefehlAnwender() {}
+
+  public static AnwendungsErgebnis anwenden(Gesetz alt, List<Aenderungsbefehl> befehle) {
+    var normen = new ArrayList<>(alt.normen());
+    var protokoll = new ArrayList<AngewandteAenderung>();
+
+    for (var befehl : befehle) {
+      protokoll.add(wendeAn(normen, befehl));
+    }
+
+    return new AnwendungsErgebnis(alt.mitNormen(normen), protokoll);
+  }
+
+  private static AngewandteAenderung wendeAn(List<Norm> normen, Aenderungsbefehl befehl) {
+    if (befehl instanceof UnbekannterBefehl) {
+      return manuell(befehl, "Befehl nicht erkannt.");
+    }
+    if (befehl.stelle().betrifftInhaltsuebersicht()) {
+      return manuell(
+          befehl, "Änderungen an der Inhaltsübersicht werden nicht automatisch angewandt.");
+    }
+    try {
+      return switch (befehl) {
+        case Ersetzung e -> wendeErsetzungAn(normen, e);
+        case Streichung s -> wendeStreichungAn(normen, s);
+        case WoerterEinfuegung w -> wendeWoerterEinfuegungAn(normen, w);
+        case Neufassung n -> wendeNeufassungAn(normen, n);
+        case StrukturEinfuegung s -> wendeStrukturEinfuegungAn(normen, s);
+        case Anfuegung a -> wendeAnfuegungAn(normen, a);
+        case Aufhebung a -> wendeAufhebungAn(normen, a);
+        case Umnummerierung u -> wendeUmnummerierungAn(normen, u);
+        case UnbekannterBefehl u -> manuell(befehl, "Befehl nicht erkannt.");
+      };
+    } catch (RuntimeException e) {
+      return manuell(befehl, "Anwendung fehlgeschlagen: " + e);
+    }
+  }
+
+  // --- Wortweise Textoperationen -------------------------------------------------------------
+
+  private static AngewandteAenderung wendeErsetzungAn(List<Norm> normen, Ersetzung befehl) {
+    return bearbeiteText(
+        normen,
+        befehl,
+        text -> {
+          if (befehl.amEnde()) {
+            var gestutzt = text.stripTrailing();
+            if (!gestutzt.endsWith(befehl.alt())) {
+              return TextErgebnis.fehler("Der Text endet nicht mit „" + befehl.alt() + "“.");
+            }
+            return TextErgebnis.ok(
+                gestutzt.substring(0, gestutzt.length() - befehl.alt().length()) + befehl.neu());
+          }
+          int anzahl = zaehleVorkommen(text, befehl.alt());
+          if (anzahl == 0) {
+            return TextErgebnis.fehler("„" + befehl.alt() + "“ kommt im Zieltext nicht vor.");
+          }
+          if (anzahl > 1 && !befehl.jeweils()) {
+            return TextErgebnis.fehler(
+                "„" + befehl.alt() + "“ kommt " + anzahl + "-mal vor (ohne „jeweils“ mehrdeutig).");
+          }
+          return TextErgebnis.ok(text.replace(befehl.alt(), befehl.neu()));
+        });
+  }
+
+  private static AngewandteAenderung wendeStreichungAn(List<Norm> normen, Streichung befehl) {
+    return bearbeiteText(
+        normen,
+        befehl,
+        text -> {
+          int anzahl = zaehleVorkommen(text, befehl.woerter());
+          if (anzahl == 0) {
+            return TextErgebnis.fehler("„" + befehl.woerter() + "“ kommt im Zieltext nicht vor.");
+          }
+          if (anzahl > 1) {
+            return TextErgebnis.fehler("„" + befehl.woerter() + "“ kommt " + anzahl + "-mal vor.");
+          }
+          return TextErgebnis.ok(
+              text.replace(befehl.woerter(), "")
+                  .replaceAll("  +", " ")
+                  .replaceAll(" ([,;.])", "$1"));
+        });
+  }
+
+  private static AngewandteAenderung wendeWoerterEinfuegungAn(
+      List<Norm> normen, WoerterEinfuegung befehl) {
+    return bearbeiteText(
+        normen,
+        befehl,
+        text ->
+            switch (befehl.anker()) {
+              case WortAnker.NachWoertern nach -> {
+                var pruefung = eindeutigeFundstelle(text, nach.woerter());
+                if (pruefung.fehler() != null) {
+                  yield TextErgebnis.fehler(pruefung.fehler());
+                }
+                int ende = pruefung.index() + nach.woerter().length();
+                yield TextErgebnis.ok(
+                    text.substring(0, ende) + " " + befehl.woerter() + text.substring(ende));
+              }
+              case WortAnker.VorWoertern vor -> {
+                var pruefung = eindeutigeFundstelle(text, vor.woerter());
+                if (pruefung.fehler() != null) {
+                  yield TextErgebnis.fehler(pruefung.fehler());
+                }
+                yield TextErgebnis.ok(
+                    text.substring(0, pruefung.index())
+                        + befehl.woerter()
+                        + " "
+                        + text.substring(pruefung.index()));
+              }
+              case WortAnker.VorKommaAmEnde ignoriert -> {
+                var gestutzt = text.stripTrailing();
+                if (!gestutzt.endsWith(",")) {
+                  yield TextErgebnis.fehler("Der Zieltext endet nicht mit einem Komma.");
+                }
+                yield TextErgebnis.ok(
+                    gestutzt.substring(0, gestutzt.length() - 1) + " " + befehl.woerter() + ",");
+              }
+              case WortAnker.AmEnde ignoriert -> {
+                var gestutzt = text.stripTrailing();
+                if (gestutzt.endsWith(".") || gestutzt.endsWith(",") || gestutzt.endsWith(";")) {
+                  var satzzeichen = gestutzt.charAt(gestutzt.length() - 1);
+                  yield TextErgebnis.ok(
+                      gestutzt.substring(0, gestutzt.length() - 1)
+                          + " "
+                          + befehl.woerter()
+                          + satzzeichen);
+                }
+                yield TextErgebnis.ok(gestutzt + " " + befehl.woerter());
+              }
+            });
+  }
+
+  // --- Strukturoperationen -------------------------------------------------------------------
+
+  private static AngewandteAenderung wendeNeufassungAn(List<Norm> normen, Neufassung befehl) {
+    var stelle = befehl.stelle();
+
+    if (stelle.betrifftUeberschrift()) {
+      var aufloesung = loeseNormAuf(normen, stelle);
+      if (aufloesung.fehler() != null) {
+        return manuell(befehl, aufloesung.fehler());
+      }
+      var norm = normen.get(aufloesung.normIndex());
+      var titel = befehl.neuerText().replaceFirst("^§\\s*\\S+\\s+", "").strip();
+      normen.set(aufloesung.normIndex(), norm.mitTitel(titel));
+      return angewandt(befehl, norm.enbez());
+    }
+
+    if (nurParagraph(stelle)) {
+      var aufloesung = loeseNormAuf(normen, stelle);
+      if (aufloesung.fehler() != null) {
+        return manuell(befehl, aufloesung.fehler());
+      }
+      var alteNorm = normen.get(aufloesung.normIndex());
+      var neueNorm = parseNorm(befehl.neuerText(), alteNorm.enbez(), alteNorm);
+      normen.set(aufloesung.normIndex(), neueNorm);
+      return angewandt(befehl, alteNorm.enbez());
+    }
+
+    if (stelle.absatz().isPresent() && feinsteIstAbsatz(stelle)) {
+      var ergebnis = StellenAufloeser.aufloese(gesetzAus(normen), stelle);
+      if (ergebnis instanceof StellenAufloeser.Ergebnis.NichtGefunden nicht) {
+        return manuell(befehl, nicht.begruendung());
+      }
+      var fundstelle = ((StellenAufloeser.Ergebnis.Gefunden) ergebnis).fundstelle();
+      var norm = normen.get(fundstelle.normIndex());
+      var absaetze = new ArrayList<>(norm.absaetze());
+      var alterAbsatz = absaetze.get(fundstelle.absatzIndex());
+      var neueAbsaetze = parseAbsaetze(befehl.neuerText());
+      if (neueAbsaetze.size() == 1) {
+        var neuer = neueAbsaetze.get(0);
+        absaetze.set(
+            fundstelle.absatzIndex(),
+            new Absatz(
+                neuer.nummer() != null ? neuer.nummer() : alterAbsatz.nummer(), neuer.text()));
+      } else {
+        absaetze.remove((int) fundstelle.absatzIndex());
+        absaetze.addAll(fundstelle.absatzIndex(), neueAbsaetze);
+      }
+      normen.set(fundstelle.normIndex(), norm.mitAbsaetzen(absaetze));
+      return angewandt(befehl, norm.enbez());
+    }
+
+    // Neufassung eines Satzes / einer Nummer / eines Buchstabens: Bereich ersetzen.
+    return bearbeiteText(normen, befehl, text -> TextErgebnis.ok(befehl.neuerText().strip()));
+  }
+
+  private static AngewandteAenderung wendeStrukturEinfuegungAn(
+      List<Norm> normen, StrukturEinfuegung befehl) {
+    return switch (befehl.ebene()) {
+      case PARAGRAPH -> {
+        var enbezNeu = "§ " + befehl.bezeichnung();
+        if (StellenAufloeser.normIndex(gesetzAus(normen), enbezNeu) >= 0) {
+          yield manuell(befehl, enbezNeu + " existiert bereits im Stammgesetz.");
+        }
+        var aufloesung = loeseNormAuf(normen, befehl.stelle());
+        if (aufloesung.fehler() != null) {
+          yield manuell(befehl, aufloesung.fehler());
+        }
+        var anker = normen.get(aufloesung.normIndex());
+        var neueNorm =
+            parseNorm(
+                befehl.text(),
+                enbezNeu,
+                new Norm(enbezNeu, null, anker.gliederung(), List.of(), false));
+        normen.add(aufloesung.normIndex() + (befehl.vorher() ? 0 : 1), neueNorm);
+        yield angewandt(befehl, enbezNeu);
+      }
+      case ABSATZ -> {
+        var stelle = befehl.stelle();
+        if (stelle.absatz().isEmpty()) {
+          yield manuell(befehl, "Einfügeanker nennt keinen Absatz: " + stelle.anzeigeText());
+        }
+        var ergebnis = StellenAufloeser.aufloese(gesetzAus(normen), stelle);
+        if (ergebnis instanceof StellenAufloeser.Ergebnis.NichtGefunden nicht) {
+          yield manuell(befehl, nicht.begruendung());
+        }
+        var fundstelle = ((StellenAufloeser.Ergebnis.Gefunden) ergebnis).fundstelle();
+        var norm = normen.get(fundstelle.normIndex());
+        var absaetze = new ArrayList<>(norm.absaetze());
+        int position = fundstelle.absatzIndex() + (befehl.vorher() ? 0 : 1);
+        absaetze.addAll(position, parseAbsaetze(befehl.text()));
+        normen.set(fundstelle.normIndex(), norm.mitAbsaetzen(absaetze));
+        yield angewandt(befehl, norm.enbez());
+      }
+      case SATZ ->
+          bearbeiteBereich(
+              normen,
+              befehl,
+              (text, bereich) -> {
+                var einschub = " " + befehl.text().strip();
+                int position = befehl.vorher() ? bereich.von() : bereich.bis();
+                return TextErgebnis.ok(
+                    befehl.vorher()
+                        ? text.substring(0, position)
+                            + befehl.text().strip()
+                            + " "
+                            + text.substring(position)
+                        : text.substring(0, position) + einschub + text.substring(position));
+              });
+      case NUMMER, BUCHSTABE ->
+          bearbeiteBereich(
+              normen,
+              befehl,
+              (text, bereich) -> {
+                var einrueckung = einrueckungVon(text, bereich.von());
+                int position = befehl.vorher() ? bereich.von() : bereich.bis();
+                var zeile = einrueckung + befehl.text().strip().replaceAll("\\s+", " ");
+                return TextErgebnis.ok(
+                    befehl.vorher()
+                        ? text.substring(0, position) + zeile + "\n" + text.substring(position)
+                        : text.substring(0, position) + "\n" + zeile + text.substring(position));
+              });
+    };
+  }
+
+  private static AngewandteAenderung wendeAnfuegungAn(List<Norm> normen, Anfuegung befehl) {
+    return switch (befehl.ebene()) {
+      case ABSATZ -> {
+        var aufloesung = loeseNormAuf(normen, befehl.stelle());
+        if (aufloesung.fehler() != null) {
+          yield manuell(befehl, aufloesung.fehler());
+        }
+        var norm = normen.get(aufloesung.normIndex());
+        var absaetze = new ArrayList<>(norm.absaetze());
+        absaetze.addAll(parseAbsaetze(befehl.text()));
+        normen.set(aufloesung.normIndex(), norm.mitAbsaetzen(absaetze));
+        yield angewandt(befehl, norm.enbez());
+      }
+      case SATZ ->
+          bearbeiteText(
+              normen,
+              befehl,
+              text -> TextErgebnis.ok(text.stripTrailing() + " " + befehl.text().strip()));
+      case NUMMER, BUCHSTABE ->
+          bearbeiteText(
+              normen,
+              befehl,
+              text ->
+                  TextErgebnis.ok(
+                      text.stripTrailing()
+                          + "\n  "
+                          + befehl.text().strip().replaceAll("\\s+", " ")));
+      case PARAGRAPH -> manuell(befehl, "Anfügen ganzer Paragraphen wird nicht unterstützt.");
+    };
+  }
+
+  private static AngewandteAenderung wendeAufhebungAn(List<Norm> normen, Aufhebung befehl) {
+    var stelle = befehl.stelle();
+
+    if (nurParagraph(stelle)) {
+      var aufloesung = loeseNormAuf(normen, stelle);
+      if (aufloesung.fehler() != null) {
+        return manuell(befehl, aufloesung.fehler());
+      }
+      var norm = normen.get(aufloesung.normIndex());
+      if (norm.weggefallen()) {
+        return manuell(befehl, norm.enbez() + " ist bereits weggefallen.");
+      }
+      normen.set(aufloesung.normIndex(), norm.alsWeggefallen());
+      return angewandt(befehl, norm.enbez());
+    }
+
+    if (stelle.absatz().isPresent() && feinsteIstAbsatz(stelle)) {
+      var ergebnis = StellenAufloeser.aufloese(gesetzAus(normen), stelle);
+      if (ergebnis instanceof StellenAufloeser.Ergebnis.NichtGefunden nicht) {
+        return manuell(befehl, nicht.begruendung());
+      }
+      var fundstelle = ((StellenAufloeser.Ergebnis.Gefunden) ergebnis).fundstelle();
+      var norm = normen.get(fundstelle.normIndex());
+      var absaetze = new ArrayList<>(norm.absaetze());
+      var alter = absaetze.get(fundstelle.absatzIndex());
+      absaetze.set(fundstelle.absatzIndex(), new Absatz(alter.nummer(), "(weggefallen)"));
+      normen.set(fundstelle.normIndex(), norm.mitAbsaetzen(absaetze));
+      return angewandt(befehl, norm.enbez());
+    }
+
+    // Satz / Nummer / Buchstabe aufheben: Bereich entfernen bzw. als weggefallen markieren.
+    return bearbeiteBereich(
+        normen,
+        befehl,
+        (text, bereich) -> {
+          var label = labelVon(stelle);
+          if (label != null) {
+            var einrueckung = einrueckungVon(text, bereich.von());
+            return TextErgebnis.ok(
+                text.substring(0, bereich.von())
+                    + einrueckung
+                    + label
+                    + " (weggefallen)"
+                    + text.substring(bereich.bis()));
+          }
+          return TextErgebnis.ok(
+              (text.substring(0, bereich.von()) + text.substring(bereich.bis()))
+                  .replaceAll("  +", " ")
+                  .strip());
+        });
+  }
+
+  private static AngewandteAenderung wendeUmnummerierungAn(
+      List<Norm> normen, Umnummerierung befehl) {
+    var altAbsatz = befehl.stelle().absatz();
+    var neuAbsatz = befehl.neu().absatz();
+    if (altAbsatz.isPresent() && neuAbsatz.isPresent()) {
+      var ergebnis = StellenAufloeser.aufloese(gesetzAus(normen), befehl.stelle());
+      if (ergebnis instanceof StellenAufloeser.Ergebnis.NichtGefunden nicht) {
+        return manuell(befehl, nicht.begruendung());
+      }
+      var fundstelle = ((StellenAufloeser.Ergebnis.Gefunden) ergebnis).fundstelle();
+      var norm = normen.get(fundstelle.normIndex());
+      var absaetze = new ArrayList<>(norm.absaetze());
+      var absatz = absaetze.get(fundstelle.absatzIndex());
+      absaetze.set(fundstelle.absatzIndex(), new Absatz(neuAbsatz.get().nummer(), absatz.text()));
+      normen.set(fundstelle.normIndex(), norm.mitAbsaetzen(absaetze));
+      return angewandt(befehl, norm.enbez());
+    }
+    // Satz-Umnummerierungen ändern den Text nicht (Sätze sind unnummeriert).
+    return angewandt(befehl, "(keine Textänderung nötig)");
+  }
+
+  // --- Gemeinsame Helfer ---------------------------------------------------------------------
+
+  private record TextErgebnis(@Nullable String text, @Nullable String fehler) {
+    static TextErgebnis ok(String text) {
+      return new TextErgebnis(text, null);
+    }
+
+    static TextErgebnis fehler(String begruendung) {
+      return new TextErgebnis(null, begruendung);
+    }
+  }
+
+  private interface TextOperation {
+    TextErgebnis wende(String text);
+  }
+
+  private interface BereichsOperation {
+    TextErgebnis wende(String text, SatzTeiler.SatzBereich bereich);
+  }
+
+  /**
+   * Wendet eine Textoperation auf den durch die Stelle bestimmten Bereich an. Ohne
+   * Bereichs-/Absatzangabe wird die Operation auf jeden Absatz der Norm versucht; sie muss dann in
+   * genau einem Absatz anwendbar sein.
+   */
+  private static AngewandteAenderung bearbeiteText(
+      List<Norm> normen, Aenderungsbefehl befehl, TextOperation operation) {
+    var ergebnis = StellenAufloeser.aufloese(gesetzAus(normen), befehl.stelle());
+    if (ergebnis instanceof StellenAufloeser.Ergebnis.NichtGefunden nicht) {
+      return manuell(befehl, nicht.begruendung());
+    }
+    var fundstelle = ((StellenAufloeser.Ergebnis.Gefunden) ergebnis).fundstelle();
+    var norm = normen.get(fundstelle.normIndex());
+
+    if (fundstelle.absatzIndex() != null) {
+      var absaetze = new ArrayList<>(norm.absaetze());
+      var absatz = absaetze.get(fundstelle.absatzIndex());
+      var neuerText = wendeAufBereichAn(absatz.text(), fundstelle.bereich(), operation);
+      if (neuerText.fehler() != null) {
+        return manuell(befehl, neuerText.fehler());
+      }
+      absaetze.set(fundstelle.absatzIndex(), absatz.mitText(neuerText.text()));
+      normen.set(fundstelle.normIndex(), norm.mitAbsaetzen(absaetze));
+      return angewandt(befehl, norm.enbez());
+    }
+
+    // Ganze Norm als Wirkungsbereich: Operation muss in genau einem Absatz gelingen.
+    var absaetze = new ArrayList<>(norm.absaetze());
+    Integer trefferIndex = null;
+    TextErgebnis treffer = null;
+    String letzterFehler = "Norm hat keine Absätze.";
+    for (int i = 0; i < absaetze.size(); i++) {
+      var versuch = operation.wende(absaetze.get(i).text());
+      if (versuch.fehler() == null) {
+        if (trefferIndex != null) {
+          return manuell(
+              befehl, "Mehrere Absätze von " + norm.enbez() + " kommen infrage; mehrdeutig.");
+        }
+        trefferIndex = i;
+        treffer = versuch;
+      } else {
+        letzterFehler = versuch.fehler();
+      }
+    }
+    if (trefferIndex == null) {
+      return manuell(befehl, letzterFehler);
+    }
+    absaetze.set(trefferIndex, absaetze.get(trefferIndex).mitText(treffer.text()));
+    normen.set(fundstelle.normIndex(), norm.mitAbsaetzen(absaetze));
+    return angewandt(befehl, norm.enbez());
+  }
+
+  /** Wie {@link #bearbeiteText}, aber die Operation braucht den konkreten Zeichenbereich. */
+  private static AngewandteAenderung bearbeiteBereich(
+      List<Norm> normen, Aenderungsbefehl befehl, BereichsOperation operation) {
+    var ergebnis = StellenAufloeser.aufloese(gesetzAus(normen), befehl.stelle());
+    if (ergebnis instanceof StellenAufloeser.Ergebnis.NichtGefunden nicht) {
+      return manuell(befehl, nicht.begruendung());
+    }
+    var fundstelle = ((StellenAufloeser.Ergebnis.Gefunden) ergebnis).fundstelle();
+    if (fundstelle.absatzIndex() == null || fundstelle.bereich() == null) {
+      return manuell(
+          befehl,
+          "„" + befehl.stelle().anzeigeText() + "“ bezeichnet keinen konkreten Textbereich.");
+    }
+    var norm = normen.get(fundstelle.normIndex());
+    var absaetze = new ArrayList<>(norm.absaetze());
+    var absatz = absaetze.get(fundstelle.absatzIndex());
+    var neuerText = operation.wende(absatz.text(), fundstelle.bereich());
+    if (neuerText.fehler() != null) {
+      return manuell(befehl, neuerText.fehler());
+    }
+    absaetze.set(fundstelle.absatzIndex(), absatz.mitText(neuerText.text()));
+    normen.set(fundstelle.normIndex(), norm.mitAbsaetzen(absaetze));
+    return angewandt(befehl, norm.enbez());
+  }
+
+  private static TextErgebnis wendeAufBereichAn(
+      String text, SatzTeiler.@Nullable SatzBereich bereich, TextOperation operation) {
+    if (bereich == null) {
+      return operation.wende(text);
+    }
+    var ausschnitt = text.substring(bereich.von(), bereich.bis());
+    var ergebnis = operation.wende(ausschnitt);
+    if (ergebnis.fehler() != null) {
+      return ergebnis;
+    }
+    return TextErgebnis.ok(
+        text.substring(0, bereich.von()) + ergebnis.text() + text.substring(bereich.bis()));
+  }
+
+  private record NormAufloesung(int normIndex, @Nullable String fehler) {}
+
+  private static NormAufloesung loeseNormAuf(List<Norm> normen, Stelle stelle) {
+    if (stelle.paragraph().isEmpty()) {
+      return new NormAufloesung(-1, "Stelle nennt keinen Paragraphen: " + stelle.anzeigeText());
+    }
+    var enbez = "§ " + stelle.paragraph().get().nummer();
+    int index = StellenAufloeser.normIndex(gesetzAus(normen), enbez);
+    if (index < 0) {
+      return new NormAufloesung(-1, enbez + " existiert nicht im Gesetz.");
+    }
+    return new NormAufloesung(index, null);
+  }
+
+  private static boolean nurParagraph(Stelle stelle) {
+    return stelle.komponenten().size() == 1
+        && stelle.komponenten().get(0) instanceof Stelle.Paragraph;
+  }
+
+  private static boolean feinsteIstAbsatz(Stelle stelle) {
+    return stelle.komponenten().stream()
+        .noneMatch(
+            k ->
+                k instanceof Stelle.SatzNr
+                    || k instanceof Stelle.NummerNr
+                    || k instanceof Stelle.BuchstabeNr);
+  }
+
+  private static @Nullable String labelVon(Stelle stelle) {
+    for (var komponente : stelle.komponenten().reversed()) {
+      if (komponente instanceof Stelle.NummerNr n) {
+        return n.nummer() + ".";
+      }
+      if (komponente instanceof Stelle.BuchstabeNr b) {
+        return b.kennung() + ")";
+      }
+    }
+    return null;
+  }
+
+  private static String einrueckungVon(String text, int position) {
+    int i = position;
+    var sb = new StringBuilder();
+    while (i < text.length() && (text.charAt(i) == ' ' || text.charAt(i) == '\t')) {
+      sb.append(text.charAt(i));
+      i++;
+    }
+    return sb.toString();
+  }
+
+  private record Fundpruefung(int index, @Nullable String fehler) {}
+
+  private static Fundpruefung eindeutigeFundstelle(String text, String woerter) {
+    int anzahl = zaehleVorkommen(text, woerter);
+    if (anzahl == 0) {
+      return new Fundpruefung(-1, "„" + woerter + "“ kommt im Zieltext nicht vor.");
+    }
+    if (anzahl > 1) {
+      return new Fundpruefung(-1, "„" + woerter + "“ kommt " + anzahl + "-mal vor; mehrdeutig.");
+    }
+    return new Fundpruefung(text.indexOf(woerter), null);
+  }
+
+  private static int zaehleVorkommen(String text, String suchtext) {
+    if (suchtext.isEmpty()) {
+      return 0;
+    }
+    int anzahl = 0;
+    int index = 0;
+    while ((index = text.indexOf(suchtext, index)) >= 0) {
+      anzahl++;
+      index += suchtext.length();
+    }
+    return anzahl;
+  }
+
+  /** Zerlegt einen zitierten Normtext („§ 28a Titel (1) … (2) …“) in Titel und Absätze. */
+  private static Norm parseNorm(String zitat, String enbez, Norm vorlage) {
+    var text = zitat.strip();
+    String titel = vorlage.titel();
+
+    var absatzStart = ABSATZ_MARKER.matcher(text);
+    int erster = absatzStart.find() ? absatzStart.start() : -1;
+    var kopf = (erster >= 0 ? text.substring(0, erster) : text).strip();
+    if (!kopf.isEmpty()) {
+      titel = kopf.replaceFirst("^§\\s*\\S+\\s*", "").replaceAll("\\s+", " ").strip();
+      if (titel.isEmpty()) {
+        titel = vorlage.titel();
+      }
+    }
+
+    var absaetze = erster >= 0 ? parseAbsaetze(text.substring(erster)) : List.<Absatz>of();
+    if (absaetze.isEmpty() && kopf.isEmpty()) {
+      absaetze = List.of(new Absatz(null, text));
+    } else if (absaetze.isEmpty()) {
+      // Kein Absatzmarker: gesamter Text nach der Überschrift ist ein unnummerierter Absatz.
+      absaetze = List.of();
+    }
+
+    return new Norm(enbez, titel, vorlage.gliederung(), absaetze, false);
+  }
+
+  /** Zerlegt zitierten Text in Absätze anhand der „(n)“-Marker. */
+  static List<Absatz> parseAbsaetze(String zitat) {
+    var text = zitat.strip();
+    var absaetze = new ArrayList<Absatz>();
+    var matcher = ABSATZ_MARKER.matcher(text);
+
+    int vorherigesEnde = 0;
+    String vorherigeNummer = null;
+    while (matcher.find()) {
+      if (matcher.start() > vorherigesEnde || vorherigeNummer != null) {
+        var inhalt = text.substring(vorherigesEnde, matcher.start()).strip();
+        if (!inhalt.isEmpty() || vorherigeNummer != null) {
+          absaetze.add(new Absatz(vorherigeNummer, normalisiereZitatText(inhalt)));
+        }
+      }
+      vorherigeNummer = matcher.group(1);
+      vorherigesEnde = matcher.end();
+    }
+    var rest = text.substring(vorherigesEnde).strip();
+    if (!rest.isEmpty() || vorherigeNummer != null) {
+      absaetze.add(new Absatz(vorherigeNummer, normalisiereZitatText(rest)));
+    }
+    return absaetze;
+  }
+
+  /** Fließtext-Whitespace glätten, Aufzählungszeilen des Zitats aber erhalten. */
+  private static String normalisiereZitatText(String text) {
+    var zeilen = text.split("\n");
+    var sb = new StringBuilder();
+    for (var zeile : zeilen) {
+      var gestutzt = zeile.strip();
+      if (gestutzt.isEmpty()) {
+        continue;
+      }
+      if (sb.length() == 0) {
+        sb.append(gestutzt);
+      } else if (gestutzt.matches("^(\\d+[a-z]?\\.|[a-z]{1,3}\\))\\s.*")) {
+        // Aufzählungspunkt: eigene Zeile.
+        sb.append("\n  ").append(gestutzt);
+      } else {
+        sb.append(' ').append(gestutzt);
+      }
+    }
+    return sb.toString();
+  }
+
+  private static AngewandteAenderung angewandt(Aenderungsbefehl befehl, String enbez) {
+    return new AngewandteAenderung(
+        befehl, Status.ANGEWANDT, "", new LinkedHashSet<>(List.of(enbez)));
+  }
+
+  private static AngewandteAenderung manuell(Aenderungsbefehl befehl, String begruendung) {
+    return new AngewandteAenderung(befehl, Status.MANUELL_PRUEFEN, begruendung, Set.of());
+  }
+
+  private static Gesetz gesetzAus(List<Norm> normen) {
+    return new Gesetz("", null, null, normen);
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java b/src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java
new file mode 100644
index 0000000..a15aafa
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/anwendung/SatzTeiler.java
@@ -0,0 +1,112 @@
+package eu.mulk.aendggner.anwendung;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * Zerlegt einen Absatztext in Sätze im Rechtssinne, mit einer Stoppliste für juristische
+ * Abkürzungen und Datumsangaben („Abs.“, „31. März 2021“).
+ */
+public final class SatzTeiler {
+
+  /** Ein Satz als Zeichenbereich {@code [von, bis)} im Absatztext. */
+  public record SatzBereich(int von, int bis) {}
+
+  private static final Set<String> ABKUERZUNGEN =
+      Set.of(
+          "Abs",
+          "Nr",
+          "Nrn",
+          "Buchst",
+          "S",
+          "Art",
+          "bzw",
+          "vgl",
+          "ggf",
+          "gem",
+          "insbes",
+          "u",
+          "z",
+          "v",
+          "d",
+          "h",
+          "B",
+          "ff",
+          "Halbs",
+          "Doppelbuchst",
+          "usw",
+          "etc");
+
+  private static final Set<String> MONATE =
+      Set.of(
+          "Januar",
+          "Februar",
+          "März",
+          "April",
+          "Mai",
+          "Juni",
+          "Juli",
+          "August",
+          "September",
+          "Oktober",
+          "November",
+          "Dezember");
+
+  /**
+   * Kandidat für ein Satzende: Punkt (ggf. gefolgt von schließendem Zitat oder Klammer), dann
+   * Leerraum, dann Großbuchstabe, Zitat oder Klammer.
+   */
+  private static final Pattern SATZENDE = Pattern.compile("(\\.[“)]*)\\s+(?=[A-ZÄÖÜ„(])");
+
+  private SatzTeiler() {}
+
+  public static List<SatzBereich> teile(String text) {
+    var bereiche = new ArrayList<SatzBereich>();
+    var matcher = SATZENDE.matcher(text);
+    int start = 0;
+    while (matcher.find()) {
+      int punkt = matcher.start();
+      if (istAbkuerzung(text, punkt) || istDatum(text, punkt, matcher.end())) {
+        continue;
+      }
+      bereiche.add(new SatzBereich(start, matcher.end(1)));
+      start = matcher.end();
+    }
+    if (start < text.length()) {
+      bereiche.add(new SatzBereich(start, text.length()));
+    }
+    return bereiche;
+  }
+
+  /** Die Satztexte statt der Bereiche. */
+  public static List<String> teileTexte(String text) {
+    return teile(text).stream().map(b -> text.substring(b.von(), b.bis()).strip()).toList();
+  }
+
+  private static boolean istAbkuerzung(String text, int punktPosition) {
+    var wort = wortVor(text, punktPosition);
+    return ABKUERZUNGEN.contains(wort);
+  }
+
+  /** „31. März 2021“ — Ziffern vor dem Punkt, Monatsname dahinter. */
+  private static boolean istDatum(String text, int punktPosition, int naechstesWortPosition) {
+    var wort = wortVor(text, punktPosition);
+    if (!wort.matches("\\d{1,2}")) {
+      return false;
+    }
+    var rest = text.substring(naechstesWortPosition);
+    var naechstesWort = rest.split("[\\s,.;]", 2)[0];
+    return MONATE.contains(naechstesWort);
+  }
+
+  private static String wortVor(String text, int position) {
+    int ende = position;
+    int anfang = ende;
+    while (anfang > 0 && Character.isLetterOrDigit(text.charAt(anfang - 1))) {
+      anfang--;
+    }
+    return text.substring(anfang, ende);
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java b/src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java
new file mode 100644
index 0000000..8c19c78
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/anwendung/StellenAufloeser.java
@@ -0,0 +1,177 @@
+package eu.mulk.aendggner.anwendung;
+
+import eu.mulk.aendggner.aenderung.Stelle;
+import eu.mulk.aendggner.gesetz.Gesetz;
+import eu.mulk.aendggner.gesetz.Norm;
+import java.util.List;
+import java.util.regex.Pattern;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Löst eine {@link Stelle} gegen ein {@link Gesetz} zu einer konkreten Fundstelle auf: Norm, Absatz
+ * und — bei Satz-/Nummer-/Buchstaben-Angaben — Zeichenbereich im Absatztext.
+ */
+final class StellenAufloeser {
+
+  /**
+   * @param normIndex Index der Norm in {@code gesetz.normen()}.
+   * @param absatzIndex Index des Absatzes; {@code null}, wenn die Stelle die ganze Norm meint.
+   * @param bereich Zeichenbereich im Absatztext; {@code null}, wenn der ganze Absatz gemeint ist.
+   */
+  record Fundstelle(
+      int normIndex, @Nullable Integer absatzIndex, SatzTeiler.@Nullable SatzBereich bereich) {}
+
+  sealed interface Ergebnis {
+    record Gefunden(Fundstelle fundstelle) implements Ergebnis {}
+
+    record NichtGefunden(String begruendung) implements Ergebnis {}
+  }
+
+  private StellenAufloeser() {}
+
+  static Ergebnis aufloese(Gesetz gesetz, Stelle stelle) {
+    if (stelle.istLeer()) {
+      return new Ergebnis.NichtGefunden("Stelle nennt keine Fundstelle im Gesetz.");
+    }
+
+    // 1. Norm bestimmen.
+    String enbez;
+    if (stelle.betrifftInhaltsuebersicht()) {
+      enbez = "Inhaltsübersicht";
+    } else if (stelle.paragraph().isPresent()) {
+      enbez = "§ " + stelle.paragraph().get().nummer();
+    } else {
+      return new Ergebnis.NichtGefunden("Stelle nennt keinen Paragraphen: " + stelle.anzeigeText());
+    }
+    int normIndex = normIndex(gesetz, enbez);
+    if (normIndex < 0) {
+      return new Ergebnis.NichtGefunden(enbez + " existiert nicht im Gesetz.");
+    }
+    var norm = gesetz.normen().get(normIndex);
+
+    // 2. Absatz bestimmen.
+    Integer absatzIndex = null;
+    if (stelle.absatz().isPresent()) {
+      var nummer = stelle.absatz().get().nummer();
+      absatzIndex = absatzIndex(norm, nummer);
+      if (absatzIndex < 0) {
+        return new Ergebnis.NichtGefunden(enbez + " hat keinen Absatz " + nummer + ".");
+      }
+    }
+
+    // 3. Feinste Komponente (Buchstabe > Nummer > Satz) als Textbereich auflösen.
+    var feinste = feinsteKomponente(stelle);
+    if (feinste == null) {
+      return new Ergebnis.Gefunden(new Fundstelle(normIndex, absatzIndex, null));
+    }
+
+    if (absatzIndex == null) {
+      if (norm.absaetze().size() == 1) {
+        absatzIndex = 0;
+      } else {
+        return new Ergebnis.NichtGefunden(
+            enbez
+                + " hat "
+                + norm.absaetze().size()
+                + " Absätze; „"
+                + stelle.anzeigeText()
+                + "“ ist ohne Absatzangabe nicht eindeutig.");
+      }
+    }
+
+    var text = norm.absaetze().get(absatzIndex).text();
+    var bereich = loeseKomponenteAuf(feinste, text);
+    if (bereich == null) {
+      return new Ergebnis.NichtGefunden(
+          "„" + stelle.anzeigeText() + "“ ist im Text von " + enbez + " nicht auffindbar.");
+    }
+    return new Ergebnis.Gefunden(new Fundstelle(normIndex, absatzIndex, bereich));
+  }
+
+  static int normIndex(Gesetz gesetz, String enbez) {
+    var normen = gesetz.normen();
+    for (int i = 0; i < normen.size(); i++) {
+      if (normen.get(i).enbez().equals(enbez)) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  static int absatzIndex(Norm norm, String nummer) {
+    var absaetze = norm.absaetze();
+    for (int i = 0; i < absaetze.size(); i++) {
+      if (nummer.equals(absaetze.get(i).nummer())) {
+        return i;
+      }
+    }
+    // Unnummerierter Einzelabsatz gilt als „Absatz 1“.
+    if (absaetze.size() == 1 && absaetze.get(0).nummer() == null && nummer.equals("1")) {
+      return 0;
+    }
+    return -1;
+  }
+
+  private static Stelle.@Nullable Komponente feinsteKomponente(Stelle stelle) {
+    Stelle.Komponente feinste = null;
+    for (var komponente : stelle.komponenten()) {
+      switch (komponente) {
+        case Stelle.SatzNr s -> feinste = besser(feinste, s, 1);
+        case Stelle.NummerNr n -> feinste = besser(feinste, n, 2);
+        case Stelle.BuchstabeNr b -> feinste = besser(feinste, b, 3);
+        default -> {}
+      }
+    }
+    return feinste;
+  }
+
+  private static Stelle.Komponente besser(
+      Stelle.@Nullable Komponente bisher, Stelle.Komponente neu, int rang) {
+    if (bisher == null) {
+      return neu;
+    }
+    return rang(bisher) >= rang ? bisher : neu;
+  }
+
+  private static int rang(Stelle.Komponente komponente) {
+    return switch (komponente) {
+      case Stelle.SatzNr s -> 1;
+      case Stelle.NummerNr n -> 2;
+      case Stelle.BuchstabeNr b -> 3;
+      default -> 0;
+    };
+  }
+
+  private static SatzTeiler.@Nullable SatzBereich loeseKomponenteAuf(
+      Stelle.Komponente komponente, String text) {
+    return switch (komponente) {
+      case Stelle.SatzNr satz -> {
+        int index = Integer.parseInt(satz.nummer().replaceAll("[a-z]$", "")) - 1;
+        var saetze = SatzTeiler.teile(text);
+        yield index >= 0 && index < saetze.size() ? saetze.get(index) : null;
+      }
+      case Stelle.NummerNr nummer -> zeilenBereich(text, Pattern.quote(nummer.nummer()) + "\\.");
+      case Stelle.BuchstabeNr buchstabe ->
+          zeilenBereich(text, Pattern.quote(buchstabe.kennung()) + "\\)");
+      default -> null;
+    };
+  }
+
+  /** Findet die (eindeutige) Aufzählungszeile, die mit dem gegebenen Label beginnt. */
+  private static SatzTeiler.@Nullable SatzBereich zeilenBereich(String text, String labelRegex) {
+    var muster = Pattern.compile("(?m)^[ \\t]*" + labelRegex + "[ \\t].*$");
+    var matcher = muster.matcher(text);
+    SatzTeiler.SatzBereich gefunden = null;
+    while (matcher.find()) {
+      if (gefunden != null) {
+        return null; // mehrdeutig (z.B. gleiche Buchstaben in mehreren Nummern)
+      }
+      gefunden = new SatzTeiler.SatzBereich(matcher.start(), matcher.end());
+    }
+    return gefunden;
+  }
+
+  static List<Stelle.Komponente> komponenten(Stelle stelle) {
+    return stelle.komponenten();
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Absatz.java b/src/main/java/eu/mulk/aendggner/gesetz/Absatz.java
new file mode 100644
index 0000000..9ab00f5
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Absatz.java
@@ -0,0 +1,22 @@
+package eu.mulk.aendggner.gesetz;
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Ein Absatz einer Einzelnorm.
+ *
+ * @param nummer die Absatznummer (z.B. „1“, „2a“); {@code null} bei unnummerierten Absätzen.
+ * @param text der geflattete Text ohne den führenden Nummernmarker; Aufzählungen als eingerückte
+ *     Zeilen („1. …“, „a) …“).
+ */
+public record Absatz(@Nullable String nummer, String text) {
+
+  /** Text mit vorangestelltem Nummernmarker, wie er angezeigt wird. */
+  public String anzeigeText() {
+    return nummer == null ? text : "(" + nummer + ") " + text;
+  }
+
+  public Absatz mitText(String neuerText) {
+    return new Absatz(nummer, neuerText);
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Gesetz.java b/src/main/java/eu/mulk/aendggner/gesetz/Gesetz.java
new file mode 100644
index 0000000..5db0860
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Gesetz.java
@@ -0,0 +1,20 @@
+package eu.mulk.aendggner.gesetz;
+
+import java.util.List;
+import java.util.Optional;
+
+/** Ein Stammgesetz, bestehend aus einer geordneten Liste von Einzelnormen. */
+public record Gesetz(String jurabk, String langue, String kurzue, List<Norm> normen) {
+
+  public Gesetz {
+    normen = List.copyOf(normen);
+  }
+
+  public Optional<Norm> norm(String enbez) {
+    return normen.stream().filter(n -> n.enbez().equals(enbez)).findFirst();
+  }
+
+  public Gesetz mitNormen(List<Norm> neueNormen) {
+    return new Gesetz(jurabk, langue, kurzue, neueNormen);
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java b/src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java
new file mode 100644
index 0000000..21c9c4a
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Gliederung.java
@@ -0,0 +1,11 @@
+package eu.mulk.aendggner.gesetz;
+
+import org.jspecify.annotations.Nullable;
+
+/** Eine Gliederungseinheit (z.B. „2. Abschnitt — Koordinierung und Früherkennung“). */
+public record Gliederung(String bezeichnung, @Nullable String titel) {
+
+  public String anzeigeText() {
+    return titel == null ? bezeichnung : bezeichnung + " — " + titel;
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/Norm.java b/src/main/java/eu/mulk/aendggner/gesetz/Norm.java
new file mode 100644
index 0000000..10c3fa6
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/gesetz/Norm.java
@@ -0,0 +1,49 @@
+package eu.mulk.aendggner.gesetz;
+
+import java.util.List;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Eine Einzelnorm eines Gesetzes (z.B. „§ 5“ oder „Inhaltsübersicht“).
+ *
+ * @param enbez Einzelnormbezeichnung, z.B. „§ 5“, „§ 28a“, „Inhaltsübersicht“.
+ * @param titel amtliche Überschrift (nullable).
+ * @param gliederung übergeordnete Gliederungseinheit (nullable).
+ * @param absaetze die Absätze; bei unstrukturierten Normen ein einzelner unnummerierter Absatz.
+ * @param weggefallen ob die Norm aufgehoben ist.
+ */
+public record Norm(
+    String enbez,
+    @Nullable String titel,
+    @Nullable Gliederung gliederung,
+    List<Absatz> absaetze,
+    boolean weggefallen) {
+
+  public Norm {
+    absaetze = List.copyOf(absaetze);
+  }
+
+  public Norm mitAbsaetzen(List<Absatz> neueAbsaetze) {
+    return new Norm(enbez, titel, gliederung, neueAbsaetze, weggefallen);
+  }
+
+  public Norm mitTitel(@Nullable String neuerTitel) {
+    return new Norm(enbez, neuerTitel, gliederung, absaetze, weggefallen);
+  }
+
+  public Norm alsWeggefallen() {
+    return new Norm(enbez, titel, gliederung, List.of(new Absatz(null, "(weggefallen)")), true);
+  }
+
+  /** Gesamttext der Norm (alle Absätze, durch Leerzeilen getrennt). */
+  public String gesamtText() {
+    var sb = new StringBuilder();
+    for (var absatz : absaetze) {
+      if (sb.length() > 0) {
+        sb.append("\n\n");
+      }
+      sb.append(absatz.anzeigeText());
+    }
+    return sb.toString();
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/gii/ContentFlattener.java b/src/main/java/eu/mulk/aendggner/gesetz/gii/ContentFlattener.java
new file mode 100644
index 0000000..eef8536
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/gesetz/gii/ContentFlattener.java
@@ -0,0 +1,126 @@
+package eu.mulk.aendggner.gesetz.gii;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Flattet den strukturierten Inhalt eines gii-norm-{@code <P>}-Elements zu Klartext.
+ *
+ * <p>Aufzählungen ({@code <DL>/<DT>/<DD>/<LA>}) werden zu eingerückten Zeilen („1. …“, „a) …“),
+ * {@code <BR/>} zu Zeilenumbrüchen, {@code <pre>} bleibt wörtlich erhalten, Tabellenzellen werden
+ * mit „ | “ verbunden.
+ */
+final class ContentFlattener {
+
+  private ContentFlattener() {}
+
+  static String flatten(Element p) {
+    var sb = new StringBuilder();
+    flattenKinder(p, sb, 0);
+    return normalisiere(sb.toString());
+  }
+
+  private static void flattenKinder(Node parent, StringBuilder sb, int einrueckung) {
+    for (var kind = parent.getFirstChild(); kind != null; kind = kind.getNextSibling()) {
+      flattenKnoten(kind, sb, einrueckung);
+    }
+  }
+
+  private static void flattenKnoten(Node knoten, StringBuilder sb, int einrueckung) {
+    switch (knoten.getNodeType()) {
+      case Node.TEXT_NODE, Node.CDATA_SECTION_NODE -> sb.append(knoten.getNodeValue());
+      case Node.ELEMENT_NODE -> flattenElement((Element) knoten, sb, einrueckung);
+      default -> {}
+    }
+  }
+
+  private static void flattenElement(Element element, StringBuilder sb, int einrueckung) {
+    switch (element.getNodeName()) {
+      case "BR" -> sb.append('\n');
+      case "DL" -> flattenListe(element, sb, einrueckung);
+      case "pre" -> sb.append(element.getTextContent());
+      case "table" -> flattenTabelle(element, sb);
+      default -> flattenKinder(element, sb, einrueckung);
+    }
+  }
+
+  private static void flattenListe(Element dl, StringBuilder sb, int einrueckung) {
+    String aktuellesLabel = null;
+    for (var kind = dl.getFirstChild(); kind != null; kind = kind.getNextSibling()) {
+      if (kind.getNodeType() != Node.ELEMENT_NODE) {
+        continue;
+      }
+      var kindElement = (Element) kind;
+      switch (kindElement.getNodeName()) {
+        case "DT" -> aktuellesLabel = kindElement.getTextContent().strip();
+        case "DD" -> {
+          var eintrag = new StringBuilder();
+          flattenKinder(kindElement, eintrag, einrueckung + 1);
+          neueZeile(sb);
+          sb.append("  ".repeat(einrueckung + 1));
+          if (aktuellesLabel != null && !aktuellesLabel.isEmpty()) {
+            sb.append(aktuellesLabel).append(' ');
+          }
+          sb.append(eintrag.toString().strip());
+          sb.append('\n');
+          aktuellesLabel = null;
+        }
+        default -> {}
+      }
+    }
+  }
+
+  private static void flattenTabelle(Element table, StringBuilder sb) {
+    for (var row : alleNachkommen(table, "row")) {
+      var zeile = new StringBuilder();
+      for (var entry : alleNachkommen(row, "entry")) {
+        var zellText = entry.getTextContent().strip();
+        if (zellText.isEmpty()) {
+          continue;
+        }
+        if (zeile.length() > 0) {
+          zeile.append(" | ");
+        }
+        zeile.append(zellText);
+      }
+      if (zeile.length() > 0) {
+        neueZeile(sb);
+        sb.append(zeile);
+        sb.append('\n');
+      }
+    }
+  }
+
+  private static java.util.List<Element> alleNachkommen(Element parent, String name) {
+    var ergebnis = new java.util.ArrayList<Element>();
+    var elemente = parent.getElementsByTagName(name);
+    for (int i = 0; i < elemente.getLength(); i++) {
+      ergebnis.add((Element) elemente.item(i));
+    }
+    return ergebnis;
+  }
+
+  private static void neueZeile(StringBuilder sb) {
+    if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '\n') {
+      sb.append('\n');
+    }
+  }
+
+  /** Whitespace in Fließtextzeilen zusammenziehen, Zeilenstruktur aber erhalten. */
+  private static String normalisiere(String text) {
+    var zeilen = text.split("\n", -1);
+    var sb = new StringBuilder();
+    for (var zeile : zeilen) {
+      var fuehrend = zeile.length() - zeile.stripLeading().length();
+      var normalisiert =
+          zeile.substring(0, fuehrend)
+              + zeile.substring(fuehrend).replaceAll("[ \\t]+", " ").stripTrailing();
+      if (sb.length() > 0) {
+        sb.append('\n');
+      }
+      sb.append(normalisiert);
+    }
+    // Mehrfache Leerzeilen zusammenfassen.
+    return sb.toString().replaceAll("\n{3,}", "\n\n");
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoader.java b/src/main/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoader.java
new file mode 100644
index 0000000..ca7bdf6
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoader.java
@@ -0,0 +1,159 @@
+package eu.mulk.aendggner.gesetz.gii;
+
+import eu.mulk.aendggner.gesetz.Absatz;
+import eu.mulk.aendggner.gesetz.Gesetz;
+import eu.mulk.aendggner.gesetz.Gliederung;
+import eu.mulk.aendggner.gesetz.Norm;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.jspecify.annotations.Nullable;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Liest ein Stammgesetz im gii-norm-Format von gesetze-im-internet.de.
+ *
+ * <p>Die DTD-Referenz ({@code gii-norm.dtd} per HTTP) wird bewusst nicht aufgelöst; der Loader
+ * arbeitet vollständig offline.
+ */
+public final class GiiXmlLoader {
+
+  private static final Pattern ABSATZ_MARKER =
+      Pattern.compile("^\\((\\d+[a-z]?)\\)\\s+", Pattern.UNICODE_CASE);
+
+  public Gesetz load(Path datei) throws IOException, SAXException {
+    var builder = neuerDocumentBuilder();
+    var dokument = builder.parse(datei.toFile());
+    var wurzel = dokument.getDocumentElement();
+
+    String jurabk = null;
+    String langue = null;
+    String kurzue = null;
+    var normen = new ArrayList<Norm>();
+    Gliederung aktuelleGliederung = null;
+
+    for (var normElement : kindElemente(wurzel, "norm")) {
+      var metadaten = erstesKind(normElement, "metadaten");
+      if (metadaten == null) {
+        continue;
+      }
+
+      if (jurabk == null) {
+        jurabk = kindText(metadaten, "jurabk");
+        langue = kindText(metadaten, "langue");
+        kurzue = kindText(metadaten, "kurzue");
+      }
+
+      var gliederungselement = erstesKind(metadaten, "gliederungseinheit");
+      if (gliederungselement != null) {
+        var bez = kindText(gliederungselement, "gliederungsbez");
+        var titel = kindText(gliederungselement, "gliederungstitel");
+        if (bez != null) {
+          aktuelleGliederung = new Gliederung(bez, titel);
+        }
+      }
+
+      var enbez = kindText(metadaten, "enbez");
+      if (enbez == null) {
+        // Rahmen-Norm (Metadaten des Gesamtgesetzes, Fußnoten) — keine Einzelnorm.
+        continue;
+      }
+
+      var titel = kindText(metadaten, "titel");
+      var absaetze = leseAbsaetze(normElement);
+      var weggefallen =
+          (titel != null && titel.strip().equals("(weggefallen)"))
+              || (absaetze.size() == 1 && absaetze.get(0).text().strip().equals("(weggefallen)"));
+      normen.add(new Norm(enbez, titel, aktuelleGliederung, absaetze, weggefallen));
+    }
+
+    if (jurabk == null) {
+      throw new SAXException("Keine <norm>-Elemente mit Metadaten gefunden: " + datei);
+    }
+    return new Gesetz(jurabk, langue, kurzue, normen);
+  }
+
+  private static ArrayList<Absatz> leseAbsaetze(Element normElement) {
+    var absaetze = new ArrayList<Absatz>();
+    var textdaten = erstesKind(normElement, "textdaten");
+    if (textdaten == null) {
+      return absaetze;
+    }
+    var text = erstesKind(textdaten, "text");
+    if (text == null) {
+      return absaetze;
+    }
+    var content = erstesKind(text, "Content");
+    if (content == null) {
+      return absaetze;
+    }
+
+    for (var p : kindElemente(content, "P")) {
+      var geflattet = ContentFlattener.flatten(p).strip();
+      if (geflattet.isEmpty()) {
+        continue;
+      }
+      var matcher = ABSATZ_MARKER.matcher(geflattet);
+      if (matcher.find()) {
+        absaetze.add(new Absatz(matcher.group(1), geflattet.substring(matcher.end())));
+      } else {
+        absaetze.add(new Absatz(null, geflattet));
+      }
+    }
+    return absaetze;
+  }
+
+  private static DocumentBuilder neuerDocumentBuilder() {
+    try {
+      var factory = DocumentBuilderFactory.newInstance();
+      factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+      factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+      factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+      factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+      factory.setXIncludeAware(false);
+      factory.setExpandEntityReferences(false);
+      var builder = factory.newDocumentBuilder();
+      builder.setEntityResolver((publicId, systemId) -> new InputSource(new StringReader("")));
+      return builder;
+    } catch (ParserConfigurationException e) {
+      throw new IllegalStateException("XML-Parser kann nicht konfiguriert werden", e);
+    }
+  }
+
+  private static Iterable<Element> kindElemente(Element parent, String name) {
+    var ergebnis = new ArrayList<Element>();
+    for (var kind = parent.getFirstChild(); kind != null; kind = kind.getNextSibling()) {
+      if (kind.getNodeType() == Node.ELEMENT_NODE && kind.getNodeName().equals(name)) {
+        ergebnis.add((Element) kind);
+      }
+    }
+    return ergebnis;
+  }
+
+  private static @Nullable Element erstesKind(Element parent, String name) {
+    for (var kind = parent.getFirstChild(); kind != null; kind = kind.getNextSibling()) {
+      if (kind.getNodeType() == Node.ELEMENT_NODE && kind.getNodeName().equals(name)) {
+        return (Element) kind;
+      }
+    }
+    return null;
+  }
+
+  private static @Nullable String kindText(Element parent, String name) {
+    var element = erstesKind(parent, name);
+    if (element == null) {
+      return null;
+    }
+    var text = element.getTextContent().strip();
+    return text.isEmpty() ? null : text;
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java b/src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java
new file mode 100644
index 0000000..2f5f735
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/synopse/HtmlRenderer.java
@@ -0,0 +1,252 @@
+package eu.mulk.aendggner.synopse;
+
+import eu.mulk.aendggner.aenderung.Aenderungsbefehl.UnbekannterBefehl;
+import eu.mulk.aendggner.gesetz.Norm;
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * Rendert eine {@link Synopse} als selbständige HTML-Datei: alte Fassung links, neue rechts,
+ * wortweise Änderungen hervorgehoben, gefolgt von einem Abschnitt „Manuell prüfen“.
+ */
+public final class HtmlRenderer {
+
+  private HtmlRenderer() {}
+
+  public static String rendere(Synopse synopse, String quelleBeschreibung) {
+    var sb = new StringBuilder();
+    sb.append("<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n<meta charset=\"utf-8\">\n");
+    sb.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n");
+    sb.append("<title>Synopse: ")
+        .append(esc(synopse.alt().jurabk()))
+        .append("</title>\n<style>\n")
+        .append(CSS)
+        .append("</style>\n</head>\n<body>\n");
+
+    rendereKopf(sb, synopse, quelleBeschreibung);
+
+    for (var eintrag : synopse.eintraege()) {
+      rendereEintrag(sb, eintrag);
+    }
+
+    rendereManuellZuPruefen(sb, synopse);
+
+    sb.append("</body>\n</html>\n");
+    return sb.toString();
+  }
+
+  private static void rendereKopf(StringBuilder sb, Synopse synopse, String quelle) {
+    sb.append("<header>\n<h1>Synopse: ").append(esc(synopse.alt().jurabk())).append("</h1>\n");
+    if (synopse.alt().langue() != null) {
+      sb.append("<p class=\"langue\">").append(esc(synopse.alt().langue())).append("</p>\n");
+    }
+    sb.append("<p class=\"quelle\">")
+        .append(esc(quelle))
+        .append(" — erstellt am ")
+        .append(LocalDate.now())
+        .append(" mit ÄndGgner</p>\n");
+    long geaendert =
+        synopse.eintraege().stream()
+            .filter(e -> e.art() != Synopse.Aenderungsart.UNVERAENDERT)
+            .count();
+    sb.append("<p class=\"statistik\">")
+        .append(geaendert)
+        .append(" geänderte Normen, ")
+        .append(synopse.manuellZuPruefen().size())
+        .append(" manuell zu prüfende Befehle</p>\n");
+    sb.append("<div class=\"spaltenkopf\"><div>Alte Fassung</div><div>Neue Fassung</div></div>\n");
+    sb.append("</header>\n");
+  }
+
+  private static void rendereEintrag(StringBuilder sb, Synopse.Eintrag eintrag) {
+    sb.append("<section class=\"norm ")
+        .append(eintrag.art().name().toLowerCase())
+        .append("\">\n<h2>")
+        .append(esc(eintrag.enbez()));
+    var titel =
+        eintrag.neuNorm().titel() != null
+            ? eintrag.neuNorm().titel()
+            : eintrag.altNorm() != null ? eintrag.altNorm().titel() : null;
+    if (titel != null) {
+      sb.append(" — ").append(esc(titel));
+    }
+    sb.append(markierung(eintrag.art()));
+    sb.append("</h2>\n");
+    if (eintrag.neuNorm().gliederung() != null) {
+      sb.append("<p class=\"gliederung\">")
+          .append(esc(eintrag.neuNorm().gliederung().anzeigeText()))
+          .append("</p>\n");
+    }
+    if (!eintrag.ursachen().isEmpty()) {
+      sb.append("<p class=\"ursachen\">Geändert durch: ");
+      var erste = true;
+      for (var ursache : eintrag.ursachen()) {
+        if (!erste) {
+          sb.append("; ");
+        }
+        sb.append(esc(ursache.befehl().provenienz().anzeigeText()));
+        erste = false;
+      }
+      sb.append("</p>\n");
+    }
+
+    var spalten = spaltenFuer(eintrag);
+    sb.append("<div class=\"vergleich\">\n<div class=\"alt\">")
+        .append(
+            spalten.altHtml().isEmpty()
+                ? "<span class=\"leer\">(nicht vorhanden)</span>"
+                : spalten.altHtml())
+        .append("</div>\n<div class=\"neu\">")
+        .append(
+            spalten.neuHtml().isEmpty()
+                ? "<span class=\"leer\">(nicht vorhanden)</span>"
+                : spalten.neuHtml())
+        .append("</div>\n</div>\n</section>\n");
+  }
+
+  private static WortDiff.Spalten spaltenFuer(Synopse.Eintrag eintrag) {
+    var altText = eintrag.altNorm() == null ? "" : textVon(eintrag.altNorm());
+    var neuText = textVon(eintrag.neuNorm());
+    if (eintrag.art() == Synopse.Aenderungsart.NEU) {
+      return new WortDiff.Spalten("", "<ins>" + WortDiff.escapeHtml(neuText) + "</ins>");
+    }
+    return WortDiff.vergleiche(altText, neuText);
+  }
+
+  private static String textVon(Norm norm) {
+    return norm.gesamtText();
+  }
+
+  private static String markierung(Synopse.Aenderungsart art) {
+    return switch (art) {
+      case NEU -> " <span class=\"badge neu-badge\">neu</span>";
+      case AUFGEHOBEN -> " <span class=\"badge aufgehoben-badge\">aufgehoben</span>";
+      case GEAENDERT -> " <span class=\"badge geaendert-badge\">geändert</span>";
+      case UNVERAENDERT -> "";
+    };
+  }
+
+  private static void rendereManuellZuPruefen(StringBuilder sb, Synopse synopse) {
+    if (synopse.manuellZuPruefen().isEmpty() && synopse.warnungen().isEmpty()) {
+      return;
+    }
+    sb.append("<section class=\"manuell\">\n<h2>Manuell prüfen</h2>\n");
+    if (!synopse.warnungen().isEmpty()) {
+      sb.append("<h3>Warnungen der Textverarbeitung</h3>\n<ul>\n");
+      for (var warnung : synopse.warnungen()) {
+        sb.append("<li>").append(esc(warnung)).append("</li>\n");
+      }
+      sb.append("</ul>\n");
+    }
+    if (!synopse.manuellZuPruefen().isEmpty()) {
+      sb.append("<h3>Nicht automatisch angewandte Befehle</h3>\n<ol>\n");
+      for (var eintrag : synopse.manuellZuPruefen()) {
+        var befehl = eintrag.befehl();
+        sb.append("<li><strong>")
+            .append(esc(befehl.provenienz().anzeigeText()))
+            .append("</strong>");
+        if (!(befehl instanceof UnbekannterBefehl) || !eintrag.begruendung().isEmpty()) {
+          sb.append(" — ").append(esc(eintrag.begruendung()));
+        }
+        sb.append("<br><span class=\"originaltext\">")
+            .append(esc(befehl.provenienz().originalText()))
+            .append("</span></li>\n");
+      }
+      sb.append("</ol>\n");
+    }
+    sb.append("</section>\n");
+  }
+
+  private static String esc(String text) {
+    return WortDiff.escapeHtml(text);
+  }
+
+  static List<String> zeilenVon(String text) {
+    return text.lines().toList();
+  }
+
+  private static final String CSS =
+      """
+      :root {
+        color-scheme: light dark;
+        --del-bg: #ffd7d7;
+        --del-fg: #8b0000;
+        --ins-bg: #d7f5d7;
+        --ins-fg: #005f00;
+        --rand: #ccc;
+        --dezent: #666;
+      }
+      @media (prefers-color-scheme: dark) {
+        :root {
+          --del-bg: #5a1f1f;
+          --del-fg: #ffb3b3;
+          --ins-bg: #1f4a1f;
+          --ins-fg: #b3ffb3;
+          --rand: #555;
+          --dezent: #aaa;
+        }
+      }
+      body {
+        font-family: Georgia, "Times New Roman", serif;
+        line-height: 1.45;
+        max-width: 90rem;
+        margin: 0 auto;
+        padding: 1rem 2rem;
+      }
+      header h1 { margin-bottom: 0.2rem; }
+      .langue { font-style: italic; margin-top: 0; }
+      .quelle, .statistik, .gliederung, .ursachen { color: var(--dezent); font-size: 0.9rem; }
+      .spaltenkopf {
+        display: grid;
+        grid-template-columns: 1fr 1fr;
+        gap: 1rem;
+        font-weight: bold;
+        border-bottom: 2px solid var(--rand);
+        padding: 0.5rem 0;
+        position: sticky;
+        top: 0;
+        background: inherit;
+      }
+      section.norm { border-bottom: 1px solid var(--rand); padding: 0.7rem 0; }
+      section.norm h2 { font-size: 1.15rem; margin: 0.3rem 0; }
+      .vergleich {
+        display: grid;
+        grid-template-columns: 1fr 1fr;
+        gap: 1rem;
+        align-items: start;
+      }
+      .vergleich > div {
+        white-space: pre-wrap;
+        overflow-wrap: anywhere;
+        font-size: 0.95rem;
+      }
+      del, .alt del {
+        background: var(--del-bg);
+        color: var(--del-fg);
+        text-decoration: line-through;
+      }
+      ins, .neu ins {
+        background: var(--ins-bg);
+        color: var(--ins-fg);
+        text-decoration: none;
+      }
+      .leer { color: var(--dezent); font-style: italic; }
+      .badge {
+        font-family: system-ui, sans-serif;
+        font-size: 0.7rem;
+        font-weight: normal;
+        border-radius: 0.6rem;
+        padding: 0.1rem 0.55rem;
+        vertical-align: middle;
+      }
+      .neu-badge { background: var(--ins-bg); color: var(--ins-fg); }
+      .aufgehoben-badge { background: var(--del-bg); color: var(--del-fg); }
+      .geaendert-badge { border: 1px solid var(--rand); color: var(--dezent); }
+      section.manuell { margin-top: 2rem; }
+      section.manuell li { margin-bottom: 0.7rem; }
+      .originaltext { color: var(--dezent); font-size: 0.85rem; }
+      @media print {
+        .vergleich { break-inside: avoid; }
+      }
+      """;
+}
diff --git a/src/main/java/eu/mulk/aendggner/synopse/Synopse.java b/src/main/java/eu/mulk/aendggner/synopse/Synopse.java
new file mode 100644
index 0000000..26730a2
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/synopse/Synopse.java
@@ -0,0 +1,35 @@
+package eu.mulk.aendggner.synopse;
+
+import eu.mulk.aendggner.anwendung.BefehlAnwender.AngewandteAenderung;
+import eu.mulk.aendggner.gesetz.Gesetz;
+import eu.mulk.aendggner.gesetz.Norm;
+import java.util.List;
+import org.jspecify.annotations.Nullable;
+
+/** Eine Gegenüberstellung alter und neuer Fassung, normweise. */
+public record Synopse(
+    Gesetz alt,
+    Gesetz neu,
+    List<Eintrag> eintraege,
+    List<AngewandteAenderung> manuellZuPruefen,
+    List<String> warnungen) {
+
+  public enum Aenderungsart {
+    UNVERAENDERT,
+    GEAENDERT,
+    NEU,
+    AUFGEHOBEN
+  }
+
+  /**
+   * @param altNorm die Norm in der alten Fassung; {@code null} bei neu eingefügten Normen.
+   * @param neuNorm die Norm in der neuen Fassung.
+   */
+  public record Eintrag(
+      @Nullable Norm altNorm, Norm neuNorm, Aenderungsart art, List<AngewandteAenderung> ursachen) {
+
+    public String enbez() {
+      return neuNorm.enbez();
+    }
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java b/src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java
new file mode 100644
index 0000000..0f88538
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/synopse/SynopseBuilder.java
@@ -0,0 +1,60 @@
+package eu.mulk.aendggner.synopse;
+
+import eu.mulk.aendggner.anwendung.BefehlAnwender.AnwendungsErgebnis;
+import eu.mulk.aendggner.anwendung.BefehlAnwender.Status;
+import eu.mulk.aendggner.gesetz.Gesetz;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Paart die Normen alter und neuer Fassung zu Synopse-Einträgen. */
+public final class SynopseBuilder {
+
+  private SynopseBuilder() {}
+
+  /**
+   * @param alt das Stammgesetz vor Anwendung der Befehle.
+   * @param anwendung das Ergebnis des {@link eu.mulk.aendggner.anwendung.BefehlAnwender}.
+   * @param parseWarnungen Warnungen aus dem Parsen des Änderungsgesetzes.
+   * @param vollstaendig auch unveränderte Normen aufnehmen.
+   */
+  public static Synopse baue(
+      Gesetz alt, AnwendungsErgebnis anwendung, List<String> parseWarnungen, boolean vollstaendig) {
+    var neu = anwendung.neu();
+    var eintraege = new ArrayList<Synopse.Eintrag>();
+
+    for (var neuNorm : neu.normen()) {
+      var altNorm = alt.norm(neuNorm.enbez()).orElse(null);
+
+      Synopse.Aenderungsart art;
+      if (altNorm == null) {
+        art = Synopse.Aenderungsart.NEU;
+      } else if (neuNorm.weggefallen() && !altNorm.weggefallen()) {
+        art = Synopse.Aenderungsart.AUFGEHOBEN;
+      } else if (!gleicherInhalt(altNorm, neuNorm)) {
+        art = Synopse.Aenderungsart.GEAENDERT;
+      } else {
+        art = Synopse.Aenderungsart.UNVERAENDERT;
+      }
+
+      if (art == Synopse.Aenderungsart.UNVERAENDERT && !vollstaendig) {
+        continue;
+      }
+
+      var ursachen =
+          anwendung.protokoll().stream()
+              .filter(a -> a.betroffeneEnbez().contains(neuNorm.enbez()))
+              .toList();
+      eintraege.add(new Synopse.Eintrag(altNorm, neuNorm, art, ursachen));
+    }
+
+    var manuell =
+        anwendung.protokoll().stream().filter(a -> a.status() == Status.MANUELL_PRUEFEN).toList();
+
+    return new Synopse(alt, neu, eintraege, manuell, parseWarnungen);
+  }
+
+  private static boolean gleicherInhalt(
+      eu.mulk.aendggner.gesetz.Norm a, eu.mulk.aendggner.gesetz.Norm b) {
+    return a.gesamtText().equals(b.gesamtText()) && java.util.Objects.equals(a.titel(), b.titel());
+  }
+}
diff --git a/src/main/java/eu/mulk/aendggner/synopse/WortDiff.java b/src/main/java/eu/mulk/aendggner/synopse/WortDiff.java
new file mode 100644
index 0000000..00e6923
--- /dev/null
+++ b/src/main/java/eu/mulk/aendggner/synopse/WortDiff.java
@@ -0,0 +1,61 @@
+package eu.mulk.aendggner.synopse;
+
+import com.github.difflib.text.DiffRowGenerator;
+import java.util.List;
+
+/**
+ * Erzeugt einen wortweisen HTML-Diff zweier Texte: Entferntes links als {@code <del>}, Neues rechts
+ * als {@code <ins>}. Die Eingaben werden vor dem Taggen HTML-escapet.
+ */
+final class WortDiff {
+
+  /** Beide Spalten einer Diff-Darstellung, als HTML. */
+  record Spalten(String altHtml, String neuHtml) {}
+
+  private static final DiffRowGenerator GENERATOR =
+      DiffRowGenerator.create()
+          .showInlineDiffs(true)
+          .mergeOriginalRevised(false)
+          .inlineDiffByWord(true)
+          .oldTag(oeffnend -> oeffnend ? "<del>" : "</del>")
+          .newTag(oeffnend -> oeffnend ? "<ins>" : "</ins>")
+          .lineNormalizer(WortDiff::escapeHtml)
+          .build();
+
+  private WortDiff() {}
+
+  static Spalten vergleiche(String altText, String neuText) {
+    var zeilenAlt = altText.lines().toList();
+    var zeilenNeu = neuText.lines().toList();
+    var zeilen = GENERATOR.generateDiffRows(zeilenAlt, zeilenNeu);
+
+    var alt = new StringBuilder();
+    var neu = new StringBuilder();
+    for (var zeile : zeilen) {
+      if (!zeile.getOldLine().isEmpty()) {
+        if (alt.length() > 0) {
+          alt.append('\n');
+        }
+        alt.append(zeile.getOldLine());
+      }
+      if (!zeile.getNewLine().isEmpty()) {
+        if (neu.length() > 0) {
+          neu.append('\n');
+        }
+        neu.append(zeile.getNewLine());
+      }
+    }
+    return new Spalten(alt.toString(), neu.toString());
+  }
+
+  static String escapeHtml(String text) {
+    return text.replace("&", "&amp;")
+        .replace("<", "&lt;")
+        .replace(">", "&gt;")
+        .replace("\"", "&quot;");
+  }
+
+  static List<String> nurEscapen(List<String> zeilen) {
+    return zeilen.stream().map(WortDiff::escapeHtml).toList();
+  }
+}
