Index: /applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Address.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Address.java	(revision 22100)
+++ /applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Address.java	(revision 22101)
@@ -6,4 +6,5 @@
 import java.awt.GridBagLayout;
 import java.awt.Point;
+import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -13,5 +14,13 @@
 import java.awt.event.MouseMotionListener;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import javax.swing.ButtonGroup;
@@ -25,5 +34,10 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.ChangeCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.actions.mapmode.MapMode;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -36,4 +50,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -58,5 +73,7 @@
     final JTextField inputNumber = new JTextField();
     final JTextField inputStreet = new JTextField();
-
+    
+    MapFrame mapFrame;
+    
     public Address(MapFrame mapFrame) {
         super(tr("Add address"), "buildings", 
@@ -64,4 +81,5 @@
                 Shortcut.registerShortcut("mapmode:buildings", tr("Mode: {0}", tr("Buildings")), KeyEvent.VK_E, Shortcut.GROUP_EDIT),
                 mapFrame, getCursor());
+        this.mapFrame = mapFrame;
     }
 
@@ -166,10 +184,12 @@
             } else if (mouseOnExistingWays.size() == 0) {
                 // clicked a non highway and not a node => add the new address 
-                Node n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
-                if (n != null)
-                    if (!n.hasKey(tagHouseNumber))
-                        addAddrToNode(n);
-                else
-                    createNewNode(mousePos);
+                if (inputStreet.getText().equals("") || inputNumber.getText().equals("")) {
+                    Toolkit.getDefaultToolkit().beep();
+                } else {
+                    Node n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
+                    if (n == null)
+                        n = createNewNode(e);
+                    addAddrToNode(n);
+                }
             }
         }
@@ -178,9 +198,123 @@
     
     private void addAddrToNode(Node n) {
-        // node exists : just add the tag addr:housenumber and member in relation
-    }
-    
-    private void createNewNode(Point mousePos) {
-        
+        // add the tag addr:housenumber in node and member in relation
+    }
+    
+    private Node createNewNode(MouseEvent e) {
+        // DrawAction.mouseReleased() but without key modifiers
+        Node n = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
+        Collection<Command> cmds = new LinkedList<Command>();
+        cmds.add(new AddCommand(n));
+        List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(e.getPoint(), OsmPrimitive.isSelectablePredicate);
+        Map<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
+        for (WaySegment ws : wss) {
+            List<Integer> is;
+            if (insertPoints.containsKey(ws.way)) {
+                is = insertPoints.get(ws.way);
+            } else {
+                is = new ArrayList<Integer>();
+                insertPoints.put(ws.way, is);
+            }
+
+            is.add(ws.lowerIndex);
+        }
+        Set<Pair<Node,Node>> segSet = new HashSet<Pair<Node,Node>>();
+        ArrayList<Way> replacedWays = new ArrayList<Way>();
+        ArrayList<Way> reuseWays = new ArrayList<Way>();
+        for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
+            Way w = insertPoint.getKey();
+            List<Integer> is = insertPoint.getValue();
+            Way wnew = new Way(w);
+            pruneSuccsAndReverse(is);
+            for (int i : is) {
+                segSet.add(Pair.sort(new Pair<Node,Node>(w.getNode(i), w.getNode(i+1))));
+            }
+            for (int i : is) {
+                wnew.addNode(i + 1, n);
+            }
+            cmds.add(new ChangeCommand(insertPoint.getKey(), wnew));
+            replacedWays.add(insertPoint.getKey());
+            reuseWays.add(wnew);
+        }
+        adjustNode(segSet, n);
+
+        Command c = new SequenceCommand("Add node address", cmds);
+        Main.main.undoRedo.add(c);
+        return n;
+    }
+    
+    private static void adjustNode(Collection<Pair<Node,Node>> segs, Node n) {
+
+        switch (segs.size()) {
+        case 0:
+            return;
+        case 2:
+            // This computes the intersection between
+            // the two segments and adjusts the node position.
+            Iterator<Pair<Node,Node>> i = segs.iterator();
+            Pair<Node,Node> seg = i.next();
+            EastNorth A = seg.a.getEastNorth();
+            EastNorth B = seg.b.getEastNorth();
+            seg = i.next();
+            EastNorth C = seg.a.getEastNorth();
+            EastNorth D = seg.b.getEastNorth();
+
+            double u=det(B.east() - A.east(), B.north() - A.north(), C.east() - D.east(), C.north() - D.north());
+
+            // Check for parallel segments and do nothing if they are
+            // In practice this will probably only happen when a way has been duplicated
+
+            if (u == 0) return;
+
+            // q is a number between 0 and 1
+            // It is the point in the segment where the intersection occurs
+            // if the segment is scaled to lenght 1
+
+            double q = det(B.north() - C.north(), B.east() - C.east(), D.north() - C.north(), D.east() - C.east()) / u;
+            EastNorth intersection = new EastNorth(
+                    B.east() + q * (A.east() - B.east()),
+                    B.north() + q * (A.north() - B.north()));
+
+            int snapToIntersectionThreshold
+            = Main.pref.getInteger("edit.snap-intersection-threshold",10);
+
+            // only adjust to intersection if within snapToIntersectionThreshold pixel of mouse click; otherwise
+            // fall through to default action.
+            // (for semi-parallel lines, intersection might be miles away!)
+            if (Main.map.mapView.getPoint(n).distance(Main.map.mapView.getPoint(intersection)) < snapToIntersectionThreshold) {
+                n.setEastNorth(intersection);
+                return;
+            }
+
+        default:
+            EastNorth P = n.getEastNorth();
+            seg = segs.iterator().next();
+            A = seg.a.getEastNorth();
+            B = seg.b.getEastNorth();
+            double a = P.distanceSq(B);
+            double b = P.distanceSq(A);
+            double c = A.distanceSq(B);
+            q = (a - b + c) / (2*c);
+            n.setEastNorth(new EastNorth(B.east() + q * (A.east() - B.east()), B.north() + q * (A.north() - B.north())));
+        }
+    }
+    
+    static double det(double a, double b, double c, double d) {
+        return a * d - b * c;
+    }
+
+    private static void pruneSuccsAndReverse(List<Integer> is) {
+        //if (is.size() < 2) return;
+
+        HashSet<Integer> is2 = new HashSet<Integer>();
+        for (int i : is) {
+            if (!is2.contains(i - 1) && !is2.contains(i + 1)) {
+                is2.add(i);
+            }
+        }
+        is.clear();
+        is.addAll(is2);
+        Collections.sort(is);
+        Collections.reverse(is);
     }
 
