This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch available-felidae
in repository https://gitbox.apache.org/repos/asf/maven-release.git

commit 465144271d88fd7ae6089e7f340f1e0e8a5c9354
Author: Guillaume Nodet <[email protected]>
AuthorDate: Fri Apr 3 16:58:19 2026 +0200

    Replace JDOM2 with DomTrip for lossless POM XML editing
    
    DomTrip provides lossless XML round-tripping, preserving comments,
    whitespace, attribute order, quote styles, CDATA sections, and entity
    encoding. This eliminates the intro/outtro hacks required by JDOM2.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 maven-release-manager/pom.xml                      |   4 +-
 .../release/phase/AbstractRewritePomsPhase.java    |   6 +-
 .../JDomBuild.java => domtrip/DomTripBuild.java}   |  68 ++----
 .../DomTripDependency.java}                        |  21 +-
 .../DomTripDependencyManagement.java}              |  44 ++--
 .../DomTripExtension.java}                         |  21 +-
 .../DomTripMavenCoordinate.java}                   |  42 ++--
 .../release/transform/domtrip/DomTripModel.java    | 165 +++++++++++++
 .../transform/domtrip/DomTripModelBase.java        |  67 ++++++
 .../release/transform/domtrip/DomTripModelETL.java | 108 +++++++++
 .../DomTripModelETLFactory.java}                   |  18 +-
 .../JDomParent.java => domtrip/DomTripParent.java} |  27 +--
 .../JDomPlugin.java => domtrip/DomTripPlugin.java} |  46 ++--
 .../DomTripPluginManagement.java}                  |  43 ++--
 .../DomTripProfile.java}                           |  23 +-
 .../DomTripProperties.java}                        |  46 ++--
 .../DomTripReportPlugin.java}                      |  21 +-
 .../DomTripReporting.java}                         |  43 ++--
 .../JDomScm.java => domtrip/DomTripScm.java}       |  26 +-
 .../release/transform/domtrip/DomTripUtils.java    |  75 ++++++
 .../shared/release/transform/jdom2/JDomModel.java  | 210 ----------------
 .../release/transform/jdom2/JDomModelBase.java     |  99 --------
 .../release/transform/jdom2/JDomModelETL.java      | 225 ------------------
 .../shared/release/transform/jdom2/JDomUtils.java  | 113 ---------
 .../AbstractRewritingReleasePhaseTestCase.java     |   4 +-
 .../release/transform/jdom2/JDomBuildTest.java     | 264 ---------------------
 .../jdom2/JDomDependencyManagementTest.java        |  80 -------
 .../transform/jdom2/JDomDependencyTest.java        | 160 -------------
 .../release/transform/jdom2/JDomExtensionTest.java |  93 --------
 .../release/transform/jdom2/JDomModelTest.java     | 101 --------
 .../release/transform/jdom2/JDomParentTest.java    |  90 -------
 .../transform/jdom2/JDomPropertiesTest.java        | 138 -----------
 .../release/transform/jdom2/JDomScmTest.java       | 125 ----------
 pom.xml                                            |   6 +-
 34 files changed, 613 insertions(+), 2009 deletions(-)

diff --git a/maven-release-manager/pom.xml b/maven-release-manager/pom.xml
index d1252e7c..7b58f7e2 100644
--- a/maven-release-manager/pom.xml
+++ b/maven-release-manager/pom.xml
@@ -149,8 +149,8 @@ under the License.
     </dependency>
 
     <dependency>
-      <groupId>org.jdom</groupId>
-      <artifactId>jdom2</artifactId>
+      <groupId>eu.maveniverse.maven.domtrip</groupId>
+      <artifactId>domtrip-core</artifactId>
     </dependency>
 
     <dependency>
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
index 8311a136..4ded83f7 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractRewritePomsPhase.java
@@ -62,7 +62,7 @@ import 
org.apache.maven.shared.release.transform.MavenCoordinate;
 import org.apache.maven.shared.release.transform.ModelETL;
 import org.apache.maven.shared.release.transform.ModelETLFactory;
 import org.apache.maven.shared.release.transform.ModelETLRequest;
-import org.apache.maven.shared.release.transform.jdom2.JDomModelETLFactory;
+import 
org.apache.maven.shared.release.transform.domtrip.DomTripModelETLFactory;
 import org.apache.maven.shared.release.util.CiFriendlyVersion;
 import org.apache.maven.shared.release.util.MavenExpression;
 import org.apache.maven.shared.release.util.ReleaseUtil;
@@ -90,9 +90,9 @@ public abstract class AbstractRewritePomsPhase extends 
AbstractReleasePhase impl
     private Map<String, ScmTranslator> scmTranslators;
 
     /**
-     * Use jdom2-sax as default.
+     * Use domtrip as default.
      */
-    private String modelETL = JDomModelETLFactory.NAME;
+    private String modelETL = DomTripModelETLFactory.NAME;
 
     private long startTime = -1 * 1000;
 
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomBuild.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripBuild.java
similarity index 77%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomBuild.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripBuild.java
index 74ed10c2..7e904fa7 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomBuild.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripBuild.java
@@ -16,36 +16,33 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Extension;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginManagement;
 import org.apache.maven.model.Resource;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms BUILD element.
