Index: /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/GuiContainer.java
===================================================================
--- /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/GuiContainer.java	(revision 26191)
+++ /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/GuiContainer.java	(revision 26192)
@@ -27,4 +27,10 @@
     static final Color GREEN = new Color(66, 234, 108);
     
+    private static final GuiContainer EMPTY = new GuiContainer(ModelContainer.empty());
+    
+    public static GuiContainer empty() {
+        return EMPTY;
+    }
+    
     private final ModelContainer mc;
     
@@ -46,5 +52,6 @@
         
         final LatLon originCoor = Main.getProjection().eastNorth2latlon(new EastNorth(origin.getX(), origin.getY()));
-        final LatLon relCoor = Main.getProjection().eastNorth2latlon(new EastNorth(origin.getX() + 1, origin.getY() + 1));
+        final LatLon relCoor = Main.getProjection().eastNorth2latlon(
+                new EastNorth(origin.getX() + 1, origin.getY() + 1));
         
         // meters per source unit
@@ -65,4 +72,8 @@
     
     private static Point2D avgOrigin(List<Point2D> locs) {
+        if (locs.isEmpty()) {
+            return new Point2D.Double(0, 0);
+        }
+        
         double x = 0;
         double y = 0;
@@ -143,4 +154,8 @@
     
     public Rectangle2D getBounds() {
+        if (isEmpty()) {
+            return new Rectangle2D.Double(-1, -1, 2, 2);
+        }
+        
         final List<Junction> primaries = new ArrayList<Junction>(mc.getPrimaryJunctions());
         final List<Double> top = new ArrayList<Double>();
@@ -178,3 +193,7 @@
         return junctions.values();
     }
+    
+    public boolean isEmpty() {
+        return mc.isEmpty();
+    }
 }
Index: /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/JunctionPane.java
===================================================================
--- /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/JunctionPane.java	(revision 26191)
+++ /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/JunctionPane.java	(revision 26192)
@@ -5,4 +5,7 @@
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
 import java.awt.RenderingHints;
 import java.awt.event.ActionEvent;
@@ -24,5 +27,8 @@
 import javax.swing.AbstractAction;
 import javax.swing.JComponent;
+import javax.swing.JLabel;
 import javax.swing.KeyStroke;
+
+import org.openstreetmap.josm.plugins.turnlanes.model.UnexpectedDataException;
 
 class JunctionPane extends JComponent {
@@ -142,4 +148,6 @@
     private GuiContainer container;
     
+    private final JLabel error = new JLabel("");
+    
     private int width = 0;
     private int height = 0;
@@ -159,4 +167,9 @@
         setJunction(container);
         
+        setLayout(new GridBagLayout());
+        error.setOpaque(false);
+        add(error, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+                new Insets(8, 8, 8, 8), 0, 0));
+        
         setFocusable(true);
         
@@ -250,19 +263,14 @@
         removeMouseMotionListener(mip);
         removeMouseWheelListener(mip);
-        interactives.clear();
-        dragging = null;
+        this.interactives.clear();
+        this.dragging = null;
+        
         this.container = container;
-        
-        if (container == null) {
-            this.state = null;
-        } else {
-            setState(new State.Dirty(new State.Default()));
-            
-            center();
-            
-            addMouseListener(mip);
-            addMouseMotionListener(mip);
-            addMouseWheelListener(mip);
-        }
+        center();
+        setState(new State.Invalid(new State.Default()));
+        
+        addMouseListener(mip);
+        addMouseMotionListener(mip);
+        addMouseWheelListener(mip);
     }
     
