Index: src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java	(revision 159)
+++ src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java	(revision 160)
@@ -10,16 +10,11 @@
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.Iterator;
 
 import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.io.ObjectListDownloader;
+import org.openstreetmap.josm.io.IncompleteDownloader;
 import org.xml.sax.SAXException;
 
@@ -39,37 +34,17 @@
 	 */
 	private final class DownloadTask extends PleaseWaitRunnable {
-		private ObjectListDownloader reader;
-		private DataSet dataSet;
-		private boolean nodesLoaded = false;
+		private IncompleteDownloader reader;
 
-		private DownloadTask(Collection<OsmPrimitive> toDownload) {
+		private DownloadTask(Collection<Way> toDownload) {
 			super(trn("Downloading {0} segment", "Downloading {0} segments", toDownload.size(), toDownload.size()));
-			reader = new ObjectListDownloader(toDownload);
+			reader = new IncompleteDownloader(toDownload);
 		}
 
 		@Override public void realRun() throws IOException, SAXException {
-			dataSet = reader.parse();
+			reader.parse();
 		}
 
 		@Override protected void finish() {
-			if (dataSet == null)
-				return; // user cancelled download or error occoured
-			if (dataSet.allPrimitives().isEmpty())
-				errorMessage = tr("No data imported.");
-			if (errorMessage == null && nodesLoaded == false)
-				startDownloadNodes();
-			else if (errorMessage == null)
-				Main.main.addLayer(new OsmDataLayer(dataSet, tr("Data Layer"), null));
-		}
-
-		private void startDownloadNodes() {
-			Collection<OsmPrimitive> nodes = new HashSet<OsmPrimitive>();
-			for (Segment s : dataSet.segments) {
-				nodes.add(s.from);
-				nodes.add(s.to);
-			}
-			reader = new ObjectListDownloader(nodes);
-			nodesLoaded = true;
-			Main.worker.execute(this);
+			Main.parent.repaint();
 		}
 
@@ -85,20 +60,14 @@
 	public void actionPerformed(ActionEvent e) {
 		Collection<Way> ways = new HashSet<Way>();
-		boolean sel = false;
-		for (Way w : Main.ds.ways) {
-			if (w.isIncomplete())
+		for (Way w : Main.ds.ways)
+			if (w.isIncomplete() && w.selected)
 				ways.add(w);
-			sel = sel || w.selected;
+		if (ways.isEmpty()) {
+			JOptionPane.showMessageDialog(Main.parent, tr("Please select an incomplete way."));
+			return;
 		}
-		if (sel)
-			for (Iterator<Way> it = ways.iterator(); it.hasNext();)
-				if (!it.next().selected)
-					it.remove();
-		Collection<OsmPrimitive> toDownload = new HashSet<OsmPrimitive>();
-		for (Way w : ways)
-			toDownload.addAll(w.segments);
-		if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(Main.parent, tr("Download {0} ways containing a total of {1} segments?", ways.size(), toDownload.size()), tr("Download?"), JOptionPane.YES_NO_OPTION))
+		if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(Main.parent, tr("Download {0} incomplete ways?", ways.size()), tr("Download?"), JOptionPane.YES_NO_OPTION))
 			return;
-		PleaseWaitRunnable task = new DownloadTask(toDownload);
+		PleaseWaitRunnable task = new DownloadTask(ways);
 		Main.worker.execute(task);
 	}
Index: src/org/openstreetmap/josm/actions/ExternalToolsAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/ExternalToolsAction.java	(revision 159)
+++ src/org/openstreetmap/josm/actions/ExternalToolsAction.java	(revision 160)
@@ -201,5 +201,5 @@
 			}
 			if (output != null)
-				dataSet = OsmReader.parseDataSet(p.getInputStream(), Main.pleaseWaitDlg.currentAction, Main.pleaseWaitDlg.progress);
+				dataSet = OsmReader.parseDataSet(p.getInputStream(), Main.ds, Main.pleaseWaitDlg);
 		}
 