+ * DomTrip implementation of poms BUILD element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomBuild extends Build {
+public class DomTripBuild extends Build {
     private final Element build;
+    private final Editor editor;
 
-    /**
-     * <p>Constructor for JDomBuild.</p>
-     *
-     * @param build a {@link org.jdom2.Element} object
-     */
-    public JDomBuild(Element build) {
+    public DomTripBuild(Element build, Editor editor) {
         this.build = build;
+        this.editor = editor;
     }
 
     @Override
@@ -55,18 +52,11 @@ public class JDomBuild extends Build {
 
     @Override
     public List<Extension> getExtensions() {
-        Element extensionsElm = build.getChild("extensions", 
build.getNamespace());
-        if (extensionsElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> extensionElms = 
extensionsElm.getChildren("extension", build.getNamespace());
-
-            List<Extension> extensions = new ArrayList<>(extensionElms.size());
-            for (Element extensionElm : extensionElms) {
-                extensions.add(new JDomExtension(extensionElm));
-            }
-            return extensions;
-        }
+        return build.childElement("extensions")
+                .map(exts -> exts.childElements("extension")
+                        .map(ext -> (Extension) new DomTripExtension(ext, 
editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
     }
 
     @Override
@@ -221,12 +211,9 @@ public class JDomBuild extends Build {
 
     @Override
     public PluginManagement getPluginManagement() {
-        Element pluginManagementElm = build.getChild("pluginManagement", 
build.getNamespace());
-        if (pluginManagementElm == null) {
-            return null;
-        } else {
-            return new JDomPluginManagement(pluginManagementElm);
-        }
+        return build.childElement("pluginManagement")
+                .map(elm -> (PluginManagement) new 
DomTripPluginManagement(elm, editor))
+                .orElse(null);
     }
 
     @Override
@@ -241,20 +228,11 @@ public class JDomBuild extends Build {
 
     @Override
     public List<Plugin> getPlugins() {
-        Element pluginsElm = build.getChild("plugins", build.getNamespace());
-        if (pluginsElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> pluginElms = pluginsElm.getChildren("plugin", 
build.getNamespace());
-
-            List<Plugin> plugins = new ArrayList<>(pluginElms.size());
-
-            for (Element pluginElm : pluginElms) {
-                plugins.add(new JDomPlugin(pluginElm));
-            }
-
-            return plugins;
-        }
+        return build.childElement("plugins")
+                .map(plugins -> plugins.childElements("plugin")
+                        .map(plugin -> (Plugin) new DomTripPlugin(plugin, 
editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomDependency.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripDependency.java
similarity index 87%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomDependency.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripDependency.java
index 9bc7b6e9..1d819763 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomDependency.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripDependency.java
@@ -16,31 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
 import java.util.List;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Exclusion;
 import org.apache.maven.shared.release.transform.MavenCoordinate;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms DEPENDENCY element.
+ * DomTrip implementation of poms DEPENDENCY element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomDependency extends Dependency implements MavenCoordinate {
+public class DomTripDependency extends Dependency implements MavenCoordinate {
     private final MavenCoordinate coordinate;
 
-    /**
-     * <p>Constructor for JDomDependency.</p>
-     *
-     * @param dependency a {@link org.jdom2.Element} object
-     */
-    public JDomDependency(Element dependency) {
-        this.coordinate = new JDomMavenCoordinate(dependency);
+    public DomTripDependency(Element dependency, Editor editor) {
+        this.coordinate = new DomTripMavenCoordinate(dependency, editor);
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyManagement.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripDependencyManagement.java
similarity index 57%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyManagement.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripDependencyManagement.java
index cfe6e921..bece5bc6 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyManagement.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripDependencyManagement.java
@@ -16,32 +16,29 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.DependencyManagement;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms DEPENDENCYMANAGEMENT element.
+ * DomTrip implementation of poms DEPENDENCYMANAGEMENT element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomDependencyManagement extends DependencyManagement {
+public class DomTripDependencyManagement extends DependencyManagement {
     private final Element dependencyManagement;
+    private final Editor editor;
 
-    /**
-     * <p>Constructor for JDomDependencyManagement.</p>
-     *
-     * @param dependencyManagement a {@link org.jdom2.Element} object
-     */
-    public JDomDependencyManagement(Element dependencyManagement) {
+    public DomTripDependencyManagement(Element dependencyManagement, Editor 
editor) {
         this.dependencyManagement = dependencyManagement;
+        this.editor = editor;
     }
 
     @Override
@@ -51,21 +48,12 @@ public class JDomDependencyManagement extends 
DependencyManagement {
 
     @Override
     public List<Dependency> getDependencies() {
-        Element dependenciesElm = 
dependencyManagement.getChild("dependencies", 
dependencyManagement.getNamespace());
-        if (dependenciesElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> dependencyElms =
-                    dependenciesElm.getChildren("dependency", 
dependencyManagement.getNamespace());
-
-            List<Dependency> dependencies = new 
ArrayList<>(dependencyElms.size());
-
-            for (Element dependencyElm : dependencyElms) {
-                dependencies.add(new JDomDependency(dependencyElm));
-            }
-
-            return dependencies;
-        }
+        return dependencyManagement
+                .childElement("dependencies")
+                .map(deps -> deps.childElements("dependency")
+                        .map(dep -> (Dependency) new DomTripDependency(dep, 
editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomExtension.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripExtension.java
similarity index 77%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomExtension.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripExtension.java
index 2a08c35c..e93f51d8 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomExtension.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripExtension.java
@@ -16,28 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Extension;
 import org.apache.maven.shared.release.transform.MavenCoordinate;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms EXTENSION element.
+ * DomTrip implementation of poms EXTENSION element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomExtension extends Extension implements MavenCoordinate {
+public class DomTripExtension extends Extension implements MavenCoordinate {
     private final MavenCoordinate coordinate;
 
-    /**
-     * <p>Constructor for JDomExtension.</p>
-     *
-     * @param extension a {@link org.jdom2.Element} object
-     */
-    public JDomExtension(Element extension) {
-        this.coordinate = new JDomMavenCoordinate(extension);
+    public DomTripExtension(Element extension, Editor editor) {
+        this.coordinate = new DomTripMavenCoordinate(extension, editor);
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomMavenCoordinate.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripMavenCoordinate.java
similarity index 55%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomMavenCoordinate.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripMavenCoordinate.java
index 7f431d81..b1ec8fcd 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomMavenCoordinate.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripMavenCoordinate.java
@@ -16,60 +16,48 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.shared.release.transform.MavenCoordinate;
-import org.jdom2.Element;
 
 /**
- * <p>JDomMavenCoordinate class.</p>
+ * DomTrip implementation of {@link MavenCoordinate}.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomMavenCoordinate implements MavenCoordinate {
+public class DomTripMavenCoordinate implements MavenCoordinate {
     private final Element element;
+    private final Editor editor;
 
-    /**
-     * <p>Constructor for JDomMavenCoordinate.</p>
-     *
-     * @param elm a {@link org.jdom2.Element} object
-     */
-    public JDomMavenCoordinate(Element elm) {
-        this.element = elm;
+    public DomTripMavenCoordinate(Element element, Editor editor) {
+        this.element = element;
+        this.editor = editor;
     }
 
     @Override
     public String getGroupId() {
-        return element.getChildTextTrim("groupId", element.getNamespace());
+        return element.childTextTrimmed("groupId");
     }
 
     @Override
     public String getArtifactId() {
-        return element.getChildTextTrim("artifactId", element.getNamespace());
+        return element.childTextTrimmed("artifactId");
     }
 
     @Override
     public String getVersion() {
-        Element version = getVersionElement();
-        if (version == null) {
-            return null;
-        } else {
-            return version.getTextTrim();
-        }
-    }
-
-    private Element getVersionElement() {
-        return element.getChild("version", element.getNamespace());
+        return element.childElement("version").map(e -> 
e.textContentTrimmed()).orElse(null);
     }
 
     @Override
     public void setVersion(String version) {
-        JDomUtils.rewriteValue(getVersionElement(), version);
+        element.childElement("version").ifPresent(e -> 
DomTripUtils.rewriteValue(editor, e, version));
     }
 
     @Override
     public String getName() {
-        return element.getName();
+        return element.name();
     }
 }
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModel.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModel.java
new file mode 100644
index 00000000..c04f001a
--- /dev/null
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModel.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.release.transform.domtrip;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+import eu.maveniverse.domtrip.Document;
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.Scm;
+import org.apache.maven.shared.release.config.ReleaseDescriptor;
+import org.apache.maven.shared.release.util.CiFriendlyVersion;
+
+/**
+ * DomTrip implementation of poms PROJECT element.
+ *
+ * @since 3.4
+ */
+public class DomTripModel extends Model {
+    private final Element project;
+    private final Editor editor;
+    private final DomTripModelBase modelBase;
+    private final ReleaseDescriptor releaseDescriptor;
+
+    public DomTripModel(Document document, Editor editor, ReleaseDescriptor 
releaseDescriptor) {
+        this(document.root(), editor, releaseDescriptor);
+    }
+
+    public DomTripModel(Element project, Editor editor, ReleaseDescriptor 
releaseDescriptor) {
+        this.project = project;
+        this.editor = editor;
+        this.releaseDescriptor = releaseDescriptor;
+        this.modelBase = new DomTripModelBase(project, editor);
+    }
+
+    @Override
+    public Build getBuild() {
+        return modelBase.getBuild();
+    }
+
+    @Override
+    public List<Dependency> getDependencies() {
+        return modelBase.getDependencies();
+    }
+
+    @Override
+    public DependencyManagement getDependencyManagement() {
+        return modelBase.getDependencyManagement();
+    }
+
+    @Override
+    public Parent getParent() {
+        return project.childElement("parent")
+                .map(elm -> (Parent) new DomTripParent(elm, editor))
+                .orElse(null);
+    }
+
+    @Override
+    public List<Profile> getProfiles() {
+        return project.childElement("profiles")
+                .map(profilesElm -> profilesElm
+                        .childElements("profile")
+                        .map(profileElm -> (Profile) new 
DomTripProfile(profileElm, editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
+    }
+
+    @Override
+    public Properties getProperties() {
+        return project.childElement("properties")
+                .map(elm -> (Properties) new DomTripProperties(elm, editor))
+                .orElse(null);
+    }
+
+    @Override
+    public Reporting getReporting() {
+        return project.childElement("reporting")
+                .map(elm -> (Reporting) new DomTripReporting(elm, editor))
+                .orElse(null);
+    }
+
+    @Override
+    public void setScm(Scm scm) {
+        if (scm == null) {
+            project.childElement("scm").ifPresent(editor::removeElement);
+        } else {
+            Element scmRoot = editor.addElement(project, "scm");
+
+            // Write current values to DomTrip tree
+            Scm domTripScm = new DomTripScm(scmRoot, editor);
+            domTripScm.setConnection(scm.getConnection());
+            domTripScm.setDeveloperConnection(scm.getDeveloperConnection());
+            domTripScm.setTag(scm.getTag());
+            domTripScm.setUrl(scm.getUrl());
+        }
+    }
+
+    @Override
+    public Scm getScm() {
+        return project.childElement("scm")
+                .map(elm -> (Scm) new DomTripScm(elm, editor))
+                .orElse(null);
+    }
+
+    @Override
+    public void setVersion(String version) {
+        Element versionElement = project.childElement("version").orElse(null);
+
+        String parentVersion;
+        Element parent = project.childElement("parent").orElse(null);
+        if (parent != null) {
+            parentVersion = parent.childTextTrimmed("version");
+        } else {
+            parentVersion = null;
+        }
+
+        if (versionElement == null) {
+            // never add version when parent references CI friendly property
+            if (!(parentVersion != null && 
CiFriendlyVersion.isCiFriendlyVersion(parentVersion))
+                    && !version.equals(parentVersion)) {
+                // we will add this after artifactId, since it was missing but 
different from the inherited version
+                Element artifactIdElement = 
project.childElement("artifactId").orElse(null);
+                if (artifactIdElement != null) {
+                    versionElement = 
editor.insertElementAfter(artifactIdElement, "version", version);
+                } else {
+                    editor.addElement(project, "version", version);
+                }
+            }
+        } else {
+            String versionText = versionElement.textContentTrimmed();
+            if (versionText != null && 
CiFriendlyVersion.isCiFriendlyVersion(versionText)) {
+                // try to rewrite property if CI friendly expression is used
+                CiFriendlyVersion.rewriteCiFriendlyProperties(version, 
getProperties(), releaseDescriptor);
+            } else {
+                DomTripUtils.rewriteValue(editor, versionElement, version);
+            }
+        }
+    }
+}
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelBase.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelBase.java
new file mode 100644
index 00000000..363823e0
--- /dev/null
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelBase.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.release.transform.domtrip;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+
+/**
+ * DomTrip shared model base logic.
+ *
+ * @since 3.4
+ */
+public class DomTripModelBase {
+    private final Element modelBase;
+    private final Editor editor;
+
+    public DomTripModelBase(Element modelBase, Editor editor) {
+        this.modelBase = modelBase;
+        this.editor = editor;
+    }
+
+    public Build getBuild() {
+        return modelBase
+                .childElement("build")
+                .map(elm -> (Build) new DomTripBuild(elm, editor))
+                .orElse(null);
+    }
+
+    public List<Dependency> getDependencies() {
+        return modelBase
+                .childElement("dependencies")
+                .map(deps -> deps.childElements("dependency")
+                        .map(dep -> (Dependency) new DomTripDependency(dep, 
editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
+    }
+
+    public DependencyManagement getDependencyManagement() {
+        return modelBase
+                .childElement("dependencyManagement")
+                .map(elm -> (DependencyManagement) new 
DomTripDependencyManagement(elm, editor))
+                .orElse(null);
+    }
+}
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelETL.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelETL.java
new file mode 100644
index 00000000..d3a16f6f
--- /dev/null
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelETL.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.release.transform.domtrip;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+
+import eu.maveniverse.domtrip.Document;
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
+import org.apache.maven.model.Model;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.release.ReleaseExecutionException;
+import org.apache.maven.shared.release.config.ReleaseDescriptor;
+import org.apache.maven.shared.release.transform.ModelETL;
+import org.codehaus.plexus.util.xml.XmlStreamWriter;
+
+/**
+ * DomTrip implementation for extracting, transforming and loading the Model 
(pom.xml).
+ * <p>
+ * DomTrip provides lossless XML round-tripping, preserving all formatting 
details
+ * including comments, whitespace, attribute order, quote styles, and entity 
encoding.
+ * This eliminates the need for the intro/outtro hacks required by the JDOM2 
implementation.
+ *
+ * @since 3.4
+ */
+public class DomTripModelETL implements ModelETL {
+    private ReleaseDescriptor releaseDescriptor;
+
+    private MavenProject project;
+
+    private Document document;
+
+    private Editor editor;
+
+    public void setReleaseDescriptor(ReleaseDescriptor releaseDescriptor) {
+        this.releaseDescriptor = releaseDescriptor;
+    }
+
+    public void setProject(MavenProject project) {
+        this.project = project;
+    }
+
+    @Override
+    public void extract(File pomFile) throws ReleaseExecutionException {
+        try {
+            document = Document.of(pomFile.toPath());
+            editor = new Editor(document);
+        } catch (Exception e) {
+            throw new ReleaseExecutionException("Error reading POM: " + 
e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void transform() {}
+
+    @Override
+    public void load(File targetFile) throws ReleaseExecutionException {
+        writePom(targetFile);
+    }
+
+    @Override
+    public Model getModel() {
+        return new DomTripModel(document, editor, releaseDescriptor);
+    }
+
+    private void writePom(File pomFile) throws ReleaseExecutionException {
+        if (releaseDescriptor.isAddSchema()) {
+            Element rootElement = document.root();
+
+            String modelVersion = project.getModelVersion();
+            String pomNamespaceUri = "http://maven.apache.org/POM/"; + 
modelVersion;
+            String xsiNamespaceUri = 
"http://www.w3.org/2001/XMLSchema-instance";;
+
+            rootElement.namespaceDeclaration("", pomNamespaceUri);
+            rootElement.namespaceDeclaration("xsi", xsiNamespaceUri);
+
+            if (rootElement.attribute("xsi:schemaLocation") == null) {
+                rootElement.attribute(
+                        "xsi:schemaLocation",
+                        pomNamespaceUri + " 
https://maven.apache.org/xsd/maven-"; + modelVersion + ".xsd");
+            }
+        }
+
+        try (Writer writer = new XmlStreamWriter(pomFile)) {
+            writer.write(document.toXml());
+        } catch (IOException e) {
+            throw new ReleaseExecutionException("Error writing POM: " + 
e.getMessage(), e);
+        }
+    }
+}
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelETLFactory.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelETLFactory.java
similarity index 72%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelETLFactory.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelETLFactory.java
index cb904555..01790adb 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelETLFactory.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripModelETLFactory.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
 import javax.inject.Named;
 import javax.inject.Singleton;
@@ -25,21 +25,19 @@ import 
org.apache.maven.shared.release.transform.ModelETLFactory;
 import org.apache.maven.shared.release.transform.ModelETLRequest;
 
 /**
- * <p>JDomModelETLFactory class.</p>
+ * Factory for creating {@link DomTripModelETL} instances.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
 @Singleton
-@Named(JDomModelETLFactory.NAME)
-public class JDomModelETLFactory implements ModelETLFactory {
-    public static final String NAME = "jdom2-sax";
+@Named(DomTripModelETLFactory.NAME)
+public class DomTripModelETLFactory implements ModelETLFactory {
+    public static final String NAME = "domtrip";
 
     @Override
-    public JDomModelETL newInstance(ModelETLRequest request) {
-        JDomModelETL result = new JDomModelETL();
+    public DomTripModelETL newInstance(ModelETLRequest request) {
+        DomTripModelETL result = new DomTripModelETL();
 
-        result.setLs(request.getLineSeparator());
         result.setProject(request.getProject());
         result.setReleaseDescriptor(request.getReleaseDescriptor());
 
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomParent.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripParent.java
similarity index 76%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomParent.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripParent.java
index bb078be8..80756f36 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomParent.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripParent.java
@@ -16,37 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Parent;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms PARENT element.
+ * DomTrip implementation of poms PARENT element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomParent extends Parent {
-    private Element parent;
+public class DomTripParent extends Parent {
+    private final Element parent;
+    private final Editor editor;
 
-    /**
-     * <p>Constructor for JDomParent.</p>
-     *
-     * @param parent a {@link org.jdom2.Element} object
-     */
-    public JDomParent(Element parent) {
+    public DomTripParent(Element parent, Editor editor) {
         this.parent = parent;
+        this.editor = editor;
     }
 
     @Override
     public String getVersion() {
-        return parent.getChildText("version", parent.getNamespace());
+        return parent.childText("version");
     }
 
     @Override
     public void setVersion(String version) {
-        JDomUtils.rewriteElement("version", version, parent, 
parent.getNamespace());
+        DomTripUtils.rewriteElement(editor, "version", version, parent);
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomPlugin.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripPlugin.java
similarity index 76%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomPlugin.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripPlugin.java
index 60b65252..e8479af4 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomPlugin.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripPlugin.java
@@ -16,37 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginExecution;
 import org.apache.maven.shared.release.transform.MavenCoordinate;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms PLUGIN element.
+ * DomTrip implementation of poms PLUGIN element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomPlugin extends Plugin implements MavenCoordinate {
-    private Element plugin;
+public class DomTripPlugin extends Plugin implements MavenCoordinate {
+    private final Element plugin;
+    private final Editor editor;
     private final MavenCoordinate coordinate;
 
-    /**
-     * <p>Constructor for JDomPlugin.</p>
-     *
-     * @param plugin a {@link org.jdom2.Element} object
-     */
-    public JDomPlugin(Element plugin) {
+    public DomTripPlugin(Element plugin, Editor editor) {
         this.plugin = plugin;
-        this.coordinate = new JDomMavenCoordinate(plugin);
+        this.editor = editor;
+        this.coordinate = new DomTripMavenCoordinate(plugin, editor);
     }
 
     @Override
@@ -66,20 +63,11 @@ public class JDomPlugin extends Plugin implements 
MavenCoordinate {
 
     @Override
     public List<Dependency> getDependencies() {
-        Element dependenciesElm = plugin.getChild("dependencies", 
plugin.getNamespace());
-        if (dependenciesElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> dependencyElms = 
dependenciesElm.getChildren("dependency", plugin.getNamespace());
-
-            List<Dependency> dependencies = new 
ArrayList<>(dependencyElms.size());
-
-            for (Element dependencyElm : dependencyElms) {
-                dependencies.add(new JDomDependency(dependencyElm));
-            }
-
-            return dependencies;
-        }
+        return plugin.childElement("dependencies")
+                .map(deps -> deps.childElements("dependency")
+                        .map(dep -> (Dependency) new DomTripDependency(dep, 
editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomPluginManagement.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripPluginManagement.java
similarity index 63%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomPluginManagement.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripPluginManagement.java
index 00e33183..49214cae 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomPluginManagement.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripPluginManagement.java
@@ -16,33 +16,30 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginManagement;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms PLUGINMANAGEMENT element.
+ * DomTrip implementation of poms PLUGINMANAGEMENT element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomPluginManagement extends PluginManagement {
+public class DomTripPluginManagement extends PluginManagement {
     private final Element pluginManagement;
+    private final Editor editor;
 
-    /**
-     * <p>Constructor for JDomPluginManagement.</p>
-     *
-     * @param pluginManagement a {@link org.jdom2.Element} object
-     */
-    public JDomPluginManagement(Element pluginManagement) {
+    public DomTripPluginManagement(Element pluginManagement, Editor editor) {
         this.pluginManagement = pluginManagement;
+        this.editor = editor;
     }
 
     @Override
@@ -52,20 +49,12 @@ public class JDomPluginManagement extends PluginManagement {
 
     @Override
     public List<Plugin> getPlugins() {
-        Element pluginsElm = pluginManagement.getChild("plugins", 
pluginManagement.getNamespace());
-        if (pluginsElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> pluginElms = pluginsElm.getChildren("plugin", 
pluginManagement.getNamespace());
-
-            List<Plugin> plugins = new ArrayList<>(pluginElms.size());
-
-            for (Element pluginElm : pluginElms) {
-                plugins.add(new JDomPlugin(pluginElm));
-            }
-
-            return plugins;
-        }
+        return pluginManagement
+                .childElement("plugins")
+                .map(plugins -> plugins.childElements("plugin")
+                        .map(plugin -> (Plugin) new DomTripPlugin(plugin, 
editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomProfile.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripProfile.java
similarity index 74%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomProfile.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripProfile.java
index 343f0678..5ffc5525 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomProfile.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripProfile.java
@@ -16,32 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
 import java.util.List;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.BuildBase;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.DependencyManagement;
 import org.apache.maven.model.Profile;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms PROFILE element.
+ * DomTrip implementation of poms PROFILE element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomProfile extends Profile {
-    private final JDomModelBase modelBase;
+public class DomTripProfile extends Profile {
+    private final DomTripModelBase modelBase;
 
-    /**
-     * <p>Constructor for JDomProfile.</p>
-     *
-     * @param profile a {@link org.jdom2.Element} object
-     */
-    public JDomProfile(Element profile) {
-        this.modelBase = new JDomModelBase(profile);
+    public DomTripProfile(Element profile, Editor editor) {
+        this.modelBase = new DomTripModelBase(profile, editor);
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomProperties.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripProperties.java
similarity index 77%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomProperties.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripProperties.java
index bb6f5908..b526f7ad 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomProperties.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripProperties.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -30,35 +30,33 @@ import java.util.InvalidPropertiesFormatException;
 import java.util.Properties;
 import java.util.Set;
 
-import org.jdom2.Element;
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 
 /**
- * JDOM2 implementation of poms PROPERTIES element
- * Only few methods are properly implemented as the underlying data structure 
of {@link java.util.Hashtable} is never populated.
+ * DomTrip implementation of poms PROPERTIES element.
+ * Only few methods are properly implemented as the underlying data structure 
of
+ * {@link java.util.Hashtable} is never populated.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomProperties extends Properties {
+public class DomTripProperties extends Properties {
     private final Element properties;
+    private final Editor editor;
 
-    /**
-     * <p>Constructor for JDomProperties.</p>
-     *
-     * @param properties a {@link org.jdom2.Element} object
-     */
-    public JDomProperties(Element properties) {
+    public DomTripProperties(Element properties, Editor editor) {
         this.properties = properties;
+        this.editor = editor;
     }
 
     @Override
     public synchronized Object put(Object key, Object value) {
-        Element property = properties.getChild((String) key, 
properties.getNamespace());
-
-        if (property == null) {
-            property = new Element((String) key, properties.getNamespace());
+        Element property = properties.childElement((String) key).orElse(null);
+        if (property != null) {
+            DomTripUtils.rewriteValue(editor, property, (String) value);
+        } else {
+            editor.addElement(properties, (String) key, (String) value);
         }
-        JDomUtils.rewriteValue(property, (String) value);
 
         // todo follow specs of Hashtable.put
         return null;
@@ -107,20 +105,13 @@ public class JDomProperties extends Properties {
 
     @Override
     public String getProperty(String key) {
-        Element property = properties.getChild(key, properties.getNamespace());
-
-        if (property == null) {
-            return null;
-        } else {
-            return property.getTextTrim();
-        }
+        return 
properties.childElement(key).map(Element::textContentTrimmed).orElse(null);
     }
 
     @Override
     public boolean containsKey(Object key) {
         if (key instanceof String) {
-            Element property = properties.getChild((String) key, 
properties.getNamespace());
-            return property != null;
+            return properties.childElement((String) key).isPresent();
         }
         return false;
     }
@@ -128,7 +119,6 @@ public class JDomProperties extends Properties {
     @Override
     public String getProperty(String key, String defaultValue) {
         String property = getProperty(key);
-
         return property == null ? defaultValue : property;
     }
 
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomReportPlugin.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripReportPlugin.java
similarity index 86%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomReportPlugin.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripReportPlugin.java
index da418b56..90863af4 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomReportPlugin.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripReportPlugin.java
@@ -16,32 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
 import java.util.List;
 import java.util.Map;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.ReportPlugin;
 import org.apache.maven.model.ReportSet;
 import org.apache.maven.shared.release.transform.MavenCoordinate;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms reports PLUGIN element.
+ * DomTrip implementation of poms reports PLUGIN element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomReportPlugin extends ReportPlugin implements MavenCoordinate {
+public class DomTripReportPlugin extends ReportPlugin implements 
MavenCoordinate {
     private final MavenCoordinate coordinate;
 
-    /**
-     * <p>Constructor for JDomReportPlugin.</p>
-     *
-     * @param reportPlugin a {@link org.jdom2.Element} object
-     */
-    public JDomReportPlugin(Element reportPlugin) {
-        this.coordinate = new JDomMavenCoordinate(reportPlugin);
+    public DomTripReportPlugin(Element reportPlugin, Editor editor) {
+        this.coordinate = new DomTripMavenCoordinate(reportPlugin, editor);
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomReporting.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripReporting.java
similarity index 70%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomReporting.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripReporting.java
index bef77f51..64523d00 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomReporting.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripReporting.java
@@ -16,34 +16,31 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.ReportPlugin;
 import org.apache.maven.model.Reporting;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms REPORTING element.
+ * DomTrip implementation of poms REPORTING element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomReporting extends Reporting {
+public class DomTripReporting extends Reporting {
 
     private final Element reporting;
+    private final Editor editor;
 
-    /**
-     * <p>Constructor for JDomReporting.</p>
-     *
-     * @param reporting a {@link org.jdom2.Element} object
-     */
-    public JDomReporting(Element reporting) {
+    public DomTripReporting(Element reporting, Editor editor) {
         this.reporting = reporting;
+        this.editor = editor;
     }
 
     @Override
@@ -58,20 +55,12 @@ public class JDomReporting extends Reporting {
 
     @Override
     public List<ReportPlugin> getPlugins() {
-        Element pluginsElm = reporting.getChild("plugins", 
reporting.getNamespace());
-        if (pluginsElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> pluginElms = pluginsElm.getChildren("plugin", 
reporting.getNamespace());
-
-            List<ReportPlugin> plugins = new ArrayList<>(pluginElms.size());
-
-            for (Element pluginElm : pluginElms) {
-                plugins.add(new JDomReportPlugin(pluginElm));
-            }
-
-            return plugins;
-        }
+        return reporting
+                .childElement("plugins")
+                .map(plugins -> plugins.childElements("plugin")
+                        .map(plugin -> (ReportPlugin) new 
DomTripReportPlugin(plugin, editor))
+                        .collect(Collectors.toList()))
+                .orElse(Collections.emptyList());
     }
 
     @Override
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomScm.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripScm.java
similarity index 70%
rename from 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomScm.java
rename to 
maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripScm.java
index f15fa846..82232bc9 100644
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomScm.java
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripScm.java
@@ -16,22 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.shared.release.transform.jdom2;
+package org.apache.maven.shared.release.transform.domtrip;
 
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
 import org.apache.maven.model.Scm;
-import org.jdom2.Element;
 
 /**
- * JDOM2 implementation of poms SCM element.
+ * DomTrip implementation of poms SCM element.
  *
- * @author Robert Scholte
- * @since 3.0
+ * @since 3.4
  */
-public class JDomScm extends Scm {
-    private Element scm;
+public class DomTripScm extends Scm {
+    private final Element scm;
+    private final Editor editor;
 
-    JDomScm(Element scm) {
+    DomTripScm(Element scm, Editor editor) {
         this.scm = scm;
+        this.editor = editor;
     }
 
     @Override
@@ -41,7 +43,7 @@ public class JDomScm extends Scm {
 
     @Override
     public void setConnection(String connection) {
-        JDomUtils.rewriteElement("connection", connection, scm, 
scm.getNamespace());
+        DomTripUtils.rewriteElement(editor, "connection", connection, scm);
     }
 
     @Override
@@ -51,7 +53,7 @@ public class JDomScm extends Scm {
 
     @Override
     public void setDeveloperConnection(String developerConnection) {
-        JDomUtils.rewriteElement("developerConnection", developerConnection, 
scm, scm.getNamespace());
+        DomTripUtils.rewriteElement(editor, "developerConnection", 
developerConnection, scm);
     }
 
     @Override
@@ -61,7 +63,7 @@ public class JDomScm extends Scm {
 
     @Override
     public void setTag(String tag) {
-        JDomUtils.rewriteElement("tag", tag, scm, scm.getNamespace());
+        DomTripUtils.rewriteElement(editor, "tag", tag, scm);
     }
 
     @Override
@@ -71,6 +73,6 @@ public class JDomScm extends Scm {
 
     @Override
     public void setUrl(String url) {
-        JDomUtils.rewriteElement("url", url, scm, scm.getNamespace());
+        DomTripUtils.rewriteElement(editor, "url", url, scm);
     }
 }
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripUtils.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripUtils.java
new file mode 100644
index 00000000..c5c9d28e
--- /dev/null
+++ 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/domtrip/DomTripUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.release.transform.domtrip;
+
+import java.util.Optional;
+
+import eu.maveniverse.domtrip.Editor;
+import eu.maveniverse.domtrip.Element;
+
+/**
+ * Common DomTrip functions.
+ *
+ * @since 3.4
+ */
+public final class DomTripUtils {
+
+    private DomTripUtils() {
+        // noop
+    }
+
+    /**
+     * Updates the text value of the given element. Preserves surrounding 
whitespace
+     * and CDATA sections when present.
+     *
+     * @param editor  the editor for formatting-aware modifications
+     * @param element the element to update, must not be {@code null}
+     * @param value   the text string to set, must not be {@code null}
+     */
+    public static void rewriteValue(Editor editor, Element element, String 
value) {
+        editor.setTextContent(element, value);
+    }
+
+    /**
+     * Creates, updates or removes a child element.
+     *
+     * @param editor the editor for formatting-aware modifications
+     * @param name   the child element name
+     * @param value  the text value to set, or {@code null} to remove the 
element
+     * @param root   the parent element
+     * @return the created/updated element, or {@code null} if removed
+     */
+    public static Element rewriteElement(Editor editor, String name, String 
value, Element root) {
+        Optional<Element> tagElement = root.childElement(name);
+        if (tagElement.isPresent()) {
+            if (value != null) {
+                rewriteValue(editor, tagElement.get(), value);
+                return tagElement.get();
+            } else {
+                editor.removeElement(tagElement.get());
+                return null;
+            }
+        } else {
+            if (value != null) {
+                return editor.addElement(root, name, value);
+            }
+        }
+        return null;
+    }
+}
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModel.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModel.java
deleted file mode 100644
index d5811b5f..00000000
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModel.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.maven.model.Build;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.DependencyManagement;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.Parent;
-import org.apache.maven.model.Profile;
-import org.apache.maven.model.Reporting;
-import org.apache.maven.model.Scm;
-import org.apache.maven.shared.release.config.ReleaseDescriptor;
-import org.apache.maven.shared.release.util.CiFriendlyVersion;
-import org.jdom2.Document;
-import org.jdom2.Element;
-import org.jdom2.Text;
-
-/**
- * JDOM2 implementation of poms PROJECT element.
- *
- * @author Robert Scholte
- * @since 3.0
- */
-public class JDomModel extends Model {
-    private final Element project;
-
-    private final JDomModelBase modelBase;
-
-    /**
-     * The ReleaseDescriptor after a commit performed.
-     */
-    private final ReleaseDescriptor releaseDescriptor;
-
-    /**
-     * <p>Constructor for JDomModel.</p>
-     *
-     * @param document a {@link org.jdom2.Document} object
-     */
-    public JDomModel(Document document, ReleaseDescriptor releaseDescriptor) {
-        this(document.getRootElement(), releaseDescriptor);
-    }
-
-    /**
-     * <p>Constructor for JDomModel.</p>
-     *
-     * @param project a {@link org.jdom2.Element} object
-     */
-    public JDomModel(Element project, ReleaseDescriptor releaseDescriptor) {
-        this.project = project;
-        this.releaseDescriptor = releaseDescriptor;
-        this.modelBase = new JDomModelBase(project);
-    }
-
-    @Override
-    public Build getBuild() {
-        return modelBase.getBuild();
-    }
-
-    @Override
-    public List<Dependency> getDependencies() {
-        return modelBase.getDependencies();
-    }
-
-    @Override
-    public DependencyManagement getDependencyManagement() {
-        return modelBase.getDependencyManagement();
-    }
-
-    @Override
-    public Parent getParent() {
-        Element elm = getParentElement();
-        if (elm == null) {
-            return null;
-        } else {
-            // this way scm setters change DOM tree immediately
-            return new JDomParent(elm);
-        }
-    }
-
-    private Element getParentElement() {
-        return project.getChild("parent", project.getNamespace());
-    }
-
-    @Override
-    public List<Profile> getProfiles() {
-        Element profilesElm = project.getChild("profiles", 
project.getNamespace());
-        if (profilesElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> profileElms = profilesElm.getChildren("profile", 
project.getNamespace());
-
-            List<Profile> profiles = new ArrayList<>(profileElms.size());
-
-            for (Element profileElm : profileElms) {
-                profiles.add(new JDomProfile(profileElm));
-            }
-
-            return profiles;
-        }
-    }
-
-    @Override
-    public Properties getProperties() {
-        Element properties = project.getChild("properties", 
project.getNamespace());
-
-        if (properties == null) {
-            return null;
-        } else {
-            return new JDomProperties(properties);
-        }
-    }
-
-    @Override
-    public Reporting getReporting() {
-        Element reporting = project.getChild("reporting", 
project.getNamespace());
-
-        if (reporting == null) {
-            return null;
-        } else {
-            return new JDomReporting(reporting);
-        }
-    }
-
-    @Override
-    public void setScm(Scm scm) {
-        if (scm == null) {
-            JDomUtils.rewriteElement("scm", null, project, 
project.getNamespace());
-        } else {
-            Element scmRoot = new Element("scm");
-            scmRoot.addContent("\n  ");
-
-            // Write current values to JDOM2 tree
-            Scm jdomScm = new JDomScm(scmRoot);
-            jdomScm.setConnection(scm.getConnection());
-            jdomScm.setDeveloperConnection(scm.getDeveloperConnection());
-            jdomScm.setTag(scm.getTag());
-            jdomScm.setUrl(scm.getUrl());
-
-            project.addContent("\n  ").addContent(scmRoot).addContent("\n");
-        }
-    }
-
-    @Override
-    public Scm getScm() {
-        Element elm = project.getChild("scm", project.getNamespace());
-        if (elm == null) {
-            return null;
-        } else {
-            // this way scm setters change DOM tree immediately
-            return new JDomScm(elm);
-        }
-    }
-
-    @Override
-    public void setVersion(String version) {
-        Element versionElement = project.getChild("version", 
project.getNamespace());
-
-        String parentVersion;
-        Element parent = getParentElement();
-        if (parent != null) {
-            parentVersion = parent.getChildTextTrim("version", 
project.getNamespace());
-        } else {
-            parentVersion = null;
-        }
-
-        if (versionElement == null) {
-            // never add version when parent references CI friendly property
-            if (!(parentVersion != null && 
CiFriendlyVersion.isCiFriendlyVersion(parentVersion))
-                    && !version.equals(parentVersion)) {
-                // we will add this after artifactId, since it was missing but 
different from the inherited version
-                Element artifactIdElement = project.getChild("artifactId", 
project.getNamespace());
-                int index = project.indexOf(artifactIdElement);
-
-                versionElement = new Element("version", 
project.getNamespace());
-                versionElement.setText(version);
-                project.addContent(index + 1, new Text("\n  "));
-                project.addContent(index + 2, versionElement);
-            }
-        } else {
-            if 
(CiFriendlyVersion.isCiFriendlyVersion(versionElement.getTextNormalize())) {
-                // try to rewrite property if CI friendly expression is used
-                CiFriendlyVersion.rewriteCiFriendlyProperties(version, 
getProperties(), releaseDescriptor);
-            } else {
-                JDomUtils.rewriteValue(versionElement, version);
-            }
-        }
-    }
-}
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelBase.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelBase.java
deleted file mode 100644
index 209af354..00000000
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelBase.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.maven.model.Build;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.DependencyManagement;
-import org.jdom2.Element;
-
-/**
- * <p>JDomModelBase class.</p>
- *
- * @author Robert Scholte
- * @since 3.0
- */
-public class JDomModelBase {
-    private final Element modelBase;
-
-    /**
-     * <p>Constructor for JDomModelBase.</p>
-     *
-     * @param modelBase a {@link org.jdom2.Element} object
-     */
-    public JDomModelBase(Element modelBase) {
-        this.modelBase = modelBase;
-    }
-
-    /**
-     * <p>getBuild.</p>
-     *
-     * @return a {@link org.apache.maven.model.Build} object
-     */
-    public Build getBuild() {
-        Element elm = modelBase.getChild("build", modelBase.getNamespace());
-        if (elm == null) {
-            return null;
-        } else {
-            // this way build setters change DOM tree immediately
-            return new JDomBuild(elm);
-        }
-    }
-
-    /**
-     * <p>getDependencies.</p>
-     *
-     * @return a {@link java.util.List} object
-     */
-    public List<Dependency> getDependencies() {
-        Element dependenciesElm = modelBase.getChild("dependencies", 
modelBase.getNamespace());
-        if (dependenciesElm == null) {
-            return Collections.emptyList();
-        } else {
-            List<Element> dependencyElms = 
dependenciesElm.getChildren("dependency", modelBase.getNamespace());
-
-            List<Dependency> dependencies = new 
ArrayList<>(dependencyElms.size());
-
-            for (Element dependencyElm : dependencyElms) {
-                dependencies.add(new JDomDependency(dependencyElm));
-            }
-
-            return dependencies;
-        }
-    }
-
-    /**
-     * <p>getDependencyManagement.</p>
-     *
-     * @return a {@link org.apache.maven.model.DependencyManagement} object
-     */
-    public DependencyManagement getDependencyManagement() {
-        Element elm = modelBase.getChild("dependencyManagement", 
modelBase.getNamespace());
-        if (elm == null) {
-            return null;
-        } else {
-            // this way build setters change DOM tree immediately
-            return new JDomDependencyManagement(elm);
-        }
-    }
-}
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelETL.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelETL.java
deleted file mode 100644
index 10e2a11e..00000000
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomModelETL.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Iterator;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.maven.model.Model;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.release.ReleaseExecutionException;
-import org.apache.maven.shared.release.config.ReleaseDescriptor;
-import org.apache.maven.shared.release.transform.ModelETL;
-import org.apache.maven.shared.release.util.ReleaseUtil;
-import org.codehaus.plexus.util.xml.XmlStreamWriter;
-import org.jdom2.CDATA;
-import org.jdom2.Comment;
-import org.jdom2.Document;
-import org.jdom2.Element;
-import org.jdom2.JDOMException;
-import org.jdom2.Namespace;
-import org.jdom2.filter.ContentFilter;
-import org.jdom2.filter.ElementFilter;
-import org.jdom2.input.SAXBuilder;
-import org.jdom2.output.Format;
-import org.jdom2.output.XMLOutputter;
-
-/**
- * JDOM2 implementation for extracting, transform, loading the Model (pom.xml)
- *
- * @author Robert Scholte
- * @since 3.0
- */
-public class JDomModelETL implements ModelETL {
-    private ReleaseDescriptor releaseDescriptor;
-
-    private MavenProject project;
-
-    private Document document;
-
-    private String intro = null;
-    private String outtro = null;
-
-    private String ls = ReleaseUtil.LS;
-
-    /**
-     * <p>Setter for the field <code>ls</code>.</p>
-     *
-     * @param ls a {@link java.lang.String} object
-     */
-    public void setLs(String ls) {
-        this.ls = ls;
-    }
-
-    /**
-     * <p>Setter for the field <code>releaseDescriptor</code>.</p>
-     *
-     * @param releaseDescriptor a {@link 
org.apache.maven.shared.release.config.ReleaseDescriptor} object
-     */
-    public void setReleaseDescriptor(ReleaseDescriptor releaseDescriptor) {
-        this.releaseDescriptor = releaseDescriptor;
-    }
-
-    /**
-     * <p>Setter for the field <code>project</code>.</p>
-     *
-     * @param project a {@link org.apache.maven.project.MavenProject} object
-     */
-    public void setProject(MavenProject project) {
-        this.project = project;
-    }
-
-    @Override
-    public void extract(File pomFile) throws ReleaseExecutionException {
-        try {
-            String content = ReleaseUtil.readXmlFile(pomFile, ls);
-            // we need to eliminate any extra whitespace inside elements, as 
JDOM2 will nuke it
-            content = content.replaceAll("<([^!][^>]*?)\\s{2,}([^>]*?)>", "<$1 
$2>");
-            content = content.replaceAll("(\\s{2,})/>", "$1 />");
-
-            SAXBuilder builder = new SAXBuilder();
-            document = builder.build(new StringReader(content));
-
-            // Normalize line endings to platform's style (XML processors like 
JDOM2 normalize line endings to "\n" as
-            // per section 2.11 of the XML spec)
-            normaliseLineEndings(document);
-
-            // rewrite DOM as a string to find differences, since text outside 
the root element is not tracked
-            StringWriter w = new StringWriter();
-            Format format = Format.getRawFormat();
-            format.setLineSeparator(ls);
-            XMLOutputter out = new XMLOutputter(format);
-            out.output(document.getRootElement(), w);
-
-            int index = content.indexOf(w.toString());
-            if (index >= 0) {
-                intro = content.substring(0, index);
-                outtro = content.substring(index + w.toString().length());
-            } else {
-                /*
-                 * NOTE: Due to whitespace, attribute reordering or entity 
expansion the above indexOf test can easily
-                 * fail. So let's try harder. Maybe some day, when JDOM2 
offers a StaxBuilder and this builder employes
-                 * XMLInputFactory2.P_REPORT_PROLOG_WHITESPACE, this whole 
mess can be avoided.
-                 */
-                // CHECKSTYLE_OFF: LocalFinalVariableName
-                final String SPACE = "\\s++";
-                final String XML = 
"<\\?(?:(?:[^\"'>]++)|(?:\"[^\"]*+\")|(?:'[^']*+'))*+>";
-                final String INTSUB = 
"\\[(?:(?:[^\"'\\]]++)|(?:\"[^\"]*+\")|(?:'[^']*+'))*+\\]";
-                final String DOCTYPE =
-                        
"<!DOCTYPE(?:(?:[^\"'\\[>]++)|(?:\"[^\"]*+\")|(?:'[^']*+')|(?:" + INTSUB + 
"))*+>";
-                final String PI = XML;
-                final String COMMENT = "<!--(?:[^-]|(?:-[^-]))*+-->";
-
-                final String INTRO =
-                        "(?:(?:" + SPACE + ")|(?:" + XML + ")|(?:" + DOCTYPE + 
")|(?:" + COMMENT + ")|(?:" + PI + "))*";
-                final String OUTRO = "(?:(?:" + SPACE + ")|(?:" + COMMENT + 
")|(?:" + PI + "))*";
-                final String POM = "(?s)(" + INTRO + ")(.*?)(" + OUTRO + ")";
-                // CHECKSTYLE_ON: LocalFinalVariableName
-
-                Matcher matcher = Pattern.compile(POM).matcher(content);
-                if (matcher.matches()) {
-                    intro = matcher.group(1);
-                    outtro = matcher.group(matcher.groupCount());
-                }
-            }
-        } catch (JDOMException | IOException e) {
-            throw new ReleaseExecutionException("Error reading POM: " + 
e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public void transform() {}
-
-    @Override
-    public void load(File targetFile) throws ReleaseExecutionException {
-        writePom(targetFile, document, releaseDescriptor, 
project.getModelVersion(), intro, outtro);
-    }
-
-    @Override
-    public Model getModel() {
-        return new JDomModel(document, releaseDescriptor);
-    }
-
-    private void normaliseLineEndings(Document document) {
-        for (Iterator<?> i = document.getDescendants(new 
ContentFilter(ContentFilter.COMMENT)); i.hasNext(); ) {
-            Comment c = (Comment) i.next();
-            c.setText(ReleaseUtil.normalizeLineEndings(c.getText(), ls));
-        }
-        for (Iterator<?> i = document.getDescendants(new 
ContentFilter(ContentFilter.CDATA)); i.hasNext(); ) {
-            CDATA c = (CDATA) i.next();
-            c.setText(ReleaseUtil.normalizeLineEndings(c.getText(), ls));
-        }
-    }
-
-    private void writePom(
-            File pomFile,
-            Document document,
-            ReleaseDescriptor releaseDescriptor,
-            String modelVersion,
-            String intro,
-            String outtro)
-            throws ReleaseExecutionException {
-        Element rootElement = document.getRootElement();
-
-        if (releaseDescriptor.isAddSchema()) {
-            Namespace pomNamespace = Namespace.getNamespace("", 
"http://maven.apache.org/POM/"; + modelVersion);
-            rootElement.setNamespace(pomNamespace);
-            Namespace xsiNamespace = Namespace.getNamespace("xsi", 
"http://www.w3.org/2001/XMLSchema-instance";);
-            rootElement.addNamespaceDeclaration(xsiNamespace);
-
-            if (rootElement.getAttribute("schemaLocation", xsiNamespace) == 
null) {
-                rootElement.setAttribute(
-                        "schemaLocation",
-                        "http://maven.apache.org/POM/"; + modelVersion + " 
https://maven.apache.org/xsd/maven-";
-                                + modelVersion + ".xsd",
-                        xsiNamespace);
-            }
-
-            // the empty namespace is considered equal to the POM namespace, 
so match them up to avoid extra xmlns=""
-            ElementFilter elementFilter = new 
ElementFilter(Namespace.getNamespace(""));
-            for (Iterator<?> i = rootElement.getDescendants(elementFilter); 
i.hasNext(); ) {
-                Element e = (Element) i.next();
-                e.setNamespace(pomNamespace);
-            }
-        }
-
-        try (Writer writer = new XmlStreamWriter(pomFile)) {
-            if (intro != null) {
-                writer.write(intro);
-            }
-
-            Format format = Format.getRawFormat();
-            format.setLineSeparator(ls);
-            XMLOutputter out = new XMLOutputter(format);
-            out.output(document.getRootElement(), writer);
-
-            if (outtro != null) {
-                writer.write(outtro);
-            }
-        } catch (IOException e) {
-            throw new ReleaseExecutionException("Error writing POM: " + 
e.getMessage(), e);
-        }
-    }
-}
diff --git 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomUtils.java
 
b/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomUtils.java
deleted file mode 100644
index e29b2c8c..00000000
--- 
a/maven-release-manager/src/main/java/org/apache/maven/shared/release/transform/jdom2/JDomUtils.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.util.Iterator;
-
-import org.jdom2.Element;
-import org.jdom2.Namespace;
-import org.jdom2.Text;
-
-/**
- * Common JDOM2 functions.
- *
- * @author Robert Scholte
- * @since 3.0
- */
-public final class JDomUtils {
-
-    private JDomUtils() {
-        // noop
-    }
-
-    /**
-     * Updates the text value of the given element. The primary purpose of 
this method is to preserve any whitespace and
-     * comments around the original text value.
-     *
-     * @param element the element to update, must not be <code>null</code>
-     * @param value   the text string to set, must not be <code>null</code>
-     */
-    public static void rewriteValue(Element element, String value) {
-        Text text = null;
-        if (element.getContent() != null) {
-            for (Iterator<?> it = element.getContent().iterator(); 
it.hasNext(); ) {
-                Object content = it.next();
-                if ((content instanceof Text) && ((Text) 
content).getTextTrim().length() > 0) {
-                    text = (Text) content;
-                    while (it.hasNext()) {
-                        content = it.next();
-                        if (content instanceof Text) {
-                            text.append((Text) content);
-                            it.remove();
-                        } else {
-                            break;
-                        }
-                    }
-                    break;
-                }
-            }
-        }
-        if (text == null) {
-            element.addContent(value);
-        } else {
-            String chars = text.getText();
-            String trimmed = text.getTextTrim();
-            int idx = chars.indexOf(trimmed);
-            String leadingWhitespace = chars.substring(0, idx);
-            String trailingWhitespace = chars.substring(idx + 
trimmed.length());
-            text.setText(leadingWhitespace + value + trailingWhitespace);
-        }
-    }
-
-    /**
-     * <p>rewriteElement.</p>
-     *
-     * @param name a {@link java.lang.String} object
-     * @param value a {@link java.lang.String} object
-     * @param root a {@link org.jdom2.Element} object
-     * @param namespace a {@link org.jdom2.Namespace} object
-     * @return a {@link org.jdom2.Element} object
-     */
-    public static Element rewriteElement(String name, String value, Element 
root, Namespace namespace) {
-        Element tagElement = root.getChild(name, namespace);
-        if (tagElement != null) {
-            if (value != null) {
-                rewriteValue(tagElement, value);
-            } else {
-                int index = root.indexOf(tagElement);
-                root.removeContent(index);
-                for (int i = index - 1; i >= 0; i--) {
-                    if (root.getContent(i) instanceof Text) {
-                        root.removeContent(i);
-                    } else {
-                        break;
-                    }
-                }
-            }
-        } else {
-            if (value != null) {
-                Element element = new Element(name, namespace);
-                element.setText(value);
-                root.addContent("  ").addContent(element).addContent("\n  ");
-                tagElement = element;
-            }
-        }
-        return tagElement;
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/AbstractRewritingReleasePhaseTestCase.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/AbstractRewritingReleasePhaseTestCase.java
index efa316db..cd66471c 100644
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/AbstractRewritingReleasePhaseTestCase.java
+++ 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/AbstractRewritingReleasePhaseTestCase.java
@@ -33,7 +33,7 @@ import 
org.apache.maven.shared.release.config.ReleaseDescriptorBuilder;
 import org.apache.maven.shared.release.config.ReleaseUtils;
 import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
 import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
-import org.apache.maven.shared.release.transform.jdom2.JDomModelETLFactory;
+import 
org.apache.maven.shared.release.transform.domtrip.DomTripModelETLFactory;
 import org.apache.maven.shared.release.util.ReleaseUtil;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
@@ -58,7 +58,7 @@ abstract class AbstractRewritingReleasePhaseTestCase extends 
AbstractReleaseTest
     @BeforeEach
     public void setUpAbstractRewritingReleasePhaseTestCase() throws Exception {
         if (getTestedPhase() instanceof AbstractRewritePomsPhase) {
-            ((AbstractRewritePomsPhase) 
getTestedPhase()).setModelETL(JDomModelETLFactory.NAME);
+            ((AbstractRewritePomsPhase) 
getTestedPhase()).setModelETL(DomTripModelETLFactory.NAME);
             ((AbstractRewritePomsPhase) getTestedPhase()).setStartTime(0);
         }
     }
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomBuildTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomBuildTest.java
deleted file mode 100644
index b8255d12..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomBuildTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.StringReader;
-
-import org.jdom2.Document;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class JDomBuildTest {
-    private SAXBuilder builder = new SAXBuilder();
-
-    @Test
-    void testGetExtensions() throws Exception {
-        String content = "<build></build>";
-        Document document = builder.build(new StringReader(content));
-        assertNotNull(new 
JDomBuild(document.getRootElement()).getExtensions());
-        assertEquals(0, new 
JDomBuild(document.getRootElement()).getExtensions().size());
-
-        content = "<build><extensions/></build>";
-        document = builder.build(new StringReader(content));
-        assertEquals(0, new 
JDomBuild(document.getRootElement()).getExtensions().size());
-
-        content = "<build><extensions><extension/></extensions></build>";
-        document = builder.build(new StringReader(content));
-        assertEquals(1, new 
JDomBuild(document.getRootElement()).getExtensions().size());
-    }
-
-    @Test
-    void testGetPluginManagement() throws Exception {
-        String content = "<build></build>";
-        Document document = builder.build(new StringReader(content));
-        assertNull(new 
JDomBuild(document.getRootElement()).getPluginManagement());
-
-        content = "<build><pluginManagement/></build>";
-        document = builder.build(new StringReader(content));
-        assertNotNull(new 
JDomBuild(document.getRootElement()).getPluginManagement());
-    }
-
-    @Test
-    void testGetPlugins() throws Exception {
-        String content = "<build></build>";
-        Document document = builder.build(new StringReader(content));
-        assertNotNull(new JDomBuild(document.getRootElement()).getPlugins());
-        assertEquals(0, new 
JDomBuild(document.getRootElement()).getPlugins().size());
-
-        content = "<build><plugins/></build>";
-        document = builder.build(new StringReader(content));
-        assertEquals(0, new 
JDomBuild(document.getRootElement()).getPlugins().size());
-
-        content = "<build><plugins><plugin/></plugins></build>";
-        document = builder.build(new StringReader(content));
-        assertEquals(1, new 
JDomBuild(document.getRootElement()).getPlugins().size());
-    }
-
-    // All other methods throw UnsupportedOperationException
-
-    @Test
-    void testFlushPluginMap() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).flushPluginMap());
-    }
-
-    @Test
-    void testAddExtension() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).addExtension(null));
-    }
-
-    @Test
-    void testGetOutputDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getOutputDirectory());
-    }
-
-    @Test
-    void testGetScriptSourceDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getScriptSourceDirectory());
-    }
-
-    @Test
-    void testGetSourceDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getSourceDirectory());
-    }
-
-    @Test
-    void testGetTestOutputDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getTestOutputDirectory());
-    }
-
-    @Test
-    void testGetTestSourceDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getTestSourceDirectory());
-    }
-
-    @Test
-    void testRemoveExtension() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).removeExtension(null));
-    }
-
-    @Test
-    void testSetExtensions() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setExtensions(null));
-    }
-
-    @Test
-    void testSetOutputDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setOutputDirectory(null));
-    }
-
-    @Test
-    void testSetScriptSourceDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setScriptSourceDirectory(null));
-    }
-
-    @Test
-    void testSetSourceDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setSourceDirectory(null));
-    }
-
-    @Test
-    void testSetTestOutputDirectoryString() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setTestOutputDirectory(null));
-    }
-
-    @Test
-    void testSetTestSourceDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setTestSourceDirectory(null));
-    }
-
-    @Test
-    void testAddFilter() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).addFilter(null));
-    }
-
-    @Test
-    void testAddResource() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).addResource(null));
-    }
-
-    @Test
-    void testAddTestResource() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).addTestResource(null));
-    }
-
-    @Test
-    void testGetDefaultGoal() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getDefaultGoal());
-    }
-
-    @Test
-    void testGetDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getDirectory());
-    }
-
-    @Test
-    void testGetFilters() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getFilters());
-    }
-
-    @Test
-    void testGetFinalName() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getFinalName());
-    }
-
-    @Test
-    void testGetResources() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getResources());
-    }
-
-    @Test
-    void testGetTestResources() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getTestResources());
-    }
-
-    @Test
-    void testRemoveFilter() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).removeFilter(null));
-    }
-
-    @Test
-    void testRemoveResource() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).removeResource(null));
-    }
-
-    @Test
-    void testRemoveTestResource() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).removeTestResource(null));
-    }
-
-    @Test
-    void testSetDefaultGoal() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setDefaultGoal(null));
-    }
-
-    @Test
-    void testSetDirectory() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setDirectory(null));
-    }
-
-    @Test
-    void testSetFilters() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setFilters(null));
-    }
-
-    @Test
-    void testSetFinalName() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setFinalName(null));
-    }
-
-    @Test
-    void testSetResources() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setResources(null));
-    }
-
-    @Test
-    void testSetTestResources() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setTestResources(null));
-    }
-
-    @Test
-    void testSetPluginManagement() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setPluginManagement(null));
-    }
-
-    @Test
-    void testAddPlugin() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).addPlugin(null));
-    }
-
-    @Test
-    void testRemovePlugin() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).removePlugin(null));
-    }
-
-    @Test
-    void testSetPlugins() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).setPlugins(null));
-    }
-
-    @Test
-    void testGetPluginsAsMap() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomBuild(null).getPluginsAsMap());
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyManagementTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyManagementTest.java
deleted file mode 100644
index b5c101bc..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyManagementTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.StringReader;
-
-import org.jdom2.Document;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class JDomDependencyManagementTest {
-    private SAXBuilder builder = new SAXBuilder();
-
-    @Test
-    void testGetDependencies() throws Exception {
-        String content = "<dependencyManamgement></dependencyManamgement>";
-        Document document = builder.build(new StringReader(content));
-        assertNotNull(new 
JDomDependencyManagement(document.getRootElement()).getDependencies());
-        assertEquals(
-                0,
-                new JDomDependencyManagement(document.getRootElement())
-                        .getDependencies()
-                        .size());
-
-        content = 
"<dependencyManamgement><dependencies/></dependencyManamgement>";
-        document = builder.build(new StringReader(content));
-        assertEquals(
-                0,
-                new JDomDependencyManagement(document.getRootElement())
-                        .getDependencies()
-                        .size());
-
-        content = 
"<dependencyManamgement><dependencies><dependency/></dependencies></dependencyManamgement>";
-        document = builder.build(new StringReader(content));
-        assertEquals(
-                1,
-                new JDomDependencyManagement(document.getRootElement())
-                        .getDependencies()
-                        .size());
-    }
-
-    // All other methods throw UnsupportedOperationException
-
-    @Test
-    void testAddDependency() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependencyManagement(null).addDependency(null));
-    }
-
-    @Test
-    void testRemoveDependency() {
-        assertThrows(
-                UnsupportedOperationException.class, () -> new 
JDomDependencyManagement(null).removeDependency(null));
-    }
-
-    @Test
-    void testSetDependenciesListOfDependency() {
-        assertThrows(
-                UnsupportedOperationException.class, () -> new 
JDomDependencyManagement(null).setDependencies(null));
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyTest.java
deleted file mode 100644
index 008744a6..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomDependencyTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.StringReader;
-
-import org.jdom2.Element;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class JDomDependencyTest {
-    private SAXBuilder builder = new SAXBuilder();
-
-    @Test
-    void testIsOptional() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).isOptional());
-    }
-
-    @Test
-    void testSetOptional() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setOptional(true));
-    }
-
-    @Test
-    void testAddExclusion() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).addExclusion(null));
-    }
-
-    @Test
-    void testGetArtifactId() throws Exception {
-        String content = "<dependency></dependency>";
-        Element dependencyElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomDependency(dependencyElm).getArtifactId());
-        content = 
"<dependency><artifactId>ARTIFACTID</artifactId></dependency>";
-        dependencyElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("ARTIFACTID", new 
JDomDependency(dependencyElm).getArtifactId());
-    }
-
-    @Test
-    void testGetClassifier() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).getClassifier());
-    }
-
-    @Test
-    void testGetExclusions() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).getExclusions());
-    }
-
-    @Test
-    void testGetGroupId() throws Exception {
-        String content = "<dependency></dependency>";
-        Element dependencyElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomDependency(dependencyElm).getGroupId());
-        content = "<dependency><groupId>GROUPID</groupId></dependency>";
-        dependencyElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("GROUPID", new 
JDomDependency(dependencyElm).getGroupId());
-    }
-
-    @Test
-    void testGetScope() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).getScope());
-    }
-
-    @Test
-    void testGetSystemPath() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).getSystemPath());
-    }
-
-    @Test
-    void testGetType() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).getType());
-    }
-
-    @Test
-    void testGetVersion() throws Exception {
-        String content = "<dependency></dependency>";
-        Element dependencyElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomDependency(dependencyElm).getVersion());
-        content = "<dependency><version>VERSION</version></dependency>";
-        dependencyElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("VERSION", new 
JDomDependency(dependencyElm).getVersion());
-    }
-
-    @Test
-    void testRemoveExclusion() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).removeExclusion(null));
-    }
-
-    @Test
-    void testSetArtifactIdString() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setArtifactId(null));
-    }
-
-    @Test
-    void testSetClassifierString() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setClassifier(null));
-    }
-
-    @Test
-    void testSetExclusions() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setExclusions(null));
-    }
-
-    @Test
-    void testSetGroupIdString() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setGroupId(null));
-    }
-
-    @Test
-    void testSetScopeString() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setScope(null));
-    }
-
-    @Test
-    void testSetSystemPathString() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setSystemPath(null));
-    }
-
-    @Test
-    void testSetTypeString() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomDependency(null).setType(null));
-    }
-
-    @Test
-    void testSetVersionString() throws Exception {
-        String content = 
"<dependency><version>OLD_VERSION</version></dependency>";
-        Element dependencyElm = builder.build(new 
StringReader(content)).getRootElement();
-        new JDomDependency(dependencyElm).setVersion("NEW_VERSION");
-        assertEquals("NEW_VERSION", getVersion(dependencyElm));
-    }
-
-    @Test
-    void testGetName() {
-        assertEquals("dependency", new JDomDependency(null).getName());
-    }
-
-    private String getVersion(Element dependencyElm) {
-        return dependencyElm.getChildTextTrim("version", 
dependencyElm.getNamespace());
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomExtensionTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomExtensionTest.java
deleted file mode 100644
index c3db301f..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomExtensionTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.StringReader;
-
-import org.jdom2.Element;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.AssertionsKt.assertNull;
-
-class JDomExtensionTest {
-    private SAXBuilder builder = new SAXBuilder();
-
-    @Test
-    void testGetArtifactId() throws Exception {
-        String content = "<extension></extension>";
-        Element extensionElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomExtension(extensionElm).getArtifactId());
-
-        content = "<extension><artifactId>ARTIFACTID</artifactId></extension>";
-        extensionElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("ARTIFACTID", new 
JDomExtension(extensionElm).getArtifactId());
-    }
-
-    @Test
-    void testGetGroupId() throws Exception {
-        String content = "<extension></extension>";
-        Element extensionElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomExtension(extensionElm).getGroupId());
-
-        content = "<extension><groupId>GROUPID</groupId></extension>";
-        extensionElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("GROUPID", new JDomExtension(extensionElm).getGroupId());
-    }
-
-    @Test
-    void testGetVersion() throws Exception {
-        String content = "<extension></extension>";
-        Element extensionElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomExtension(extensionElm).getVersion());
-
-        content = "<extension><version>VERSION</version></extension>";
-        extensionElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("VERSION", new JDomExtension(extensionElm).getVersion());
-    }
-
-    @Test
-    void testSetArtifactId() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomExtension(null).setArtifactId(null));
-    }
-
-    @Test
-    void testSetGroupId() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomExtension(null).setGroupId(null));
-    }
-
-    @Test
-    void testSetVersion() throws Exception {
-        String content = 
"<extension><version>OLD_VERSION</version></extension>";
-        Element extensionElm = builder.build(new 
StringReader(content)).getRootElement();
-        new JDomExtension(extensionElm).setVersion("NEW_VERSION");
-        assertEquals("NEW_VERSION", getVersion(extensionElm));
-    }
-
-    @Test
-    void testGetName() {
-        assertEquals("extension", new JDomExtension(null).getName());
-    }
-
-    private String getVersion(Element extensionElm) {
-        return extensionElm.getChildTextTrim("version", 
extensionElm.getNamespace());
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomModelTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomModelTest.java
deleted file mode 100644
index 242008de..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomModelTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.StringReader;
-
-import org.apache.maven.model.Model;
-import org.apache.maven.model.Scm;
-import org.apache.maven.shared.release.config.ReleaseDescriptor;
-import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder;
-import org.jdom2.Document;
-import org.jdom2.Element;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-
-class JDomModelTest {
-    private SAXBuilder builder = new SAXBuilder();
-    private ReleaseDescriptor releaseDescriptor = new 
ReleaseDescriptorBuilder().build();
-
-    @Test
-    void testGetScm() throws Exception {
-        String content = "<project></project>";
-        Document document = builder.build(new StringReader(content));
-        assertNull(new JDomModel(document, releaseDescriptor).getScm());
-    }
-
-    @Test
-    void testSetScm() throws Exception {
-        String content = "<project></project>";
-        Document document = builder.build(new StringReader(content));
-        Model model = new JDomModel(document, releaseDescriptor);
-        assertNull(model.getScm());
-
-        model.setScm(new Scm());
-        assertNotNull(model.getScm());
-
-        model.setScm(null);
-        assertNull(model.getScm());
-    }
-
-    @Test
-    void testSetVersion() throws Exception {
-        String content = "<project></project>";
-        Element projectElm = builder.build(new 
StringReader(content)).getRootElement();
-        Model model = new JDomModel(projectElm, releaseDescriptor);
-        assertNull(model.getVersion());
-
-        model.setVersion("VERSION");
-        assertEquals("VERSION", getVersion(projectElm));
-
-        model.setVersion(null);
-        assertNull(model.getVersion());
-
-        // inherit from parent via CI friendly
-        content = 
"<project><parent><version>${revision}${changelist}</version></parent></project>";
-        projectElm = builder.build(new StringReader(content)).getRootElement();
-        model = new JDomModel(projectElm, releaseDescriptor);
-        assertNull(model.getVersion());
-        model.setVersion("PARENT_VERSION");
-        assertNull(getVersion(projectElm));
-
-        // this business logic might need to moved.
-        content = 
"<project><parent><version>PARENT_VERSION</version></parent></project>";
-        projectElm = builder.build(new StringReader(content)).getRootElement();
-        model = new JDomModel(projectElm, releaseDescriptor);
-        assertNull(model.getVersion());
-
-        model.setVersion("PARENT_VERSION");
-        assertNull(getVersion(projectElm));
-
-        model.setVersion("VERSION");
-        assertEquals("VERSION", getVersion(projectElm));
-
-        model.setVersion(null);
-        assertNull(model.getVersion());
-    }
-
-    private String getVersion(Element projectElm) {
-        return projectElm.getChildText("version", projectElm.getNamespace());
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomParentTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomParentTest.java
deleted file mode 100644
index 856ff848..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomParentTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.StringReader;
-
-import org.jdom2.Element;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class JDomParentTest {
-    private SAXBuilder builder = new SAXBuilder();
-
-    @Test
-    void testGetArtifactId() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomParent(null).getArtifactId());
-    }
-
-    @Test
-    void testGetGroupId() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomParent(null).getGroupId());
-    }
-
-    @Test
-    void testGetRelativePath() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomParent(null).getRelativePath());
-    }
-
-    @Test
-    void testGetVersion() throws Exception {
-        String content = "<parent><version>1.0</version></parent>";
-        Element parentElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("1.0", new JDomParent(parentElm).getVersion());
-    }
-
-    @Test
-    void testSetArtifactId() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomParent(null).setArtifactId(null));
-    }
-
-    @Test
-    void testSetGroupId() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomParent(null).setGroupId(null));
-    }
-
-    @Test
-    void testSetRelativePath() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomParent(null).setRelativePath(null));
-    }
-
-    @Test
-    void testSetVersionString() throws Exception {
-        String content = "<parent></parent>";
-        Element parentElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(getVersion(parentElm));
-        new JDomParent(parentElm).setVersion("VERSION");
-        assertEquals("VERSION", getVersion(parentElm));
-        new JDomParent(parentElm).setVersion(null);
-        assertNull(getVersion(parentElm));
-    }
-
-    @Test
-    void testGetId() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomParent(null).getId());
-    }
-
-    private String getVersion(Element parentElm) {
-        return parentElm.getChildText("version", parentElm.getNamespace());
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomPropertiesTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomPropertiesTest.java
deleted file mode 100644
index 6e379210..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomPropertiesTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.Writer;
-
-import org.jdom2.Element;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class JDomPropertiesTest {
-    private SAXBuilder builder = new SAXBuilder();
-
-    @Test
-    void testSetProperty() throws Exception {
-        String content = "<properties></properties>";
-        Element propertiesElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(getProperty(propertiesElm, "KEY"));
-
-        // Adding not allowed, prepare properties
-        content = "<properties><KEY>OLD_VALUE</KEY></properties>";
-        propertiesElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("OLD_VALUE", getProperty(propertiesElm, "KEY"));
-        new JDomProperties(propertiesElm).setProperty("KEY", "NEW_VALUE");
-        assertEquals("NEW_VALUE", getProperty(propertiesElm, "KEY"));
-    }
-
-    @Test
-    void testLoadReader() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).load((Reader) null));
-    }
-
-    @Test
-    void testLoadInputStream() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).load((InputStream) null));
-    }
-
-    @Test
-    void testSave() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).save(null, null));
-    }
-
-    @Test
-    void testStoreWriter() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).store((Writer) null, null));
-    }
-
-    @Test
-    void testStoreOutputStream() {
-        assertThrows(
-                UnsupportedOperationException.class, () -> new 
JDomProperties(null).store((OutputStream) null, null));
-    }
-
-    @Test
-    void testLoadFromXML() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).loadFromXML(null));
-    }
-
-    @Test
-    void testStoreToXML() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).storeToXML(null, null));
-    }
-
-    @Test
-    void testStoreToXMLEncoded() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null)
-                .storeToXML(null, null, (String) null));
-    }
-
-    @Test
-    void testGetProperty() throws Exception {
-        String content = "<properties></properties>";
-        Element propertiesElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomProperties(propertiesElm).getProperty("KEY"));
-
-        content = "<properties><KEY>VALUE</KEY></properties>";
-        propertiesElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertEquals("VALUE", new 
JDomProperties(propertiesElm).getProperty("KEY"));
-    }
-
-    @Test
-    void testGetPropertyDefault() throws Exception {
-        String content = "<properties></properties>";
-        Element propertiesElm = builder.build(new 
StringReader(content)).getRootElement();
-        assertNull(new JDomProperties(propertiesElm).getProperty("KEY", null));
-        assertEquals("", new JDomProperties(propertiesElm).getProperty("KEY", 
""));
-    }
-
-    @Test
-    void testPropertyNames() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).propertyNames());
-    }
-
-    @Test
-    void testStringPropertyNames() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).stringPropertyNames());
-    }
-
-    @Test
-    void testListPrintStream() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).list((PrintStream) null));
-    }
-
-    @Test
-    void testListPrintWriter() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomProperties(null).list((PrintWriter) null));
-    }
-
-    private String getProperty(Element propertiesElm, String key) {
-        return propertiesElm.getChildText(key, propertiesElm.getNamespace());
-    }
-}
diff --git 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomScmTest.java
 