@@ -289,4 +297,5 @@
     
     private void setState(State state) {
+        error.setText("");
         
         if (state instanceof State.AllTurns) {
@@ -294,7 +303,20 @@
             this.state = state;
         } else if (state instanceof State.Invalid) {
-            container = container.recalculate();
             dirty = true;
             setState(((State.Invalid) state).unwrap());
+            
+            try {
+                final GuiContainer old = container;
+                
+                container = container.recalculate();
+                
+                if (old.isEmpty() != container.isEmpty()) {
+                    center();
+                }
+            } catch (UnexpectedDataException e) {
+                displayError(e);
+            } catch (RuntimeException e) {
+                displayError(e);
+            }
         } else if (state instanceof State.Dirty) {
             dirty = true;
@@ -305,4 +327,21 @@
         
         repaint();
+    }
+    
+    private void displayError(UnexpectedDataException e) {
+        if (e.getKind() == UnexpectedDataException.Kind.MISSING_TAG
+                && UnexpectedDataException.Kind.MISSING_TAG.format("lanes").equals(e.getMessage())) {
+            
+            error.setText("<html>The number of lanes is not specified for one or more roads;"
+                    + " please add missing lanes tags.</html>");
+        } else {
+            displayError((RuntimeException) e);
+        }
+    }
+    
+    private void displayError(RuntimeException e) {
+        error.setText("<html>An error occured while constructing the model."
+                + " Please run the validator to make sure the data is consistent.<br><br>Error: " + e.getMessage()
+                + "</html>");
     }
     
@@ -344,9 +383,4 @@
         }
         
-        if (container == null) {
-            super.paintComponent(g);
-            return;
-        }
-        
         if (dirty) {
             paintPassive((Graphics2D) passive.getGraphics());
@@ -359,4 +393,6 @@
         g2d.drawImage(passive, 0, 0, getWidth(), getHeight(), null);
         g2d.drawImage(interactive, 0, 0, getWidth(), getHeight(), null);
+        
+        paintChildren(g);
     }
     
@@ -447,7 +483,5 @@
     
     void refresh() {
-        if (state != null) {
-            setState(new State.Invalid(state));
-        }
+        setState(new State.Invalid(state));
     }
 }
Index: /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/TurnLanesDialog.java
===================================================================
--- /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/TurnLanesDialog.java	(revision 26191)
+++ /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/TurnLanesDialog.java	(revision 26192)
@@ -15,5 +15,4 @@
 import javax.swing.Action;
 import javax.swing.ButtonGroup;
-import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JToggleButton;
@@ -40,5 +39,4 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.plugins.turnlanes.model.ModelContainer;
-import org.openstreetmap.josm.plugins.turnlanes.model.UnexpectedDataException;
 
 public class TurnLanesDialog extends ToggleDialog {
@@ -59,4 +57,5 @@
             editing = true;
             editButton.setSelected(true);
+            refresh();
         }
     }
@@ -137,9 +136,7 @@
     private static final String CARD_EDIT = "EDIT";
     private static final String CARD_VALIDATE = "VALIDATE";
-    private static final String CARD_ERROR = "ERROR";
     
     private final JPanel body = new JPanel();
-    private final JunctionPane junctionPane = new JunctionPane(null);
-    private final JLabel error = new JLabel();
+    private final JunctionPane junctionPane = new JunctionPane(GuiContainer.empty());
     
     private final JToggleButton editButton = new JToggleButton(editAction);
@@ -149,4 +146,5 @@
     
     private boolean editing = true;
+    private boolean wasShowing = false;
     
     public TurnLanesDialog() {
@@ -175,22 +173,5 @@
                 selected.addAll(newSelection);
                 
-                final Collection<OsmPrimitive> s = Collections.unmodifiableCollection(newSelection);
-                final List<Node> nodes = OsmPrimitive.getFilteredList(s, Node.class);
-                final List<Way> ways = OsmPrimitive.getFilteredList(s, Way.class);
-                
-                if (nodes.isEmpty()) {
-                    setJunction(null);
-                    return;
-                }
-                
-                try {
-                    setJunction(ModelContainer.create(nodes, ways));
-                } catch (UnexpectedDataException e) {
-                    displayError(e);
-                    return;
-                } catch (RuntimeException e) {
-                    displayError(e);
-                    return;
-                }
+                refresh();
             }
         });
@@ -210,43 +191,26 @@
         body.add(junctionPane, CARD_EDIT);
         body.add(new ValidationPanel(), CARD_VALIDATE);
-        body.add(error, CARD_ERROR);
         
         editButton.doClick();
     }
     