Index: src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/OpenAction.java	(revision 159)
+++ src/org/openstreetmap/josm/actions/OpenAction.java	(revision 160)
@@ -69,5 +69,5 @@
 				DataSet dataSet;
 				if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(fn)) {
-					dataSet = OsmReader.parseDataSet(new FileInputStream(file), null, null);
+					dataSet = OsmReader.parseDataSet(new FileInputStream(file), Main.ds, Main.pleaseWaitDlg);
 				} else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
 					JOptionPane.showMessageDialog(Main.parent, fn+": "+tr("CSV Data import for non-GPS data is not implemented yet."));
Index: src/org/openstreetmap/josm/data/conflict/Merger.java
===================================================================
--- src/org/openstreetmap/josm/data/conflict/Merger.java	(revision 160)
+++ src/org/openstreetmap/josm/data/conflict/Merger.java	(revision 160)
@@ -0,0 +1,247 @@
+package org.openstreetmap.josm.data.conflict;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
+
+/**
+ * Merger provides an operation, that merges one dataset into an other, creating a list
+ * of merged conflicts on the way.
+ * 
+ * @author Immanuel.Scholz
+ */
+public class Merger {
+
+	/**
+	 * The map of all conflicting primitives. Keys are elements from our dataset (given at
+	 * constructor) and values are the associated primitives from the other dataset.
+	 * 
+	 * All references of the conflicting primitives point always to objects from our dataset.
+	 * This ensures, that later one you can just call osm.copyFrom(conflicts.get(osm)) to
+	 * "resolve" the conflict.
+	 */
+	public final Map<OsmPrimitive, OsmPrimitive> conflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
+
+	private final DataSet ds;
+
+	/**
+	 * Maps all resolved objects that were transferred to the own dataset. The key is 
+	 * the object from the other dataset given to merge(). The value is the object that
+	 * is the resolved one in the internal dataset. Both objects are from the same class.
+	 */
+	private Map<OsmPrimitive, OsmPrimitive> resolved = new HashMap<OsmPrimitive, OsmPrimitive>();
+
+
+	private AddVisitor adder;
+
+	/**
+	 * Hold the result of a decission between two elements. <code>MY</code> is keep my own,
+	 * THEIR<code>THEIR</code> means copy the other object over here and <code>CONFLICT</code>
+	 * means that both objects have to be looked closer at to decide it finally (there are
+	 * possible conflicts).
+	 */
+	private enum Solution {MY, THEIR, CONFLICT}
+
+	/**
+	 * @param ds The dataset that is the base to merge the other into.
+	 */
+	public Merger(DataSet ds) {
+		this.ds = ds;
+		adder = new AddVisitor(ds);
+	}
+
+	/**
+	 * This function merges the given dataset into the one given at constructor. The output
+	 * is dataset obtained at the constructor. Additional to that, a list of conflicts that
+	 * need to be resolved is created as member variable <code>conflicts</code>.
+	 * 
+	 * @param other The dataset that should be merged into the one given at construction time.
+	 */
+	public void merge(DataSet other) {
+		for (Node n : other.nodes)
+			merge(n);
+		for (Segment s : other.segments)
+			merge(s);
+		for (Way w : other.ways)
+			merge(w);
+	}
+
+
+	/**
+	 * Merge the object into the own dataset or add it as conflict.
+	 */
+	public void merge(OsmPrimitive their) {
+		// find the matching partner in my dataset
+		OsmPrimitive my;
+		if (their.id == 0)
+			my = findSimilar(their);
+		else {
+			my = find(their);
+			if (my == null)
+				my = findSimilar(their); // give it a second chance.
+		}
+		
+		// partner are found, solve both primitives
+		
+		if (my == null) {
+			// their is new? -> import their to my
+			their.visit(adder);
+			resolved.put(their, their);
+			copyReferences(their);
+			return;
+		}
+		Solution solution = solve(my, their);
+
+		switch(solution) {
+		case MY:
+			resolved.put(my, my);
+			return;
+		case THEIR:
+			resolved.put(their, my);
+			copyReferences(their);
+			my.cloneFrom(their);
+			return;
+		case CONFLICT:
+			resolved.put(their, my); // thats correct. Put all references from the own in case of conflicts
+			conflicts.put(my, their);
+			copyReferences(their);
+			return;
+		}
+
+	}
+
+	/**
+	 * Replace all references in the given primitive with those from resolved map
+	 */
+	private void copyReferences(OsmPrimitive osm) {
+		osm.visit(new Visitor() {
+			public void visit(Node n) {}
+			public void visit(Segment s) {
+				s.from = (Node)resolved.get(s.from);
+				s.to = (Node)resolved.get(s.to);
+				if (s.from == null || s.to == null)
+					throw new NullPointerException();
+            }
+			public void visit(Way w) {
+				Collection<Segment> segments = new LinkedList<Segment>(w.segments);
+				w.segments.clear();
+				for (Segment s : segments) {
+					if (!resolved.containsKey(s))
+						throw new NullPointerException();
+					w.segments.add((Segment)resolved.get(s));
+				}
+            }
+		});
+    }
+
+	/**
+	 * Decide what solution is necessary for my and their object to be solved. If both
+	 * objects are as good as each other, use my object (since it is cheaper to keep it than
+	 * change everything).
+	 *
+	 * @return Which object should be used or conflict in case of problems.
+	 */
+	private Solution solve(OsmPrimitive my, OsmPrimitive their) {
+		Date myDate = my.timestamp == null ? new Date(0) : my.timestamp;
+		Date theirDate = their.timestamp == null ? new Date(0) : their.timestamp;
+		Date baseDate = theirDate.before(myDate) ? theirDate : myDate;
+
+		if (my.id == 0 && their.id != 0)
+			return Solution.THEIR;
+		if (my.id != 0 && their.id == 0)
+			return Solution.MY;
+		if (my.id == 0 && their.id == 0)
+			return my.realEqual(their) ? Solution.MY : Solution.CONFLICT;
+
+		// from here on, none primitives is new
+
+		boolean myChanged = my.modified  || myDate.after(baseDate);
+		boolean theirChanged = their.modified  || theirDate.after(baseDate);
+		if (myChanged && theirChanged)
+			return my.realEqual(their) ? Solution.MY : Solution.CONFLICT;
+		if (theirChanged)
+			return Solution.THEIR;
+		if (my instanceof Segment && ((Segment)my).incomplete && !((Segment)their).incomplete)
+			return Solution.THEIR;
+		return Solution.MY;
+	}
+
+	/**
+	 * Try to find the object in the own dataset.
+	 * @return Either the object from the own dataset or <code>null</code> if not there.
+	 */
+	private OsmPrimitive find(OsmPrimitive osm) {
+		for (OsmPrimitive own : ds.allPrimitives())
+			if (own.equals(osm))
+				return own;
+		return null;
+	}
+
+	/**
+     * Find an primitive from our dataset that matches the given primitive by having the 
+     * same location. Do not look for the id for this.
+     * 
+     * @return For nodes, return the first node with the same location (in tolerance to the
+     * servers imprecision epsilon). For segments return for same starting/ending nodes.
+     * For ways, return if consist of exact the same segments.
+     */
+    private OsmPrimitive findSimilar(OsmPrimitive their) {
+    	final OsmPrimitive[] ret = new OsmPrimitive[1];
+    	Visitor v = new Visitor(){
+			public void visit(Node n) {
+				// go for an exact match first
+				for (Node my : ds.nodes) {
+					if (my.coor.equals(n.coor)) {
+						ret[0] = my;
+						return;
+					}
+				}
+				// second chance with epsilon
+				for (Node my : ds.nodes) {
+					if (my.coor.equalsEpsilon(n.coor)) {
+						ret[0] = my;
+						return;
+					}
+				}
+            }
+			public void visit(Segment s) {
+				for (Segment my : ds.segments) {
+					if (my.from == s.from && my.to == s.to) {
+						ret[0] = my;
+						return;
+					}
+				}
+            }
+			public void visit(Way w) {
+				for (Way my : ds.ways) {
+					boolean eq = true;
+					Iterator<Segment> myIt = my.segments.iterator();
+					Iterator<Segment> theirIt = w.segments.iterator();
+					while (myIt.hasNext() && theirIt.hasNext()) {
+						if (myIt.next() != theirIt.next()) {
+							eq = false;
+							break;
+						}
+					}
+					if (eq && !myIt.hasNext() && !theirIt.hasNext()) {
+						ret[0] = my;
+						return;
+					}
+				}
+            }
+    	};
+    	their.visit(v);
+    	return ret[0];
+    }
+}
Index: src/org/openstreetmap/josm/gui/MainMenu.java
===================================================================
--- src/org/openstreetmap/josm/gui/MainMenu.java	(revision 159)
+++ src/org/openstreetmap/josm/gui/MainMenu.java	(revision 160)
@@ -11,4 +11,5 @@
 import org.openstreetmap.josm.actions.AlignInCircleAction;
 import org.openstreetmap.josm.actions.DownloadAction;