b/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomScmTest.java
deleted file mode 100644
index e6a94530..00000000
--- 
a/maven-release-manager/src/test/java/org/apache/maven/shared/release/transform/jdom2/JDomScmTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.shared.release.transform.jdom2;
-
-import java.io.StringReader;
-
-import org.jdom2.Element;
-import org.jdom2.input.SAXBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class JDomScmTest {
-    private SAXBuilder builder = new SAXBuilder();
-
-    @Test
-    void testGetConnection() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomScm(null).getConnection());
-    }
-
-    @Test
-    void testGetDeveloperConnection() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomScm(null).getDeveloperConnection());
-    }
-
-    @Test
-    void testGetTag() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomScm(null).getTag());
-    }
-
-    @Test
-    void testGetUrl() {
-        assertThrows(UnsupportedOperationException.class, () -> new 
JDomScm(null).getUrl());
-    }
-
-    @Test
-    void testSetConnectionString() throws Exception {
-        String content = "<scm></scm>";
-        Element scmElm = builder.build(new 
StringReader(content)).getRootElement();
-
-        assertNull(getConnection(scmElm));
-
-        new JDomScm(scmElm).setConnection("CONNECTION");
-        assertEquals("CONNECTION", getConnection(scmElm));
-
-        new JDomScm(scmElm).setConnection(null);
-        assertNull(getConnection(scmElm));
-    }
-
-    @Test
-    void testSetDeveloperConnectionString() throws Exception {
-        String content = "<scm></scm>";
-        Element scmElm = builder.build(new 
StringReader(content)).getRootElement();
-
-        assertNull(getDeveloperConnection(scmElm));
-
-        new JDomScm(scmElm).setDeveloperConnection("DEVELOPERCONNECTION");
-        assertEquals("DEVELOPERCONNECTION", getDeveloperConnection(scmElm));
-
-        new JDomScm(scmElm).setDeveloperConnection(null);
-        assertNull(getDeveloperConnection(scmElm));
-    }
-
-    @Test
-    void testSetTagString() throws Exception {
-        String content = "<scm></scm>";
-        Element scmElm = builder.build(new 
StringReader(content)).getRootElement();
-
-        assertNull(getUrl(scmElm));
-
-        new JDomScm(scmElm).setUrl("URL");
-        assertEquals("URL", getUrl(scmElm));
-
-        new JDomScm(scmElm).setUrl(null);
-        assertNull(getUrl(scmElm));
-    }
-
-    @Test
-    void testSetUrlString() throws Exception {
-        String content = "<scm></scm>";
-        Element scmElm = builder.build(new 
StringReader(content)).getRootElement();
-
-        assertNull(getTag(scmElm));
-
-        new JDomScm(scmElm).setTag("TAG");
-        assertEquals("TAG", getTag(scmElm));
-
-        new JDomScm(scmElm).setTag(null);
-        assertNull(getTag(scmElm));
-    }
-
-    private String getConnection(Element scmElm) {
-        return scmElm.getChildText("connection", scmElm.getNamespace());
-    }
-
-    private String getDeveloperConnection(Element scmElm) {
-        return scmElm.getChildText("developerConnection", 
scmElm.getNamespace());
-    }
-
-    private String getTag(Element scmElm) {
-        return scmElm.getChildText("tag", scmElm.getNamespace());
-    }
-
-    private String getUrl(Element scmElm) {
-        return scmElm.getChildText("url", scmElm.getNamespace());
-    }
-}
diff --git a/pom.xml b/pom.xml
index c5f46271..4e8532c9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -263,9 +263,9 @@ under the License.
       </dependency>
 
       <dependency>
-        <groupId>org.jdom</groupId>
-        <artifactId>jdom2</artifactId>
-        <version>2.0.6.1</version>
+        <groupId>eu.maveniverse.maven.domtrip</groupId>
+        <artifactId>domtrip-core</artifactId>
+        <version>1.0.0</version>
       </dependency>
       <dependency>
         <groupId>org.mockito</groupId>

Reply via email to