-    void displayError(UnexpectedDataException e) {
-        if (editing) {
-            if (e.getKind() == UnexpectedDataException.Kind.MISSING_TAG
-                    && UnexpectedDataException.Kind.MISSING_TAG.format("lanes").equals(e.getMessage())) {
-                
-                error.setText("<html>The number of lanes is not specified for one or more roads;"
-                        + " please add missing lanes tags.</html>");
-            } else {
-                displayError((RuntimeException) e);
-            }
+    @Override
+    protected void stateChanged() {
+        if (isShowing && !wasShowing) {
+            refresh();
+        }
+        wasShowing = isShowing;
+    }
+    
+    void refresh() {
+        if (isShowing && editing) {
+            final Collection<OsmPrimitive> s = Collections.unmodifiableCollection(selected);
+            final List<Node> nodes = OsmPrimitive.getFilteredList(s, Node.class);
+            final List<Way> ways = OsmPrimitive.getFilteredList(s, Way.class);
             
-            final CardLayout cl = (CardLayout) body.getLayout();
-            cl.show(body, CARD_ERROR);
-        }
-    }
-    
-    void displayError(RuntimeException e) {
-        if (editing) {
-            e.printStackTrace();
+            final ModelContainer mc = nodes.isEmpty() ? ModelContainer.empty() : ModelContainer
+                    .createEmpty(nodes, ways);
             
-            error.setText("<html>An error occured while constructing the model."
-                    + " Please run the validator to make sure the data is consistent.<br><br>Error: " + e.getMessage()
-                    + "</html>");
-            
-            final CardLayout cl = (CardLayout) body.getLayout();
-            cl.show(body, CARD_ERROR);
-        }
-    }
-    
-    void setJunction(ModelContainer mc) {
-        if (mc != null && editing) {
             junctionPane.setJunction(new GuiContainer(mc));
-            final CardLayout cl = (CardLayout) body.getLayout();
-            cl.show(body, CARD_EDIT);
         }
     }
Index: /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Junction.java
===================================================================
--- /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Junction.java	(revision 26191)
+++ /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Junction.java	(revision 26192)
@@ -18,11 +18,4 @@
         this.container = container;
         this.node = n;
-        
-        container.register(this);
-        
-        if (isPrimary()) {
-            // if turn data is invalid, this will force an exception now, not later during painting
-            // getTurns(); TODO force this again
-        }
     }
     
@@ -80,5 +73,5 @@
         
         throw new IllegalArgumentException("While there exists a road for the given way, the way neither "
-            + "starts nor ends at the junction node.");
+                + "starts nor ends at the junction node.");
     }
     
Index: /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Lane.java
===================================================================
--- /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Lane.java	(revision 26191)
+++ /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Lane.java	(revision 26192)
@@ -104,4 +104,5 @@
     private final Kind kind;
     
+    private Set<Turn> turns;
     private double length = -1;
     
@@ -222,4 +223,24 @@
     
     public Set<Turn> getTurns() {
+        return turns;
+    }
+    
+    public void remove() {
+        if (!isExtra()) {
+            throw new UnsupportedOperationException();
+        }
+        
+        final GenericCommand cmd = new GenericCommand(getOutgoingJunction().getNode().getDataSet(), tr("Delete lane."));
+        
+        for (Turn t : getTurns()) {
+            t.remove(cmd);
+        }
+        
+        getOutgoingRoadEnd().removeLane(cmd, this);
+        
+        Main.main.undoRedo.add(cmd);
+    }
+    
+    void initialize() {
         final Set<Turn> turns = Turn.load(getContainer(), Constants.TURN_ROLE_FROM, getOutgoingRoadEnd().getWay());
         
@@ -233,21 +254,5 @@
         }
         
-        return turns;
-    }
-    
-    public void remove() {
-        if (!isExtra()) {
-            throw new UnsupportedOperationException();
-        }
-        
-        final GenericCommand cmd = new GenericCommand(getOutgoingJunction().getNode().getDataSet(), tr("Delete lane."));
-        
-        for (Turn t : getTurns()) {
-            t.remove(cmd);
-        }
-        
-        getOutgoingRoadEnd().removeLane(cmd, this);
-        
-        Main.main.undoRedo.add(cmd);
+        this.turns = Collections.unmodifiableSet(turns);
     }
 }
Index: /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/ModelContainer.java
===================================================================
--- /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/ModelContainer.java	(revision 26191)
+++ /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/ModelContainer.java	(revision 26192)
@@ -2,7 +2,9 @@
 
 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.List;
 import java.util.Map;