+import org.openstreetmap.josm.actions.DownloadIncompleteAction;
 import org.openstreetmap.josm.actions.ExitAction;
 import org.openstreetmap.josm.actions.ExternalToolsAction;
@@ -55,4 +56,5 @@
 	public final JMenu fileMenu = new JMenu(tr("Files"));
 	public final JMenu connectionMenu = new JMenu(tr("Connection"));
+	private DownloadIncompleteAction downloadIncomplete = new DownloadIncompleteAction();
 
 
@@ -80,5 +82,5 @@
 		connectionMenu.setMnemonic('C');
 		connectionMenu.add(download);
-		//connectionMenu.add(new DownloadIncompleteAction());
+		connectionMenu.add(downloadIncomplete);
 		connectionMenu.add(upload);
 		add(connectionMenu);
Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 159)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 160)
@@ -72,5 +72,5 @@
 			try {
 				URLConnection con = url.openConnection();
-				InputStream in = new ProgressInputStream(con);
+				InputStream in = new ProgressInputStream(con, Main.pleaseWaitDlg);
 				Main.pleaseWaitDlg.currentAction.setText(tr("Downloading..."));
 				Map<Long, String> ids = idReader.parseIds(in);
Index: src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 159)
+++ src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 160)
@@ -44,5 +44,5 @@
     		for (int i = 0;;++i) {
     			Main.pleaseWaitDlg.currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
-    			InputStream in = getInputStream(url+i);
+    			InputStream in = getInputStream(url+i, Main.pleaseWaitDlg);
     			if (in == null)
     				break;
@@ -84,9 +84,9 @@
     public DataSet parseOsm() throws SAXException, IOException {
     	try {
-    		final InputStream in = getInputStream("map?bbox="+lon1+","+lat1+","+lon2+","+lat2);
+    		final InputStream in = getInputStream("map?bbox="+lon1+","+lat1+","+lon2+","+lat2, Main.pleaseWaitDlg);
     		if (in == null)
     			return null;
     		Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
-    		final DataSet data = OsmReader.parseDataSet(in, Main.pleaseWaitDlg.currentAction, Main.pleaseWaitDlg.progress);
+    		final DataSet data = OsmReader.parseDataSet(in, Main.ds, Main.pleaseWaitDlg);
     		in.close();
     		activeConnection = null;
Index: src/org/openstreetmap/josm/io/IncompleteDownloader.java
===================================================================
--- src/org/openstreetmap/josm/io/IncompleteDownloader.java	(revision 160)
+++ src/org/openstreetmap/josm/io/IncompleteDownloader.java	(revision 160)
@@ -0,0 +1,118 @@
+package org.openstreetmap.josm.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.util.Collection;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import uk.co.wilson.xml.MinML2;
+
+/**
+ * Capable of downloading ways without having to fully parse their segments.
+ * 
+ * @author Imi
+ */
+public class IncompleteDownloader extends OsmServerReader {
+
+	/**
+	 * The list of incomplete Ways to download. The ways will be filled and are complete after download.
+	 */
+	private final Collection<Way> toDownload;
+	private MergeVisitor merger = new MergeVisitor(Main.ds);
+	
+	public IncompleteDownloader(Collection<Way> toDownload) {
+		this.toDownload = toDownload;
+	}
+
+	public void parse() throws SAXException, IOException {
+		Main.pleaseWaitDlg.progress.setMaximum(toDownload.size());
+		Main.pleaseWaitDlg.progress.setValue(0);
+		int i = 0;
+		try {
+			for (Way w : toDownload) {
+				download(w);
+				Main.pleaseWaitDlg.progress.setValue(++i);
+			}
+		} catch (IOException e) {
+			if (!cancel)
+				throw e;
+		} catch (SAXException e) {
+			throw e;
+		} catch (Exception e) {
+			if (!cancel)
+				throw (e instanceof RuntimeException) ? (RuntimeException)e : new RuntimeException(e);
+		}
+	}
+
+	private static class SegmentParser extends MinML2 {
+		public long from, to;
+		@Override public void startElement(String ns, String lname, String qname, Attributes a) {
+			if (qname.equals("segment")) {
+				from = Long.parseLong(a.getValue("from"));
+				to = Long.parseLong(a.getValue("to"));
+			}
+		}
+	}
+
+	private void download(Way w) throws IOException, SAXException {
+		// get all the segments
+		for (Segment s : w.segments) {
+			if (!s.incomplete)
+				continue;
+			BufferedReader segReader;
+		    try {
+		    	segReader = new BufferedReader(new InputStreamReader(getInputStream("segment/"+s.id, null), "UTF-8"));
+	        } catch (FileNotFoundException e) {
+		        e.printStackTrace();
+		        throw new IOException(tr("Data error: Segment {0} is deleted but part of Way {1}", s.id, w.id));
+	        }
+			StringBuilder segBuilder = new StringBuilder();
+			for (String line = segReader.readLine(); line != null; line = segReader.readLine())
+				segBuilder.append(line+"\n");
+			SegmentParser segmentParser = new SegmentParser();
+			segmentParser.parse(new StringReader(segBuilder.toString()));
+			if (segmentParser.from == 0 || segmentParser.to == 0) {
+				System.out.println(segBuilder.toString());
+				throw new SAXException("Invalid segment response.");
+			}
+			if (!hasNode(segmentParser.from))
+				readNode(segmentParser.from, s.id).visit(merger);
+			if (!hasNode(segmentParser.to))
+				readNode(segmentParser.to, s.id).visit(merger);
+			readSegment(segBuilder.toString()).visit(merger);
+		}
+	}
+
+	private boolean hasNode(long id) {
+	    for (Node n : Main.ds.nodes)
+	    	if (n.id == id)
+	    		return true;
+	    return false;
+    }
+
+	private Segment readSegment(String seg) throws SAXException, IOException {
+        return OsmReader.parseDataSet(new ByteArrayInputStream(seg.getBytes("UTF-8")), Main.ds, null).segments.iterator().next();
+    }
+
+	private Node readNode(long id, long segId) throws SAXException, IOException {
+		try {
+	        return OsmReader.parseDataSet(getInputStream("node/"+id, null), Main.ds, null).nodes.iterator().next();
+        } catch (FileNotFoundException e) {
+	        e.printStackTrace();
+	        throw new IOException(tr("Data error: Node {0} is deleted but part of Segment {1}", id, segId));
+        }
+    }
+}
Index: src/org/openstreetmap/josm/io/ObjectListDownloader.java
===================================================================
--- src/org/openstreetmap/josm/io/ObjectListDownloader.java	(revision 159)
+++ 	(revision )
@@ -1,70 +1,0 @@
-package org.openstreetmap.josm.io;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
-import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
-import org.xml.sax.SAXException;
-
-public class ObjectListDownloader extends OsmServerReader {
-
-	/**
-	 * All the objects to download (if not downloading bounding boxes instead)
-	 */
-	private final Collection<OsmPrimitive> toDownload;
-	private final DataSet ds = new DataSet();
-	private final MergeVisitor merger = new MergeVisitor(ds);
-
-	public ObjectListDownloader(Collection<OsmPrimitive> toDownload) {
-		this.toDownload = toDownload;
-	}
-
-	public DataSet parse() throws SAXException, IOException {
-		Main.pleaseWaitDlg.progress.setMaximum(toDownload.size());
-		Main.pleaseWaitDlg.progress.setValue(0);
-		try {
-			final NameVisitor namer = new NameVisitor();
-			for (OsmPrimitive osm : toDownload) {
-				osm.visit(namer);
-				download(tr(namer.className), osm.id);
-				if (cancel)
-					break;
-			}
-			if (!merger.conflicts.isEmpty())
-				throw new RuntimeException(tr("Conflicts in disjunct objects"));
-			return ds;
-		} catch (IOException e) {
-			if (cancel)
-				return null;
-			throw e;
-		} catch (SAXException e) {
-			throw e;
-		} catch (Exception e) {
-			if (cancel)
-				return null;
-			if (e instanceof RuntimeException)
-				throw (RuntimeException)e;
-			throw new RuntimeException(e);
-		}
-	}
-
-	private void download(String className, long id) throws IOException, SAXException {
-		Main.pleaseWaitDlg.currentAction.setText(tr("Downloading {0} {1}", className, id));
-		InputStream in = getInputStream(className+"/"+id);
-		if (in == null)
-			return;
-		DataSet data = OsmReader.parseDataSet(in, null, null);
-		Main.pleaseWaitDlg.progress.setValue(Main.pleaseWaitDlg.progress.getValue()+1);
-		if (data.allPrimitives().size() > 1)
-			throw new SAXException(tr("Got more than one object when expecting only one."));
-		for (OsmPrimitive osm : data.allPrimitives())
-			osm.visit(merger);
-	}
-}
Index: src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReader.java	(revision 159)
+++ src/org/openstreetmap/josm/io/OsmReader.java	(revision 160)
@@ -13,6 +13,4 @@
 import java.util.Map.Entry;
 
-import javax.swing.BoundedRangeModel;
-import javax.swing.JLabel;
 
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -24,4 +22,5 @@
 import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
+import org.openstreetmap.josm.gui.PleaseWaitDialog;
 import org.openstreetmap.josm.tools.DateParser;
 import org.xml.sax.Attributes;
@@ -43,4 +42,10 @@
  */
 public class OsmReader {
+
+	/**
+	 * This is used as (readonly) source for finding missing references when not transferred in the
+	 * file.
+	 */
+	private DataSet references;
 
 	/**
@@ -168,6 +173,6 @@
 	private void createSegments() {
 		for (Entry<OsmPrimitiveData, long[]> e : segs.entrySet()) {
-			Node from = nodes.get(e.getValue()[0]);
-			Node to = nodes.get(e.getValue()[1]);
+			Node from = findNode(e.getValue()[0]);
+			Node to = findNode(e.getValue()[1]);
 			if (from == null || to == null)
 				continue; //TODO: implement support for incomplete nodes.
@@ -179,9 +184,29 @@
 	}
 
+	private Node findNode(long id) {
+	    Node n = nodes.get(id);
+	    if (n != null)
+	    	return n;
+	    for (Node node : references.nodes)
+	    	if (node.id == id)
+	    		return node;
+	    return null;
+    }
+
+	private Segment findSegment(long id) {
+		Segment s = segments.get(id);
+		if (s != null)
+			return s;
+		for (Segment seg : references.segments)
+			if (seg.id == id)
+				return seg;
+		return null;
+	}
+
 	private void createWays() {
 		for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) {
 			Way w = new Way();
 			for (long id : e.getValue()) {
-				Segment s = segments.get(id);
+				Segment s = findSegment(id);
 				if (s == null) {
 					s = new Segment(id); // incomplete line segment
@@ -202,14 +227,16 @@
 	/**
 	 * Parse the given input source and return the dataset.
-	 */
-	public static DataSet parseDataSet(InputStream source, JLabel currentAction, BoundedRangeModel progress) throws SAXException, IOException {
+	 * @param pleaseWaitDlg TODO
+	 */
+	public static DataSet parseDataSet(InputStream source, DataSet ref, PleaseWaitDialog pleaseWaitDlg) throws SAXException, IOException {
 		OsmReader osm = new OsmReader();
+		osm.references = ref;
 
 		// phase 1: Parse nodes and read in raw segments and ways
 		osm.new Parser().parse(new InputStreamReader(source, "UTF-8"));
-		if (progress != null)
-			progress.setValue(0);
-		if (currentAction != null)
-			currentAction.setText(tr("Preparing data..."));
+		if (pleaseWaitDlg != null) {
+			pleaseWaitDlg.progress.setValue(0);
+			pleaseWaitDlg.currentAction.setText(tr("Preparing data..."));
+		}
 		for (Node n : osm.nodes.values())
 			osm.adder.visit(n);
Index: src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 159)
+++ src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 160)
@@ -7,4 +7,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.PleaseWaitDialog;
 
 /**
@@ -20,5 +21,5 @@
 	 * @return An reader reading the input stream (servers answer) or <code>null</code>.
 	 */
-	protected InputStream getInputStream(String urlStr) throws IOException {
+	protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException {
 		urlStr = Main.pref.get("osm-server.url")+"/0.3/" + urlStr;
 		System.out.println("download: "+urlStr);
@@ -30,5 +31,5 @@
 		if (isAuthCancelled() && activeConnection.getResponseCode() == 401)
 			return null;
-		return new ProgressInputStream(activeConnection);
+		return new ProgressInputStream(activeConnection, pleaseWaitDlg);
 	}
 }
Index: src/org/openstreetmap/josm/io/ProgressInputStream.java
===================================================================
--- src/org/openstreetmap/josm/io/ProgressInputStream.java	(revision 159)
+++ src/org/openstreetmap/josm/io/ProgressInputStream.java	(revision 160)
@@ -5,5 +5,5 @@
 import java.net.URLConnection;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.PleaseWaitDialog;
 
 /**
@@ -17,14 +17,18 @@
 	private int lastDialogUpdate = 0;
 	private final URLConnection connection;
+	private PleaseWaitDialog pleaseWaitDlg;
 
-	public ProgressInputStream(URLConnection con) throws IOException {
+	public ProgressInputStream(URLConnection con, PleaseWaitDialog pleaseWaitDlg) throws IOException {
 		this.connection = con;
 		this.in = con.getInputStream();
 		int contentLength = con.getContentLength();
+		this.pleaseWaitDlg = pleaseWaitDlg;
+		if (pleaseWaitDlg == null)
+			return;
 		if (contentLength > 0)
-			Main.pleaseWaitDlg.progress.setMaximum(contentLength);
+			pleaseWaitDlg.progress.setMaximum(contentLength);
 		else
-			Main.pleaseWaitDlg.progress.setMaximum(0);
-		Main.pleaseWaitDlg.progress.setValue(0);
+			pleaseWaitDlg.progress.setMaximum(0);
+		pleaseWaitDlg.progress.setValue(0);
 	}
 
@@ -52,6 +56,9 @@
 	 */
 	private void advanceTicker(int amount) {
-		if (Main.pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1)
-			Main.pleaseWaitDlg.progress.setMaximum(connection.getContentLength());
+		if (pleaseWaitDlg == null)
+			return;
+
+		if (pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1)
+			pleaseWaitDlg.progress.setMaximum(connection.getContentLength());
 
 		readSoFar += amount;
@@ -60,8 +67,8 @@
 			lastDialogUpdate++;
 			String progStr = " "+readSoFar/1024+"/";
-			progStr += (Main.pleaseWaitDlg.progress.getMaximum()==0) ? "??? KB" : (Main.pleaseWaitDlg.progress.getMaximum()/1024)+" KB";
-			Main.pleaseWaitDlg.progress.setValue(readSoFar);
+			progStr += (pleaseWaitDlg.progress.getMaximum()==0) ? "??? KB" : (pleaseWaitDlg.progress.getMaximum()/1024)+" KB";
+			pleaseWaitDlg.progress.setValue(readSoFar);
 
-			String cur = Main.pleaseWaitDlg.currentAction.getText();
+			String cur = pleaseWaitDlg.currentAction.getText();
 			int i = cur.indexOf(' ');
 			if (i != -1)
@@ -69,5 +76,5 @@
 			else
 				cur += progStr;
-			Main.pleaseWaitDlg.currentAction.setText(cur);
+			pleaseWaitDlg.currentAction.setText(cur);
 		}
 	}
Index: src/org/openstreetmap/josm/tools/SearchCompiler.java
===================================================================
--- src/org/openstreetmap/josm/tools/SearchCompiler.java	(revision 159)
+++ src/org/openstreetmap/josm/tools/SearchCompiler.java	(revision 160)
@@ -120,4 +120,11 @@
 	}
 
+	private static class Incomplete extends Match {
+		@Override public boolean match(OsmPrimitive osm) {
+			return osm instanceof Way && ((Way)osm).isIncomplete();
+		}
+		@Override public String toString() {return "modified";}
+	}
+	
 	public static Match compile(String searchStr) {
 		return new SearchCompiler().parse(new PushbackReader(new StringReader(searchStr)));
@@ -195,9 +202,9 @@
 			if (value.equals("modified"))
 				c = new Modified();
+			else if (value.equals("incomplete"))
+				c = new Incomplete();
 			else
 				c = new Any(value);
-			if (notValue)
-				return new Not(c);
-			return c;
+			return notValue ? new Not(c) : c;
 		}
 		Match c;
