Index: src/org/openstreetmap/josm/actions/MergeNodesAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 4313)
+++ src/org/openstreetmap/josm/actions/MergeNodesAction.java	(working copy)
@@ -24,7 +24,7 @@
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.DeleteCommand;
 import org.openstreetmap.josm.command.SequenceCommand;
-import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.RelationToChildReference;
@@ -93,21 +93,61 @@
      * @return the coordinates of this node are later used for the target node
      */
     public static Node selectTargetLocationNode(List<Node> candidates) {
-        if (! Main.pref.getBoolean("merge-nodes.average-location", false)) {
-            Node targetNode = null;
+        int size = candidates.size();
+        if (size == 0)
+            throw new IllegalArgumentException("empty list");
+
+        switch (Main.pref.getInteger("merge-nodes.mode", 0)) {
+        case 0: {
+            Node targetNode = candidates.get(size - 1);
             for (final Node n : candidates) { // pick last one
                 targetNode = n;
             }
             return targetNode;
         }
+        case 1: {
+            double east = 0, north = 0;
+            for (final Node n : candidates) {
+                east += n.getEastNorth().east();
+                north += n.getEastNorth().north();
+            }
 
-        double lat = 0, lon = 0;
-        for (final Node n : candidates) {
-            lat += n.getCoor().lat();
-            lon += n.getCoor().lon();
+            return new Node(new EastNorth(east / size, north / size));  // TODO: not exact for long distances
         }
+        case 2: {
+            class WeightCoord {
+                EastNorth eastNorth;
+                double weight;
+            }
 
-        return new Node(new LatLon(lat / candidates.size(), lon / candidates.size()));
+            List<WeightCoord> wcl = new ArrayList<WeightCoord>();
+            double weight = 0;
+            for (int i = 0; i < size; i++) {
+                for (int j = i + 1; j < size; j++) {
+                    final EastNorth c1 = candidates.get(i).getEastNorth();
+                    final EastNorth c2 = candidates.get(j).getEastNorth();
+
+                    WeightCoord wc = new WeightCoord();
+                    wc.eastNorth = c1.interpolate(c2, 0.5);
+                    wc.weight = c1.distance(c2);
+                    wcl.add(wc);
+                    weight += wc.weight;
+                }
+            }
+
+            double east = 0, north = 0;
+            for (final WeightCoord wc : wcl) {
+                east += wc.eastNorth.east() * wc.weight;
+                north += wc.eastNorth.north() * wc.weight;
+            }
+
+            return new Node(new EastNorth(east / weight, north / weight)); // TODO: not exact for long distances
+        }
+        default:
+            throw new RuntimeException("unacceptable merge-nodes.mode");
+        }
+
+
     }
 
     /**