@@ -18,11 +20,19 @@
 
 public class ModelContainer {
+    private static final ModelContainer EMPTY = new ModelContainer(Collections.<Node> emptySet(), Collections
+            .<Way> emptySet(), false);
+    
     public static ModelContainer create(Iterable<Node> primaryNodes, Iterable<Way> primaryWays) {
-        final Set<Node> closedNodes = new HashSet<Node>(CollectionUtils.toList(primaryNodes));
-        final Set<Way> closedWays = new HashSet<Way>(CollectionUtils.toList(primaryWays));
-        
-        close(closedNodes, closedWays);
-        
-        return new ModelContainer(closedNodes, closedWays);
+        return new ModelContainer(new HashSet<Node>(CollectionUtils.toList(primaryNodes)), new HashSet<Way>(
+                CollectionUtils.toList(primaryWays)), false);
+    }
+    
+    public static ModelContainer createEmpty(Iterable<Node> primaryNodes, Iterable<Way> primaryWays) {
+        return new ModelContainer(new HashSet<Node>(CollectionUtils.toList(primaryNodes)), new HashSet<Way>(
+                CollectionUtils.toList(primaryWays)), true);
+    }
+    
+    public static ModelContainer empty() {
+        return EMPTY;
     }
     
@@ -41,5 +51,5 @@
                 }
                 
-                for (Way w : new ArrayList<Way>(closedWays) ) {
+                for (Way w : new ArrayList<Way>(closedWays)) {
                     closed &= close(closedNodes, closedWays, w, Constants.TURN_ROLE_VIA);
                 }
@@ -90,4 +100,18 @@
     }
     
+    private static <E extends OsmPrimitive, C extends Collection<E>> C filterUsables(C collection) {
+        final Iterator<E> it = collection.iterator();
+        
+        while (it.hasNext()) {
+            final E e = it.next();
+            
+            if (e.getDataSet() == null || !e.isUsable()) {
+                it.remove();
+            }
+        }
+        
+        return collection;
+    }
+    
     private final Map<Node, Junction> junctions = new HashMap<Node, Junction>();
     private final Map<Way, Road> roads = new HashMap<Way, Road>();
@@ -96,29 +120,58 @@
     private final Set<Way> primaryWays;
     
-    private ModelContainer(Set<Node> primaryNodes, Set<Way> primaryWays) {
-        this.primaryNodes = Collections.unmodifiableSet(new HashSet<Node>(primaryNodes));
-        this.primaryWays = Collections.unmodifiableSet(new HashSet<Way>(primaryWays));
-        
-        final Set<Pair<Way, Junction>> ws = new HashSet<Pair<Way, Junction>>();
+    private final boolean empty;
+    
+    private ModelContainer(Set<Node> primaryNodes, Set<Way> primaryWays, boolean empty) {
+        if (empty) {
+            this.primaryNodes = Collections.unmodifiableSet(new HashSet<Node>(primaryNodes));
+            this.primaryWays = Collections.unmodifiableSet(new HashSet<Way>(primaryWays));
+            this.empty = true;
+        } else {
+            final Set<Node> closedNodes = filterUsables(new HashSet<Node>(primaryNodes));
+            final Set<Way> closedWays = filterUsables(new HashSet<Way>(primaryWays));
+            
+            close(closedNodes, closedWays);
+            
+            this.primaryNodes = Collections.unmodifiableSet(closedNodes);
+            this.primaryWays = Collections.unmodifiableSet(closedWays);
+            
+            for (Pair<Way, Junction> w : createPrimaryJunctions()) {
+                if (!this.primaryWays.contains(w.a)) {
+                    addRoad(new Road(this, w.a, w.b));
+                }
+            }
+            
+            for (Route r : Utils.orderWays(this.primaryWays, this.primaryNodes)) {
+                addRoad(new Road(this, r));
+            }
+            
+            for (Road r : roads.values()) {
+                r.initialize();
+            }
+            
+            this.empty = junctions.isEmpty();
+        }
+    }
+    
+    private Set<Pair<Way, Junction>> createPrimaryJunctions() {
+        final Set<Pair<Way, Junction>> roads = new HashSet<Pair<Way, Junction>>();
+        
         for (Node n : primaryNodes) {
-            final Junction j = getOrCreateJunction(n);
-            
+            final List<Way> ws = new ArrayList<Way>();
             for (Way w : Utils.filterRoads(n.getReferrers())) {
                 if (w.isFirstLastNode(n)) {
-                    ws.add(new Pair<Way, Junction>(w, j));
-                }
-            }
-        }
-        
-        final List<Route> rs = Utils.orderWays(primaryWays, primaryNodes);
-        for (Route r : rs) {
-            addRoad(new Road(this, r));
-        }
-        
-        for (Pair<Way, Junction> w : ws) {
-            if (!primaryWays.contains(w.a)) {
-                addRoad(new Road(this, w.a, w.b));
-            }
-        }
+                    ws.add(w);
+                }
+            }
+            
+            if (ws.size() > 1) {
+                final Junction j = register(new Junction(this, n));
+                for (Way w : ws) {
+                    roads.add(new Pair<Way, Junction>(w, j));
+                }
+            }
+        }
+        
+        return roads;
     }
     
