Index: plugins/lakewalker/build.xml
===================================================================
--- plugins/lakewalker/build.xml	(revision 6054)
+++ plugins/lakewalker/build.xml	(working copy)
@@ -28,6 +28,9 @@
   <target name="compile" depends="init">
     <mkdir dir="build"></mkdir>
     <mkdir dir="build/images"></mkdir>
+    <javac srcdir="src" classpath="${josm}" destdir="build" debug="true">
+	<include name="**/*.java" />
+    </javac>
     <copy todir="build">
       <fileset dir="${plugin.build.dir}" casesensitive="yes">
     	<filename name="**/*.class"/>
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedWay.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedWay.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedWay.java	(working copy)
@@ -90,12 +90,12 @@
             errors.add( new TestError(this, Severity.WARNING, tr("Untagged ways"), w, UNTAGGED_WAY) );
         }
         
-        if( w.nodes.size() == 0 )
+        if( w.nrNodes() == 0 )
         {
             errors.add( new TestError(this, Severity.ERROR, tr("Empty ways"), w, EMPTY_WAY) );
         }
         
-        if( w.nodes.size() == 1 )
+        if( w.nrNodes() == 1 )
         {
             errors.add( new TestError(this, Severity.ERROR, tr("One node ways"), w, ONE_NODE_WAY) );
         }
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicateNode.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicateNode.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicateNode.java	(working copy)
@@ -23,6 +23,7 @@
 {
 	/** Bag of all nodes */
 	Bag<LatLon, OsmPrimitive> nodes;
+	Bag<LatLon, Way> ways;
 	
 	/**
 	 * Constructor
@@ -38,15 +39,90 @@
 	public void startTest() 
 	{
 		nodes = new Bag<LatLon, OsmPrimitive>(1000);
+		ways = new Bag<LatLon, Way>(1000);
 	}
 
+	static Node getNodeAt(Way w, LatLon l)
+	{
+		//stem.out.println("getNodeAt() begin");
+		for (Node n : w.allNodes()) {
+			//stem.out.println("	getNodeAt(" + l + ") node: " + n + " equal: " + (n.coor.equals(l)) );
+			if (n.coor.equals(l)) {
+				//stem.out.println("getNodeAt() returning: " + n);
+				return n;
+			}
+		}
+		//stem.out.println("getNodeAt() never found anything");
+		return null;
+	}
+	static String getType(OsmPrimitive p)
+	{
+			Collection<String> types = new LinkedList<String>();
+		   	types.add("highway");
+		   	types.add("railway");
+		   	types.add("powerline");
+			for (String type : types) {
+				if (p.get(type) == null)
+					continue;
+				// Motorways are allowed to intersect other
+				// roads, but not be connected.
+				if (type.equals("highway") && p.get("highway").equals("motorway"))
+					return p.get("highway");
+				return type;
+			}
+			return null;
+	}
 	@Override
 	public void endTest() 
 	{
-		for(List<OsmPrimitive> duplicated : nodes.values() )
+		for(LatLon key : ways.keySet() )
 		{
-			if( duplicated.size() > 1)
-			{
+			//stem.out.println("there are " + ways.get(key).size() + " ways and " +
+			//			   		nodes.get(key).size() + " nodes at " + key);
+			// this means that each of the nodes was found
+			// in _some_ way, meaning there are multiple ways
+			// at these coordinates.  We'll deal with merging
+			// (or not) those ways here.
+			if (ways.get(key).size() >= nodes.get(key).size())
+				nodes.remove(key);
+			ArrayList<OsmPrimitive> duplicated = new ArrayList<OsmPrimitive>();
+			for (Way w1 : ways.get(key)) {
+				for (Way w2 : ways.get(key)) {
+					if (w1 == w2) {
+						//stem.out.println("same way");
+						continue;
+					}
+					if (getType(w1) != getType(w2)) {
+						//stem.out.println("different types: '" + getType(w1) + "'/'" + getType(w2) + "'");
+						continue;
+					}
+					Node n1 = getNodeAt(w1, key);
+					Node n2 = getNodeAt(w2, key);
+					if (n1 == null || n1.deleted) {
+						//stem.out.println("n1 deleted or null: " + n1);
+						continue;
+					}
+					if (n2 == null || n2.deleted) {
+						//stem.out.println("n2 deleted or null: " + n2);
+						continue;
+					}
+					if (n1 == n2) {
+						//stem.out.println("same node");
+						continue;
+					}
+					if (!duplicated.contains(n1))
+						duplicated.add(n1);
+					if (!duplicated.contains(n2))
+						duplicated.add(n2);
+				}
+			}
+			if (duplicated.size() <= 1)
+				continue;
+			TestError testError = new TestError(this, Severity.ERROR, tr("Duplicated nodes"), duplicated);
+			errors.add( testError );
+		}
+		for(List<OsmPrimitive> duplicated : nodes.values() ) {
+			if( duplicated.size() > 1) {
 				TestError testError = new TestError(this, Severity.ERROR, tr("Duplicated nodes"), duplicated);
 				errors.add( testError );
 			}
@@ -57,8 +133,17 @@
 	@Override
 	public void visit(Node n) 
 	{
+		//stem.out.println("Visit node nr: " + n.id);
 		nodes.add(n.coor, n);
 	}
+
+	@Override
+	public void visit(Way w) 
+	{
+		for (Node n : w.allNodes()) {
+			ways.add(n.coor, w);
+		}
+	}
 	
     /**
      * Merge the nodes into one.
@@ -98,43 +183,32 @@
         nodes.remove(target);
         
         // Merge all properties
-        Node newtarget = new Node(target);
-        for (final OsmPrimitive o : nodes) 
-        {
+        Collection<Command> cmds = new LinkedList<Command>();
+
+		Map<String, String> future_keys = new HashMap<String, String>();
+		if (target.keys != null)
+			future_keys.putAll(target.keys);
+        for (final OsmPrimitive o : nodes) {
             Node n = (Node)o;
-            for ( String key : n.keySet() )
-            {
-                if( newtarget.keySet().contains(key) && !newtarget.get(key).equals(n.get(key)) )
-                {
-                    JOptionPane.showMessageDialog(Main.parent, tr("Nodes have conflicting key: " + key + " ["+newtarget.get(key)+", "+n.get(key)+"]"));
+            for ( String key : n.keySet() ) {
+				String n_val = n.get(key);
+                if( future_keys.containsKey(key) && !future_keys.get(key).equals(n_val) ) {
+                    JOptionPane.showMessageDialog(Main.parent, tr("Nodes have conflicting key: " + key + 
+																  " ["+future_keys.get(key)+", "+n.get(key)+"]"));
                     return null;
                 }
-                newtarget.put( key, n.get(key) ); 
+				future_keys.put(key, n_val); 
+				List<OsmPrimitive> l = new ArrayList<OsmPrimitive>();
+				l.add(target);
+				Command c = new ChangePropertyCommand(l, key, n_val);
+				cmds.add(c);
             }
+			for (Way w : n.waysUsing()) {
+				cmds.add(new ReplaceSubObjectCommand(w, n, target));
+			}
         }        
 
-        Collection<Command> cmds = new LinkedList<Command>();
-
-		// Now search the ways for occurences of the nodes we are about to
-		// merge and replace them with the 'target' node
-		for (Way w : Main.ds.ways) {
-			if (w.deleted || w.incomplete) continue;
-			// FIXME: use some fancy method from java.util.Collections and
-			// List.replace
-			Way wnew = null;
-			int len = w.nodes.size();
-			for (int i = 0; i < len; i++) {
-				if (!nodes.contains(w.nodes.get(i))) continue;
-				if (wnew == null) wnew = new Way(w);
-				wnew.nodes.set(i, target);
-			}
-			if (wnew != null) {
-				cmds.add(new ChangeCommand(w, wnew));
-			}
-		}
-
         cmds.add(new DeleteCommand(nodes));
-        cmds.add(new ChangeCommand(target, newtarget));
         return new SequenceCommand(tr("Merge Nodes"), cmds);
 	}
 	
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/ChangePropertyKeyCommand.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/ChangePropertyKeyCommand.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/ChangePropertyKeyCommand.java	(working copy)
@@ -47,7 +47,7 @@
 		this.newKey = newKey;
 	}
 	
-	@Override public void executeCommand() {
+	@Override public boolean executeCommand() {
 		super.executeCommand(); // save old
 		for (OsmPrimitive osm : objects) {
 			if(osm.keys != null) 
@@ -56,6 +56,7 @@
 				osm.put(newKey, osm.keys.remove(key) );
 			}
 		}
+		return true;
 	}
 
 	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/EmptyWays.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/EmptyWays.java	(revision 0)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/EmptyWays.java	(revision 0)
@@ -0,0 +1,65 @@
+package org.openstreetmap.josm.plugins.validator.tests;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.geom.Point2D;
+import java.util.*;
+
+import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.plugins.validator.*;
+import org.openstreetmap.josm.plugins.validator.util.Bag;
+import org.openstreetmap.josm.command.*;
+
+/**
+ * Checks for similar named ways, symptom of a possible typo. It uses the
+ * Levenshtein distance to check for similarity
+ * 
+ * @author frsantos
+ */
+public class EmptyWays extends Test 
+{
+    /**
+	 * Constructor
+	 */
+	public EmptyWays() 
+	{
+		super(tr("Empty Ways."),
+			  tr("This test checks for ways that have no segments in them."));
+	}
+
+    @Override
+    public Command fixError(TestError testError)
+    {
+		Way w = (Way)testError.getPrimitives().get(0); 
+        
+        List<Command> cmds = new ArrayList<Command>();
+        cmds.add(new DeleteCommand(testError.getPrimitives()));
+       	return new SequenceCommand(tr("Delete Ways"), cmds);
+    }
+    @Override
+    public boolean isFixable(TestError testError)
+    {
+		return (testError.getTester() instanceof EmptyWays);
+    }
+
+    @Override
+    public void startTest() 
+    {
+    }
+
+    @Override
+    public void endTest() 
+    {
+    }
+    
+	@Override
+	public void visit(Way w) 
+	{
+        if( w.deleted )
+            return;
+		if (w.nrNodes() > 0)
+			return;
+        errors.add(new TestError(this, Severity.WARNING, tr("Empty ways"), w));
+	}
+    
+}
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedNode.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedNode.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedNode.java	(working copy)
@@ -21,7 +21,12 @@
 public class UntaggedNode extends Test 
 {
 	/** Tags allowed in a node */
-	public static String[] allowedTags = new String[] { "created_by" };
+	public static String[] allowedTags = new String[] { 
+			"created_by",
+			"tiger:county",
+			"tiger:upload_uuid",
+			"tiger:tlid",
+			};
 	
 	/** Bag of all nodes */
 	Set<Node> emptyNodes;
@@ -75,7 +80,7 @@
 		if( tags != null )
 		{
 			numTags = tags.size();
-			for( String tag : allowedTags)
+			for( String tag : allowedTags) 
 				if( tags.containsKey(tag) ) numTags--;
 		}
 		
@@ -88,7 +93,7 @@
 	@Override
 	public void visit(Way w) 
 	{
-		for (Node n : w.nodes) {
+		for (Node n : w.allNodes()) {
 			emptyNodes.remove(n);
 		}
 	}
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java	(working copy)
@@ -70,7 +70,7 @@
                 if( natural2 == null || !natural2.equals("coastline") )
                     continue;
                 
-                if( w.nodes.get(0).equals(w2.nodes.get(0)) || w.nodes.get(w.nodes.size() - 1).equals(w2.nodes.get(w2.nodes.size() - 1)))
+                if( w.nodeNr(0).equals(w2.nodeNr(0)) || w.nodeNr(w.nrNodes() - 1).equals(w2.nodeNr(w2.nrNodes() - 1)))
                 {
                     List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
                     primitives.add(w);
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicatedWayNodes.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicatedWayNodes.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicatedWayNodes.java	(working copy)
@@ -6,9 +6,9 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.DeleteCommand;
-import org.openstreetmap.josm.command.ChangeCommand;
+import org.openstreetmap.josm.command.*;
+import java.util.LinkedList;
+import java.util.Collection;
 import java.util.Collections;
 
 public class DuplicatedWayNodes extends Test {
@@ -21,7 +21,7 @@
 		if (w.deleted || w.incomplete) return;
 
 		Node lastN = null;
-		for (Node n : w.nodes) {
+		for (Node n : w.allNodes()) {
 			if (lastN == null) {
 				lastN = n;
 				break;
@@ -35,25 +35,20 @@
 	}
 
 	@Override public Command fixError(TestError testError) {
+		Collection<Command> cmds = new LinkedList<Command>();
 		Way w = (Way) testError.getPrimitives().iterator().next();
-		Way wnew = new Way(w);
-		wnew.nodes.clear();
 		Node lastN = null;
-		for (Node n : w.nodes) {
+		for (Node n : w.allNodes()) {
 			if (lastN == null) {
-				wnew.nodes.add(n);
+				cmds.add(new ReplaceSubObjectCommand(w, null, n));
 			} else if (n == lastN) {
 				// Skip this node
 			} else {
-				wnew.nodes.add(n);
+				cmds.add(new ReplaceSubObjectCommand(w, null, n));
 			}
 			lastN = n;
 		}
-		if (wnew.nodes.size() < 2) {
-			// Empty way, delete
-			return new DeleteCommand(Collections.singleton(w));
-		} else {
-			return new ChangeCommand(w, wnew);
-		}
+		cmds.add(new ConditionalDeleteCommand(Collections.singleton(w)));
+		return new SequenceCommand(tr("Delete Duplicate Way Nodes"), cmds);
 	}
 }
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/SelfIntersectingWay.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/SelfIntersectingWay.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/SelfIntersectingWay.java	(working copy)
@@ -23,8 +23,8 @@
 	@Override public void visit(Way w) {
 		HashSet<Node> nodes = new HashSet<Node>();
 
-		for (int i = 1; i < w.nodes.size() - 1; i++) {
-			Node n = w.nodes.get(i);
+		for (int i = 1; i < w.nrNodes() - 1; i++) {
+			Node n = w.nodeNr(i);
 			if (nodes.contains(n)) {
 				errors.add(new TestError(this,
 					Severity.WARNING, tr("Self-intersecting ways"), w, 0));
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/OverlappingWays.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/OverlappingWays.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/OverlappingWays.java	(working copy)
@@ -45,12 +45,18 @@
 	@Override
 	public void endTest() 
 	{
+		// This Bag is to ensure that we don't report the same
+		// pair over and over again because they overlapped
+		// at multiple point pairs
+		Bag<List<OsmPrimitive>, Integer> duplicates = new Bag<List<OsmPrimitive>, Integer>();
 		for (List<OsmPrimitive> duplicated : nodePairs.values())
 		{
-			if (duplicated.size() > 1)
-			{
-				errors.add( new TestError(this, Severity.OTHER, tr("Overlapping ways"), duplicated) );
-			}
+			if (duplicated.size() <= 1)
+				continue;
+			if (duplicates.get(duplicated) != null)
+		   		continue;
+			duplicates.add(duplicated, new Integer(1));
+			errors.add( new TestError(this, Severity.OTHER, tr("Overlapping ways"), duplicated) );
 		}
 		nodePairs = null;
 	}
@@ -59,7 +65,7 @@
 	public void visit(Way w) 
 	{
 		Node lastN = null;
-		for (Node n : w.nodes) {
+		for (Node n : w.allNodes()) {
 			if (lastN == null) {
 				lastN = n;
 				continue;
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/CrossingWays.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/CrossingWays.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/CrossingWays.java	(working copy)
@@ -56,16 +56,17 @@
         String coastline1 = w.get("natural"); 
         boolean isCoastline1 = coastline1 != null && (coastline1.equals("water") || coastline1.equals("coastline"));
         String railway1 = w.get("railway"); 
+        String highway1 = w.get("highway"); 
         boolean isSubway1 = railway1 != null && railway1.equals("subway");
         if( w.get("highway") == null && w.get("waterway") == null && !isSubway1 && !isCoastline1) 
         	return;
         
         String layer1 = w.get("layer");
 
-		int nodesSize = w.nodes.size();
+		int nodesSize = w.nrNodes();
 		for (int i = 0; i < nodesSize - 1; i++) {
 			WaySegment ws = new WaySegment(w, i);
-            ExtendedSegment es1 = new ExtendedSegment(ws, layer1, railway1, coastline1);
+            ExtendedSegment es1 = new ExtendedSegment(ws, layer1, railway1, coastline1, highway1);
             List<List<ExtendedSegment>> cellSegments = getSegments(es1.n1, es1.n2);
             for( List<ExtendedSegment> segments : cellSegments)
             {
@@ -77,6 +78,7 @@
 	                String layer2 = es2.layer;
 	                String railway2 = es2.railway;
 	                String coastline2 = es2.coastline;
+	                String highway2 = es2.highway;
 					if (layer1 == null ? layer2 != null : !layer1.equals(layer2))
 	                	continue;
 	                
@@ -89,7 +91,11 @@
                     List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
                     primitives.add(es1.ws.way);
                     primitives.add(es2.ws.way);
-                    errors.add( new TestError(this, Severity.WARNING, tr("Crossing ways"), primitives) );
+					String error_str = "Crossing ways";
+					if ((es2.highway != null) && (es1.highway != null) &&
+						(es2.highway.equals("motorway") || es1.highway.equals("motorway")))
+						error_str = "Crossing with motorway";
+                    errors.add( new TestError(this, Severity.WARNING, tr(error_str), primitives) );
 	            }
 	            segments.add(es1);
             }
@@ -140,6 +146,9 @@
 		/** The coastline type */
 		public String coastline;
         
+		/** The highway type */
+		public String highway;
+
         /**
          * Constructor
          * @param ws The way segment
@@ -147,14 +156,15 @@
          * @param railway The railway type of the way this segment is in
          * @param coastline The coastlyne typo of the way the segment is in
          */
-        public ExtendedSegment(WaySegment ws, String layer, String railway, String coastline)
+        public ExtendedSegment(WaySegment ws, String layer, String railway, String coastline, String highway)
         {
             this.ws = ws;
-			this.n1 = ws.way.nodes.get(ws.lowerIndex);
-			this.n2 = ws.way.nodes.get(ws.lowerIndex + 1);
+			this.n1 = ws.way.nodeNr(ws.lowerIndex);
+			this.n2 = ws.way.nodeNr(ws.lowerIndex + 1);
             this.layer = layer;
             this.railway = railway;
             this.coastline = coastline;
+            this.highway = highway;
         }
         
         /**
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/MotorwayIntersections.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/MotorwayIntersections.java	(revision 0)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/MotorwayIntersections.java	(revision 0)
@@ -0,0 +1,167 @@
+package org.openstreetmap.josm.plugins.validator.tests;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.*;
+
+import org.openstreetmap.josm.command.*;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.tools.Pair;
+import org.openstreetmap.josm.plugins.validator.Severity;
+import org.openstreetmap.josm.plugins.validator.Test;
+import org.openstreetmap.josm.plugins.validator.TestError;
+import org.openstreetmap.josm.plugins.validator.util.Bag;
+
+/**
+ * @author Dave Hansen
+ */
+public class MotorwayIntersections extends Test 
+{
+	/** Bag of all way segments */
+	HashSet<Node> motorway_nodes;
+	
+	/**
+	 * Constructor
+	 */
+	public MotorwayIntersections() 
+	{
+		super(tr("Motorway Intersections."),
+			  tr("This test checks that motorways only intersect "
+				+ "with other motorways or motorway_links."));
+		
+	}
+
+	@Override
+	public void startTest() 
+	{
+		motorway_nodes = new HashSet<Node>();
+	}
+
+	static boolean isMotorway(Way w)
+	{
+		String highway = w.get("highway");
+		if (highway == null)
+			return false;
+		if (highway.equals("motorway"))
+			return true;
+		return false;
+	}
+	static boolean mayTouchMotorway(Way w)
+	{
+		if (isMotorway(w))
+			return true;
+		String highway = w.get("highway");
+		if (highway == null)
+			return false;
+		if (highway.equals("motorway_link"))
+			return true;
+		return false;
+	}
+	@Override
+	public void endTest() 
+	{
+		for (Node n : motorway_nodes) {
+			for (Way w1 : n.waysUsing()) {
+				if (!isMotorway(w1))
+					continue;
+				// It is OK for a motorway to terminate on a non-motorway
+				if (w1.nodeNr(0) == n)
+					continue;
+				if (w1.nodeNr(w1.nrNodes()-1) == n)
+					continue;
+				for (Way w2 : n.waysUsing()) {
+					if (w1 == w2)
+						continue;
+					if (mayTouchMotorway(w2))
+						continue;
+					List<OsmPrimitive> badTouch = new LinkedList<OsmPrimitive>();
+					// careful, we depend on this order staying the same
+					badTouch.add(w1);
+					badTouch.add(w2);
+					errors.add( new TestError(this, Severity.OTHER, tr("Motorway touches non-motorway"), badTouch) );
+				}
+			}
+		}
+	}
+
+	static Node getWayIntersection(Way w1, Way w2)
+	{
+		for (Node n : w1.allNodes()) {
+			if (w2.containsNode(n))
+				return n;
+		}
+		return null;
+	}
+
+	/*
+	 * There's a bug with this, and I think it affects the DuplicateNodes
+	 * test, too.  It happens when there are multiple bad intersections
+	 * on a single way.  Two TestErrors are produced, and each enters
+	 * here, makes a copy of the same, old way.  Each issues a command
+	 * to change that old way to a new one.  They overwrite each other,
+	 * so only one of the fixes will actually show up.
+	 *
+	 * Workaround for now is to press the fix button a couple of times.
+	 */
+	@Override
+	public Command fixError(TestError testError)
+	{
+        Collection<OsmPrimitive> sel = testError.getPrimitives();
+        ArrayList<Way> ways = new ArrayList<Way>();
+
+        for (OsmPrimitive osm : sel) {
+			Way w = (Way)osm;
+            ways.add(w);
+		}
+       	Way motorway = ways.get(0); 
+       	Way w2 = ways.get(1); 
+		
+		if (!isMotorway(motorway) || isMotorway(w2)) {
+			System.out.println("Error in MotorwayIntersections test: unexpected way types");
+			return null;
+		}
+
+		Node shared = getWayIntersection(motorway, w2);
+		if (shared == null || motorway.deleted || w2.deleted || shared.deleted)
+			return null;
+		Node newNode = new Node(shared);
+		int indexInW2 = w2.lookupNodeNr(shared);
+		newNode.id = 0;
+
+		Collection<Command> cmds = new LinkedList<Command>();
+		/*
+		 * Now go find all ways that use the node.  The new
+		 * node we've created is for non-motorways.  We know
+		 * that 
+		 */
+		for (Way w : shared.waysUsing()) {
+				if (w.deleted)
+					continue;
+				if (isMotorway(w))
+					continue;
+				Command c = new ReplaceSubObjectCommand(w, shared, newNode);
+				cmds.add(c);
+		}
+		if (cmds.size() == 0)
+			return null;
+        Command c = new SequenceCommand(tr("Split at intersection"), cmds);
+		return c;
+	}
+
+	@Override
+	public void visit(Way w) 
+	{
+		if (w.deleted || !isMotorway(w))
+			return;
+		for (Node n : w.allNodes())
+			motorway_nodes.add(n);
+	}
+	@Override
+	public boolean isFixable(TestError testError)
+	{
+		return (testError.getTester() instanceof MotorwayIntersections);
+	}
+}
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/GridLayer.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/GridLayer.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/GridLayer.java	(working copy)
@@ -168,7 +168,7 @@
 		public void visit(Way w) 
 		{
 			Node lastN = null;
-			for (Node n : w.nodes) {
+			for (Node n : w.allNodes()) {
 				if (lastN == null) {
 					lastN = n;
 					continue;
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/OSMValidatorPlugin.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/OSMValidatorPlugin.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/OSMValidatorPlugin.java	(working copy)
@@ -39,6 +39,7 @@
     Map<Layer, List<TestError>> layerErrors = new HashMap<Layer, List<TestError>>();
     
     /** 
+	 * 1;3B
      * All available tests 
      * TODO: is there any way to find out automagically all available tests? 
      */
@@ -53,7 +54,10 @@
         DuplicatedWayNodes.class, 
         CrossingWays.class,
         SimilarNamedWays.class,
+        EmptyWays.class,
         Coastlines.class,
+        MotorwayIntersections.class,
+        MotorwayLinksMustTouchMotorways.class,
     };
 
 	/**
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/ValidatorDialog.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/ValidatorDialog.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/ValidatorDialog.java	(working copy)
@@ -140,7 +140,9 @@
 		{
 			String description = errorType.getKey();
 			List<Command> errorCommands = errorType.getValue();
-			allComands.add( new SequenceCommand("Fix " + description, errorCommands) );
+			SequenceCommand s = new SequenceCommand("Fix " + description, errorCommands);
+			s.continueOnError = true;
+			allComands.add(s);
 		}
 		
 		if( allComands.size() > 1 )
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/TestError.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/TestError.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/TestError.java	(working copy)
@@ -20,7 +20,7 @@
 	/** The error message */
 	private String message;
 	/** The affected primitives */
-	private List<OsmPrimitive> primitives;
+	private List<OsmPrimitive> __primitives;
 	/** The tester that raised this error */
 	private Test tester;
 	/** Internal code used by testers to classify errors */
@@ -42,12 +42,22 @@
 	 * @param message The error message
 	 * @param primitives The affected primitives
 	 */
+	void assignPrimitives(List<OsmPrimitive> newprimitives, int nr)
+	{
+		for (OsmPrimitive op : newprimitives) {
+			if (op == null) {
+				System.out.println("TestError " + nr + " op null");
+				System.out.println(op.toString());
+			}
+		}
+		this.__primitives = newprimitives;
+	}
 	public TestError(Test tester, Severity severity, String message, List<OsmPrimitive> primitives)
 	{
 		this.tester = tester;
 		this.severity = severity;
 		this.message = message;
-		this.primitives = primitives;
+		assignPrimitives(primitives, 1);
 	}
 	
 	/**
@@ -66,8 +76,8 @@
 		List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
 		primitives.add(primitive);
 		
-		this.primitives = primitives;
-	}
+		assignPrimitives(primitives, 2);
+		}
 	
 	/**
 	 * Constructor
@@ -107,7 +117,7 @@
 	 */
 	public List<OsmPrimitive> getPrimitives() 
 	{
-		return primitives;
+		return __primitives;
 	}
 
 	/**
@@ -117,7 +127,7 @@
 
 	public void setPrimitives(List<OsmPrimitive> primitives) 
 	{
-		this.primitives = primitives;
+		assignPrimitives(primitives, 3);
 	}
 
 	/**
@@ -198,7 +208,7 @@
     public void paint(Graphics g, MapView mv)
     {
         PaintVisitor v = new PaintVisitor(g, mv);
-        for( OsmPrimitive p : primitives)
+        for( OsmPrimitive p : __primitives)
         {
             if( !p.deleted || !p.incomplete )
                 p.visit(v);
@@ -294,7 +304,7 @@
         public void visit(Way w)
         {
 			Node lastN = null;
-			for (Node n : w.nodes) {
+			for (Node n : w.allNodes()) {
 				if (lastN == null) {
 					lastN = n;
 					continue;
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/AgregatePrimitivesVisitor.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/AgregatePrimitivesVisitor.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/AgregatePrimitivesVisitor.java	(working copy)
@@ -50,8 +50,7 @@
 	public void visit(Way w) 
 	{
 		aggregatedData.add(w);
-		for (Node n : w.nodes)
-			visit(n);
+		w.visitNodes(this);
 	}
 
 	public void visit(Relation r) {
Index: plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/Util.java
===================================================================
--- plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/Util.java	(revision 6054)
+++ plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/Util.java	(working copy)
@@ -241,11 +241,11 @@
      */
     public static List<List<Way>> getWaysInCell(Way w, Map<Point2D,List<Way>> cellWays)
     {
-		if (w.nodes.size() == 0)
+		if (w.nrNodes() == 0)
             return Collections.emptyList();
 
-		Node n1 = w.nodes.get(0);
-		Node n2 = w.nodes.get(w.nodes.size() - 1);
+		Node n1 = w.nodeNr(0);
+		Node n2 = w.nodeNr(w.nrNodes() - 1);
         
         List<List<Way>> cells = new ArrayList<List<Way>>(2);
         Set<Point2D> cellNodes = new HashSet<Point2D>();
Index: plugins/ywms/src/org/openstreetmap/josm/plugins/ywms/ImageLoader.java
===================================================================
--- plugins/ywms/src/org/openstreetmap/josm/plugins/ywms/ImageLoader.java	(revision 6054)
+++ plugins/ywms/src/org/openstreetmap/josm/plugins/ywms/ImageLoader.java	(working copy)
@@ -199,8 +199,19 @@
 		}
 		finally
 		{
-			if( browser != null )
+			System.out.println("yvms final browser: '" + browser + "'");
+			if( browser != null) {
+				System.out.println("yvms destroy");
 			    browser.destroy();
+				System.out.println("waiting...");
+				try {
+			    browser.waitFor();
+				} catch (InterruptedException e) {
+					System.out.println("interrupted: "+ e);
+				}
+				System.out.println("done waitin");
+			}
+			System.out.println("yvms after destroy: '" + browser + "'");
 		}
 	}
 
Index: plugins/ywms/ywms.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/lang-de.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/namefinder.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/mappaint.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/openvisible.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/validator.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/lang-fr.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/lang-en_GB.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/nearclick.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/lang-ro.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: plugins/dist/colorscheme.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
