Index: /trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 15882)
+++ /trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 15883)
@@ -480,4 +480,12 @@
     public void actionPerformed(ActionEvent e) {
         join(getLayerManager().getEditDataSet().getSelectedWays());
+        clearFields();
+    }
+
+    private void clearFields() {
+        ds = null;
+        cmdsCount = 0;
+        cmds.clear();
+        addedRelations.clear();
     }
 
@@ -488,6 +496,5 @@
      */
     public void join(Collection<Way> ways) {
-        cmdsCount = 0;
-        addedRelations.clear();
+        clearFields();
 
         if (ways.isEmpty()) {
@@ -675,6 +682,21 @@
         List<WayInPolygon> preparedWays = new ArrayList<>();
 
+        // maps oldest way referring to start of each part
+        Map<Node, Way> oldestWayMap = new HashMap<>();
+
         for (Way way : outerStartingWays) {
             List<Way> splitWays = splitWayOnNodes(way, nodes);
+
+            // see #9599
+            if (!way.isNew() && splitWays.size() > 1) {
+                for (Way part : splitWays) {
+                    Node n = part.firstNode();
+                    Way old = oldestWayMap.get(n);
+                    if (old == null || old.getUniqueId() > way.getUniqueId()) {
+                        oldestWayMap.put(n, way);
+                    }
+                }
+            }
+
             preparedWays.addAll(markWayInsideSide(splitWays, false));
         }
@@ -721,4 +743,25 @@
 
         commitCommands(marktr("Delete relations"));
+
+        // see #9599: result should contain original way(s) where possible
+        if (discardedWays.stream().anyMatch(w -> !w.isNew())) {
+            for (int i = 0; i < polygons.size(); i++) {
+                Multipolygon mp = polygons.get(i);
+                for (int k = 0; k < mp.getInnerWays().size(); k++) {
+                    Way inner = mp.getInnerWays().get(k);
+                    Way older = keepOlder(inner, oldestWayMap, discardedWays);
+                    if (inner != older) {
+                        mp.getInnerWays().set(k, older);
+                    }
+                }
+                Way older = keepOlder(mp.outerWay, oldestWayMap, discardedWays);
+                if (older != mp.outerWay) {
+                    Multipolygon mpNew = new Multipolygon(older);
+                    mpNew.innerWays.addAll(mp.getInnerWays());
+                    polygons.set(i, mpNew);
+                }
+            }
+            commitCommands(marktr("Keep older versions"));
+        }
 
         // Delete the discarded inner ways
@@ -740,4 +783,31 @@
 
         return new JoinAreasResult(true, polygons);
+    }
+
+    /**
+     * Create copy of given way using an older id so that we don't create a new way instead of a modified old one.
+     * @param way the way to check
+     * @param oldestWayMap  nodes from old ways
+     * @param discardedWays collection of ways which will be deleted (modified)
+     * @return a copy of the way with an older id or the way itself
+     */
+    private Way keepOlder(Way way, Map<Node, Way> oldestWayMap, List<Way> discardedWays) {
+        Way oldest = null;
+        for (Node n : way.getNodes()) {
+            Way orig = oldestWayMap .get(n);
+            if (orig != null && (oldest == null || oldest.getUniqueId() > orig.getUniqueId())
+                    && discardedWays.contains(orig)) {
+                oldest = orig;
+            }
+        }
+        if (oldest != null) {
+            discardedWays.remove(oldest);
+            discardedWays.add(way);
+            Way copy = new Way(oldest);
+            copy.setNodes(way.getNodes());
+            cmds.add(new ChangeCommand(oldest, copy));
+            return copy;
+        }
+        return way;
     }
 
@@ -1056,5 +1126,5 @@
      * @param way way to split
      * @param nodes split points
-     * @return list of split ways (or original ways if no splitting is done).
+     * @return list of split ways (or original way if no splitting is done).
      */
     private List<Way> splitWayOnNodes(Way way, Set<Node> nodes) {
@@ -1373,7 +1443,12 @@
         //TODO: ReverseWay and Combine way are really slow and we use them a lot here. This slows down large joins.
         List<Way> actionWays = new ArrayList<>(ways.size());
-
+        int oldestPos = 0;
+        Way oldest = ways.get(0).way;
         for (WayInPolygon way : ways) {
             actionWays.add(way.way);
+            if (oldest.isNew() || !way.way.isNew() && oldest.getUniqueId() > way.way.getUniqueId()) {
+                oldest = way.way;
+                oldestPos = actionWays.size() - 1;
+            }
 
             if (!way.insideToTheRight) {
@@ -1383,4 +1458,7 @@
             }
         }
+
+        // see #9599: Help CombineWayAction to use the oldest way
+        Collections.rotate(actionWays, actionWays.size() - oldestPos);
 
         Pair<Way, Command> result = CombineWayAction.combineWaysWorker(actionWays);
Index: /trunk/test/data/regress/9599/ex5.osm
===================================================================
--- /trunk/test/data/regress/9599/ex5.osm	(revision 15883)
+++ /trunk/test/data/regress/9599/ex5.osm	(revision 15883)
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version='0.6' upload='true' generator='JOSM'>
+  <bounds minlat='43.3280894' minlon='6.5462664' maxlat='43.3282713' maxlon='6.5464564' origin='CGImap 0.3.1 (29703 thorn-02.openstreetmap.org)' />
+  <node id='2632536012' timestamp='2014-01-22T17:11:29Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.3281651' lon='6.546396' />
+  <node id='2632536021' timestamp='2014-01-22T17:11:30Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.3281697' lon='6.5463519' />
+  <node id='2632536045' timestamp='2014-01-22T17:11:30Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.3281937' lon='6.5463563' />
+  <node id='2632536051' timestamp='2014-01-22T17:11:30Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.3281998' lon='6.5462943' />
+  <node id='2632536055' timestamp='2014-01-22T17:11:30Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.3282134' lon='6.5464038' />
+  <node id='2632536063' timestamp='2014-01-22T17:11:31Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.3282302' lon='6.5464066' />
+  <node id='2632536064' timestamp='2014-01-22T17:11:31Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.328232' lon='6.5463556' />
+  <node id='2632536067' timestamp='2014-01-22T17:11:31Z' uid='875219' user='Maxime DIVO' visible='true' version='1' changeset='20145216' lat='43.328234' lon='6.5463002' />
+  <way id='257786939' timestamp='2014-01-23T06:39:25Z' uid='870861' user='botdidier2020' visible='true' version='2' changeset='20154690'>
+    <nd ref='2632536064' />
+    <nd ref='2632536055' />
+    <nd ref='2632536063' />
+    <nd ref='2632536064' />
+    <tag k='building' v='yes' />
+    <tag k='source' v='cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre. Mise à jour : 2013' />
+  </way>
+  <way id='257789043' timestamp='2014-01-23T06:44:02Z' uid='870861' user='botdidier2020' visible='true' version='2' changeset='20154690'>
+    <nd ref='2632536055' />
+    <nd ref='2632536064' />
+    <nd ref='2632536067' />
+    <nd ref='2632536051' />
+    <nd ref='2632536045' />
+    <nd ref='2632536021' />
+    <nd ref='2632536012' />
+    <nd ref='2632536055' />
+    <tag k='building' v='yes' />
+    <tag k='source' v='cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre. Mise à jour : 2013' />
+  </way>
+</osm>
Index: /trunk/test/data/regress/9599/three_old.osm
===================================================================
--- /trunk/test/data/regress/9599/three_old.osm	(revision 15883)
+++ /trunk/test/data/regress/9599/three_old.osm	(revision 15883)
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version='0.6' upload='never' generator='JOSM'>
+  <node id='353225239' timestamp='2009-02-27T13:45:58Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8972935' lon='8.4027792' />
+  <node id='353225241' timestamp='2009-02-27T13:45:58Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8972734' lon='8.402951' />
+  <node id='353225244' timestamp='2009-02-27T13:45:58Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8972311' lon='8.4027592' />
+  <node id='353225247' timestamp='2009-02-27T13:45:58Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.897211' lon='8.402931' />
+  <node id='353225249' timestamp='2009-02-27T13:45:58Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8972161' lon='8.4028895' />
+  <node id='353225252' timestamp='2009-02-27T13:45:58Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971916' lon='8.4027464' />
+  <node id='353225257' timestamp='2009-02-27T13:45:58Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971763' lon='8.4028767' />
+  <node id='353225260' timestamp='2009-02-27T13:45:59Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971682' lon='8.4028638' />
+  <node id='353225263' timestamp='2009-02-27T13:45:59Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971543' lon='8.4029921' />
+  <node id='353225267' timestamp='2009-02-27T13:45:59Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971322' lon='8.4028531' />
+  <node id='353225269' timestamp='2009-02-27T13:45:59Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971182' lon='8.4029813' />
+  <node id='353225273' timestamp='2009-02-27T13:45:59Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971772' lon='8.4028662' />
+  <node id='353225277' timestamp='2009-02-27T13:45:59Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159' lat='52.8971669' lon='8.4028741' />
+  <way id='31567319' timestamp='2009-02-27T13:46:00Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159'>
+    <nd ref='353225239' />
+    <nd ref='353225244' />
+    <nd ref='353225252' />
+    <nd ref='353225273' />
+    <nd ref='353225257' />
+    <nd ref='353225249' />
+    <nd ref='353225247' />
+    <nd ref='353225241' />
+    <nd ref='353225239' />
+    <tag k='building' v='yes' />
+  </way>
+  <way id='31567320' timestamp='2009-02-27T13:46:00Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159'>
+    <nd ref='353225260' />
+    <nd ref='353225267' />
+    <nd ref='353225269' />
+    <nd ref='353225263' />
+    <nd ref='353225277' />
+    <nd ref='353225260' />
+    <tag k='building' v='yes' />
+  </way>
+  <way id='31567321' timestamp='2009-02-27T13:46:00Z' uid='64197' user='Lothar Schiborr_1' visible='true' version='1' changeset='684159'>
+    <nd ref='353225260' />
+    <nd ref='353225273' />
+    <nd ref='353225257' />
+    <nd ref='353225277' />
+    <nd ref='353225260' />
+    <tag k='building' v='yes' />
+  </way>
+</osm>
Index: /trunk/test/unit/org/openstreetmap/josm/actions/JoinAreasActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/actions/JoinAreasActionTest.java	(revision 15882)
+++ /trunk/test/unit/org/openstreetmap/josm/actions/JoinAreasActionTest.java	(revision 15883)
@@ -52,4 +52,50 @@
 
     /**
+     * Non-regression test for bug #9599.
+     * @throws IOException if any I/O error occurs
+     * @throws IllegalDataException if OSM parsing fails
+     */
+    @Test
+    public void testTicket9599() throws IOException, IllegalDataException {
+        try (InputStream is = TestUtils.getRegressionDataStream(9599, "ex5.osm")) {
+            DataSet ds = OsmReader.parseDataSet(is, null);
+            Layer layer = new OsmDataLayer(ds, null, null);
+            MainApplication.getLayerManager().addLayer(layer);
+            try {
+                new JoinAreasAction(false).join(ds.getWays());
+                Collection<IPrimitive> found = SearchAction.searchAndReturn("type:way", SearchMode.replace);
+                assertEquals(1, found.size());
+                assertEquals(257786939, found.iterator().next().getUniqueId());
+            } finally {
+                // Ensure we clean the place before leaving, even if test fails.
+                MainApplication.getLayerManager().removeLayer(layer);
+            }
+        }
+    }
+
+    /**
+     * Non-regression test for bug #9599.
+     * @throws IOException if any I/O error occurs
+     * @throws IllegalDataException if OSM parsing fails
+     */
+    @Test
+    public void testTicket9599Simple() throws IOException, IllegalDataException {
+        try (InputStream is = TestUtils.getRegressionDataStream(9599, "three_old.osm")) {
+            DataSet ds = OsmReader.parseDataSet(is, null);
+            Layer layer = new OsmDataLayer(ds, null, null);
+            MainApplication.getLayerManager().addLayer(layer);
+            try {
+                new JoinAreasAction(false).join(ds.getWays());
+                Collection<IPrimitive> found = SearchAction.searchAndReturn("type:way", SearchMode.replace);
+                assertEquals(1, found.size());
+                assertEquals(31567319, found.iterator().next().getUniqueId());
+            } finally {
+                // Ensure we clean the place before leaving, even if test fails.
+                MainApplication.getLayerManager().removeLayer(layer);
+            }
+        }
+    }
+
+    /**
      * Non-regression test for bug #10511.
      * @throws IOException if any I/O error occurs