@@ -130,5 +183,5 @@
         }
         
-        return new Junction(this, n);
+        return register(new Junction(this, n));
     }
     
@@ -161,6 +214,5 @@
             if (oldRoad != null) {
                 if (mergedA == null) {
-                    final Road mergedRoad = mergeRoads(oldRoad, newRoad);
-                    addRoad(mergedRoad, oldRoad, newRoad);
+                    addRoad(mergeRoads(oldRoad, newRoad), oldRoad, newRoad);
                 } else if (!oldRoad.equals(mergedA) && !oldRoad.equals(mergedB)) {
                     throw new RuntimeException("A road can't be connected to more than two junctions.");
@@ -198,32 +250,38 @@
     }
     
-    void register(Junction j) {
+    private Junction register(Junction j) {
         if (junctions.put(j.getNode(), j) != null) {
             throw new IllegalStateException();
         }
+        
+        return j;
     }
     
     public Set<Junction> getPrimaryJunctions() {
+        if (empty) {
+            return Collections.emptySet();
+        }
+        
         final Set<Junction> pjs = new HashSet<Junction>();
-        
         for (Node n : primaryNodes) {
-            pjs.add(getOrCreateJunction(n));
-        }
-        
+            pjs.add(getJunction(n));
+        }
         return pjs;
     }
     
     public Set<Road> getPrimaryRoads() {
+        if (empty) {
+            return Collections.emptySet();
+        }
+        
         final Set<Road> prs = new HashSet<Road>();
-        
         for (Way w : primaryWays) {
             prs.add(roads.get(w));
         }
-        
         return prs;
     }
     
     public ModelContainer recalculate() {
-        return new ModelContainer(primaryNodes, primaryWays);
+        return new ModelContainer(primaryNodes, primaryWays, false);
     }
     
@@ -235,3 +293,7 @@
         return primaryWays.contains(r.getRoute().getFirstSegment().getWay());
     }
+    
+    public boolean isEmpty() {
+        return empty;
+    }
 }
Index: /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Road.java
===================================================================
--- /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Road.java	(revision 26191)
+++ /applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Road.java	(revision 26192)
@@ -6,4 +6,5 @@
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
@@ -33,4 +34,5 @@
         
         private final List<Lane> lanes;
+        private Set<Turn> turns;
         
         private End(boolean from, Junction junction, Relation lengthsLeft, Relation lengthsRight) {
@@ -86,5 +88,5 @@
          */
         public Set<Turn> getTurns() {
-            return Turn.load(getContainer(), Constants.TURN_ROLE_TO, getWay());
+            return turns;
         }
         
@@ -260,4 +262,12 @@
                     && bRel.get(Constants.LENGTHS_KEY_LENGTHS_RIGHT) == null) {
                 bRel.setDeleted(true);
+            }
+        }
+        
+        void initialize() {
+            this.turns = Collections.unmodifiableSet(Turn.load(getContainer(), Constants.TURN_ROLE_TO, getWay()));
+            
+            for (Lane l : lanes) {
+                l.initialize();
             }
         }
@@ -394,3 +404,8 @@
         return getContainer().isPrimary(this);
     }
+    
+    void initialize() {
+        fromEnd.initialize();
+        toEnd.initialize();
+    }
 }
