Index: applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java	(revision 27505)
+++ applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java	(revision 27516)
@@ -70,14 +70,19 @@
         }
         Node nodeToReplace = null;
-        // see if we need to replace a node in the replacement way
+        // see if we need to replace a node in the replacement way to preserve connection in history
         if (!node.isNew()) {
             // Prepare a list of nodes that are not used anywhere except in the way
             Collection<Node> nodePool = getUnimportantNodes(way);
             nodeToReplace = findNearestNode(node, nodePool);
-        }
-        
+
+            if (nodeToReplace == null && !nodePool.isEmpty()) {
+                // findNearestNode failed, just pick the first unimportant node
+                nodeToReplace = nodePool.iterator().next();
+            }
+        }
+
         List<Command> commands = new ArrayList<Command>();
         AbstractMap<String, String> nodeTags = (AbstractMap<String, String>) node.getKeys();
-        
+
         // replace sacrificial node in way with node that is being upgraded
         if (nodeToReplace != null) {
@@ -85,5 +90,5 @@
             int idx = wayNodes.indexOf(nodeToReplace);
             wayNodes.set(idx, node);
-            if (idx == 0) {
+            if (idx == 0 && way.isClosed()) {
                 // node is at start/end of way
                 wayNodes.set(wayNodes.size() - 1, node);
@@ -92,12 +97,11 @@
             commands.add(new MoveCommand(node, nodeToReplace.getCoor()));
             commands.add(new DeleteCommand(nodeToReplace));
-            
+
             // delete tags from node
             if (!nodeTags.isEmpty()) {
-                AbstractMap<String, String> nodeTagsToDelete = new HashMap<String, String>();
                 for (String key : nodeTags.keySet()) {
-                    nodeTagsToDelete.put(key, null);
+                    commands.add(new ChangePropertyCommand(node, key, null));
                 }
-                commands.add(new ChangePropertyCommand(Arrays.asList(node), nodeTagsToDelete));
+
             }
         } else {
@@ -108,8 +112,10 @@
         // Copy tags from node
         // TODO: use merge tag conflict dialog instead
-        commands.add(new ChangePropertyCommand(Arrays.asList(way), nodeTags));
-        
+        for (String key : nodeTags.keySet()) {
+            commands.add(new ChangePropertyCommand(way, key, nodeTags.get(key)));
+        }
+
         getCurrentDataSet().setSelected(way);
-        
+
         Main.main.undoRedo.add(new SequenceCommand(
                 tr("Replace geometry for way {0}", way.getDisplayName(DefaultNameFormatter.getInstance())),
@@ -209,8 +215,9 @@
     /**
      * Create a list of nodes that are not used anywhere except in the way.
+     *
      * @param way
      * @return 
      */
-    public Collection<Node> getUnimportantNodes(Way way) {
+    protected Collection<Node> getUnimportantNodes(Way way) {
         Set<Node> nodePool = new HashSet<Node>();
         Area a = getCurrentDataSet().getDataSourceArea();
