Index: branch/0.5/src/org/openstreetmap/josm/actions/CombineWayAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 329)
@@ -10,4 +10,7 @@
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.ArrayList;
 import java.util.Map;
 import java.util.Set;
@@ -15,4 +18,5 @@
 import java.util.TreeSet;
 import java.util.Map.Entry;
+import java.util.HashSet;
 
 import javax.swing.Box;
@@ -31,4 +35,6 @@
 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.data.osm.NodePair;
 import org.openstreetmap.josm.tools.GBC;
 
@@ -42,5 +48,5 @@
 	public CombineWayAction() {
 		super(tr("Combine Way"), "combineway", tr("Combine several ways into one."), KeyEvent.VK_C, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
-		DataSet.listeners.add(this);
+		DataSet.selListeners.add(this);
 	}
 
@@ -68,10 +74,64 @@
 		}
 		
-		Way oldWay = selectedWays.poll();
-		Way newWay = new Way(oldWay);
-		LinkedList<Command> cmds = new LinkedList<Command>();
+		// Battle plan:
+		//  1. Split the ways into small chunks of 2 nodes and weed out
+		//	   duplicates.
+		//  2. Take a chunk and see if others could be appended or prepended,
+		//	   if so, do it and remove it from the list of remaining chunks.
+		//	   Rather, rinse, repeat.
+		//  3. If this algorithm does not produce a single way,
+		//     complain to the user.
+		//  4. Profit!
 		
-		for (Way w : selectedWays)
-			newWay.segments.addAll(w.segments);
+		HashSet<NodePair> chunkSet = new HashSet<NodePair>();
+		for (Way w : selectedWays) {
+			if (w.nodes.size() == 0) continue;
+			Node lastN = null;
+			for (Node n : w.nodes) {
+				if (lastN == null) {
+					lastN = n;
+					continue;
+				}
+				chunkSet.add(new NodePair(lastN, n));
+				lastN = n;
+			}
+		}
+		LinkedList<NodePair> chunks = new LinkedList<NodePair>(chunkSet);
+
+		if (chunks.isEmpty()) {
+			JOptionPane.showMessageDialog(Main.parent, tr("All the ways were empty"));
+			return;
+		}
+
+		List<Node> nodeList = chunks.poll().toArrayList();
+		while (!chunks.isEmpty()) {
+			ListIterator<NodePair> it = chunks.listIterator();
+			boolean foundChunk = false;
+			while (it.hasNext()) {
+				NodePair curChunk = it.next();
+				if (curChunk.a == nodeList.get(nodeList.size() - 1)) { // append
+					nodeList.add(curChunk.b);
+					foundChunk = true;
+				} else if (curChunk.b == nodeList.get(0)) { // prepend
+					nodeList.add(0, curChunk.a);
+					foundChunk = true;
+				}
+				if (foundChunk) {
+					it.remove();
+					break;
+				}
+			}
+			if (!foundChunk) break;
+		}
+
+		if (!chunks.isEmpty()) {
+			JOptionPane.showMessageDialog(Main.parent,
+				tr("Could not combine ways (Hint: ways have to point into the same direction)"));
+			return;
+		}
+
+		Way newWay = new Way(selectedWays.get(0));
+		newWay.nodes.clear();
+		newWay.nodes.addAll(nodeList);
 		
 		// display conflict dialog
@@ -97,8 +157,9 @@
 		}
 
-		cmds.add(new DeleteCommand(selectedWays));
-		cmds.add(new ChangeCommand(oldWay, newWay));
+		LinkedList<Command> cmds = new LinkedList<Command>();
+		cmds.add(new DeleteCommand(selectedWays.subList(1, selectedWays.size())));
+		cmds.add(new ChangeCommand(selectedWays.peek(), newWay));
 		Main.main.undoRedo.add(new SequenceCommand(tr("Combine {0} ways", selectedWays.size()), cmds));
-		Main.ds.setSelected(oldWay);
+		Main.ds.setSelected(selectedWays.peek());
 	}
 
Index: branch/0.5/src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/DownloadIncompleteAction.java	(revision 329)
@@ -1,80 +1,0 @@
-// License: GPL. Copyright 2007 by Immanuel Scholz and others
-package org.openstreetmap.josm.actions;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.trn;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashSet;
-
-import javax.swing.JOptionPane;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
-import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.io.IncompleteDownloader;
-import org.xml.sax.SAXException;
-
-/**
- * Action that opens a connection to the osm server and download map data.
- *
- * An dialog is displayed asking the user to specify a rectangle to grab.
- * The url and account settings from the preferences are used.
- *
- * @author imi
- */
-public class DownloadIncompleteAction extends JosmAction {
-
-	/**
-	 * Open the download dialog and download the data.
-	 * Run in the worker thread.
-	 */
-	private final class DownloadTask extends PleaseWaitRunnable {
-		private IncompleteDownloader reader;
-
-		private DownloadTask(Collection<Way> toDownload) {
-			super(trn("Downloading {0} way", "Downloading {0} ways", toDownload.size(), toDownload.size()));
-			reader = new IncompleteDownloader(toDownload);
-		}
-
-		@Override public void realRun() throws IOException, SAXException {
-			reader.parse();
-		}
-
-		@Override protected void finish() {
-			MergeVisitor merger = new MergeVisitor(Main.ds, reader.data);
-			for (OsmPrimitive osm : reader.data.allPrimitives())
-				osm.visit(merger);
-			Main.parent.repaint();
-		}
-
-		@Override protected void cancel() {
-			reader.cancel();
-		}
-	}
-
-	public DownloadIncompleteAction() {
-		super(tr("Download incomplete objects"), "downloadincomplete", tr("Download all (selected) incomplete ways from the OSM server."), KeyEvent.VK_D, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK, true);
-	}
-
-	public void actionPerformed(ActionEvent e) {
-		Collection<Way> ways = new HashSet<Way>();
-		for (Way w : Main.ds.ways)
-			if (w.isIncomplete() && w.selected)
-				ways.add(w);
-		if (ways.isEmpty()) {
-			JOptionPane.showMessageDialog(Main.parent, tr("Please select an incomplete way."));
-			return;
-		}
-		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(ways);
-		Main.worker.execute(task);
-	}
-}
Index: branch/0.5/src/org/openstreetmap/josm/actions/ReverseSegmentAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/ReverseSegmentAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/ReverseSegmentAction.java	(revision 329)
@@ -1,59 +1,0 @@
-// License: GPL. Copyright 2007 by Immanuel Scholz and others
-/**
- * 
- */
-package org.openstreetmap.josm.actions;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.util.Collection;
-import java.util.LinkedList;
-
-import javax.swing.JOptionPane;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.ChangeCommand;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.SequenceCommand;
-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.Visitor;
-
-public final class ReverseSegmentAction extends JosmAction {
-
-    public ReverseSegmentAction() {
-    	super(tr("Reverse segments"), "segmentflip", tr("Reverse the direction of all selected Segments."), KeyEvent.VK_R, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
-    }
-
-	public void actionPerformed(ActionEvent e) {
-    	final Collection<Segment> sel = new LinkedList<Segment>();
-    	new Visitor(){
-			public void visit(Node n)    {}
-			public void visit(Segment s) {sel.add(s);}
-			public void visit(Way w)     {sel.addAll(w.segments);}
-			public void visitAll() {
-				for (OsmPrimitive osm : Main.ds.getSelected())
-					osm.visit(this);
-			}
-    	}.visitAll();
-
-    	if (sel.isEmpty()) {
-    		JOptionPane.showMessageDialog(Main.parent, tr("Please select at least one segment."));
-    		return;
-    	}
-    	Collection<Command> c = new LinkedList<Command>();
-    	for (Segment s : sel) {
-    		Segment snew = new Segment(s);
-    		Node n = snew.from;
-    		snew.from = snew.to;
-    		snew.to = n;
-    		c.add(new ChangeCommand(s, snew));
-    	}
-    	Main.main.undoRedo.add(new SequenceCommand(tr("Reverse Segments"), c));
-    	Main.map.repaint();
-    }
-}
Index: branch/0.5/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 329)
@@ -16,4 +16,5 @@
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 import java.util.Map.Entry;
 
@@ -27,7 +28,7 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
 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.NameVisitor;
@@ -35,57 +36,8 @@
 
 /**
- * Splits a way into multiple ways (all identical except the segments
- * belonging to the way).
+ * Splits a way into multiple ways (all identical except for their node list).
  * 
- * Various split modes are used depending on what is selected.
- * 
- * 1. One or more NODES (and, optionally, also one way) selected:
- * 
- * (All nodes must be part of the same way. If a way is also selected, that way
- * must contain all selected nodes.)
- * 
- * Way is split AT the node(s) into contiguous ways. If the original contained
- * one or more parts that were not reachable from any of the nodes, they form an
- * extra new way. Examples (numbers are unselected nodes, letters are selected
- * nodes)
- * 
- * 1---A---2  becomes  1---A and A---2
- * 
- * 1---A---2---B---3  becomes  1---A and A---2---B and B---3
- *  
- *     2                    
- *     |                   
- * 1---A---3  becomes  1---A and 2---A and A---3
- *
- * 1---A---2  3---4  becomes  1---A and A---2 and 3---4
- * 
- * If the selected node(s) do not clearly define the way that is to be split,
- * then the way must be selected for disambiguation (e.g. you have two ways,
- * 1---2---3 and 4---2---5, and select node 2, then you must also select the 
- * way you want to split).
- * 
- * This function will result in at least two ways, unless the selected node is
- * at the end of the way AND the way is contiguous, which will lead to an error
- * message.
- * 
- * After executing the operation, the selection will be cleared.
- * 
- * 2. One or more SEGMENTS (and, optionally, also one way) selected:
- * 
- * (All segments must be part of the same way)
- * 
- * The way is split in a fashion that makes a new way from the selected segments,
- * i.e. the selected segments are removed from the way to form a new one.
- * 
- * This function will result in exactly two ways. 
- * 
- * If splitting the segments out of the way makes a non-contiguous part from
- * something that was contiguous before, the action is aborted and an error
- * message is shown.
- * 
- * 3. Exactly one WAY selected
- * 
- * If the way is contiguous, you will get an error message. If the way is not
- * contiguous it is split it into 2...n contiguous ways.
+ * Ways are just split at the selected nodes.  The nodes remain in their
+ * original order.  Selected nodes at the end of a way are ignored.
  */
 
@@ -94,5 +46,4 @@
 	private Way selectedWay;
 	private List<Node> selectedNodes;
-	private List<Segment> selectedSegments;
 
 	/**
@@ -101,5 +52,5 @@
 	public SplitWayAction() {
 		super(tr("Split Way"), "splitway", tr("Split a way at the selected node."), KeyEvent.VK_P, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
-		DataSet.listeners.add(this);
+		DataSet.selListeners.add(this);
 	}
 
@@ -121,5 +72,4 @@
 		selectedWay = null;
 		selectedNodes = null;
-		selectedSegments = null;
 
 		Visitor splitVisitor = new Visitor(){
@@ -129,12 +79,10 @@
 				selectedNodes.add(n);
             }
-			public void visit(Segment s) {
-				if (selectedSegments == null)
-					selectedSegments = new LinkedList<Segment>();
-				selectedSegments.add(s);
-            }
 			public void visit(Way w) {
 				selectedWay = w;
             }
+			public void visit(Relation e) {
+				// enties are not considered
+			}
 		};
 		
@@ -148,6 +96,6 @@
 			for (Node n : selectedNodes) {
 				for (Way w : Main.ds.ways) {
-					for (Segment s : w.segments) {
-						if (n.equals(s.from) || n.equals(s.to)) {
+					for (Node wn : w.nodes) {
+						if (n.equals(wn)) {
 							Integer old = wayOccurenceCounter.get(w);
 							wayOccurenceCounter.put(w, (old == null) ? 1 : old+1);
@@ -183,7 +131,6 @@
 
 			HashSet<Node> nds = new HashSet<Node>(selectedNodes);
-			for (Segment s : selectedWay.segments) {
-				nds.remove(s.from);
-				nds.remove(s.to);
+			for (Node n : selectedWay.nodes) {
+				nds.remove(n);
 			}
 			if (!nds.isEmpty()) {
@@ -193,57 +140,4 @@
 				return;
 			}
-
-			// If only segments are selected, guess which way to use.
-		} else if (selectedWay == null && selectedSegments != null) {
-
-			HashMap<Way, Integer> wayOccurenceCounter = new HashMap<Way, Integer>();
-			for (Segment s : selectedSegments) {
-				for (Way w : Main.ds.ways) {
-					if (w.segments.contains(s)) {
-						Integer old = wayOccurenceCounter.get(w);
-						wayOccurenceCounter.put(w, (old == null) ? 1 : old+1);
-						break;
-					}
-				}
-			}
-			if (wayOccurenceCounter.isEmpty()) {
-				JOptionPane.showMessageDialog(Main.parent, 
-						trn("The selected segment is not part of any way.",
-								"The selected segments are not part of any way.", selectedSegments.size()));
-				return;
-			}
-
-			for (Entry<Way, Integer> entry : wayOccurenceCounter.entrySet()) {
-				if (entry.getValue().equals(selectedSegments.size())) {
-					if (selectedWay != null) {
-						JOptionPane.showMessageDialog(Main.parent,
-								trn("There is more than one way using the segment you selected. Please select the way also.",
-										"There is more than one way using the segments you selected. Please select the way also.", selectedSegments.size()));
-						return;
-					}
-					selectedWay = entry.getKey();
-				}
-			}
-
-			if (selectedWay == null) {
-				JOptionPane.showMessageDialog(Main.parent, tr("The selected segments do not share the same way."));
-				return;
-			}
-
-			// If a way and segments are selected, verify that the segments are part of the way.
-		} else if (selectedWay != null && selectedSegments != null) {
-
-			if (!selectedWay.segments.containsAll(selectedSegments)) {
-				JOptionPane.showMessageDialog(Main.parent, 
-						trn("The selected way does not contain the selected segment.",
-								"The selected way does not contain all the selected segments.", selectedSegments.size()));
-				return;
-			}
-		}
-
-		// finally check if the selected way is complete.
-		if (selectedWay.isIncomplete()) {
-			JOptionPane.showMessageDialog(Main.parent, tr("Warning: This way is incomplete. Try to download it before splitting."));
-			return;
 		}
 
@@ -261,17 +155,15 @@
 	private boolean checkSelection(Collection<? extends OsmPrimitive> selection) {
 		boolean way = false;
-		boolean segment = false;
 		boolean node = false;
 		for (OsmPrimitive p : selection) {
-			if (p instanceof Way && !way)
+			if (p instanceof Way && !way) {
 				way = true;
-			else if (p instanceof Node && !segment)
+			} else if (p instanceof Node) {
 				node = true;
-			else if (p instanceof Segment && !node)
-				segment = true;
-			else
+			} else {
 				return false;
 		}
-		return way || segment || node;
+		}
+		return node;
 	}
 
@@ -279,174 +171,54 @@
 	 * Split a way into two or more parts, starting at a selected node.
 	 * 
+	 * FIXME: what do the following "arguments" refer to?
 	 * @param way the way to split
 	 * @param nodes the node(s) to split the way at; must be part of the way.
 	 */
 	private void splitWay() {
-
-		// The basic idea is to first divide all segments forming this way into 
-		// groups, and later form new ways according to the groups. Initally, 
-		// all segments are copied into allSegments, and then gradually removed
-		// from there as new groups are built.
-
-		LinkedList<Segment> allSegments = new LinkedList<Segment>();
-		allSegments.addAll(selectedWay.segments);
-		List<List<Segment>> segmentSets = new ArrayList<List<Segment>>();
-
-		if (selectedNodes != null) {
-
-			// This is the "split at node" mode.
-
-			boolean split = true;
-			Segment splitSeg = null;
-			while (split) {
-				split = false;
-
-				// Look for a "split segment". A split segment is any segment
-				// that touches one of the split nodes and has not yet been
-				// assigned to one of the segment groups.
-				for (Segment s : allSegments) {
-					for (Node node : selectedNodes) {
-						if (s.from.equals(node) || s.to.equals(node)) {
-							split = true;
-							splitSeg = s;
-							break;
-						}
-					}
-					if (split)
-						break;
+		// We take our way's list of nodes and copy them to a way chunk (a
+		// list of nodes).  Whenever we stumble upon a selected node, we start
+		// a new way chunk.
+
+		Set<Node> nodeSet = new HashSet<Node>(selectedNodes);
+		List<List<Node>> wayChunks = new LinkedList<List<Node>>();
+		List<Node> currentWayChunk = new ArrayList<Node>();
+		wayChunks.add(currentWayChunk);
+
+		Iterator<Node> it = selectedWay.nodes.iterator();
+		while (it.hasNext()) {
+			Node currentNode = it.next();
+			boolean atEndOfWay = currentWayChunk.isEmpty() || !it.hasNext();
+			currentWayChunk.add(currentNode);
+			if (nodeSet.contains(currentNode) && !atEndOfWay) {
+				currentWayChunk = new ArrayList<Node>();
+				currentWayChunk.add(currentNode);
+				wayChunks.add(currentWayChunk);
 				}
-
-				// If a split segment was found, move this segment and all segments
-				// connected to it into a new segment group, stopping only if we
-				// reach another split node. Segment moving is done recursively by
-				// the moveSegments method.
-				if (split) {
-					LinkedList<Segment> subSegments = new LinkedList<Segment>();
-					moveSegments(allSegments, subSegments, splitSeg, selectedNodes);
-					segmentSets.add(subSegments);
-				}
-
-				// The loop continues until no more split segments were found.
-				// Nb. not all segments touching a split node are split segments; 
-				// e.g. 
-				//
-				//     2       4
-				//     |       |
-				// 1---A---3---C---5
-				//
-				// This way will be split into 5 ways (1---A,2---A,A---3---C,4---C,
-				// C---5). Depending on which is processed first, either A---3 becomes
-				// a split segment and 3---C is moved as a connecting segment, or vice
-				// versa. The result is, of course, the same but this explains why we
-				// cannot simply start a new way for each segment connecting to a split
-				// node.
-			}
-
-		} else if (selectedSegments != null) {
-
-			// This is the "split segments" mode. It is quite easy as the segments to
-			// remove are already explicitly selected, but some restrictions have to 
-			// be observed to make sure that no non-contiguous parts are created.
-
-			// first create a "scratch" copy of the full segment list and move all
-			// segments connected to the first selected segment into a temporary list.
-			LinkedList<Segment> copyOfAllSegments = new LinkedList<Segment>(allSegments);
-			LinkedList<Segment> partThatContainsSegments = new LinkedList<Segment>();
-			moveSegments(copyOfAllSegments, partThatContainsSegments, selectedSegments.get(0), null);
-
-			// this list must now contain ALL selected segments; otherwise, segments
-			// from unconnected parts of the way have been selected and this is not allowed
-			// as it would create a new non-contiguous way.
-			if (!partThatContainsSegments.containsAll(selectedSegments)) {
-				JOptionPane.showMessageDialog(Main.parent, tr("The selected segments are not in the same contiguous part of the way."));				
-				return;		
-			}
-
-			// if the contiguous part that contains the segments becomes non-contiguous
-			// after the removal of the segments, that is also an error.
-			partThatContainsSegments.removeAll(selectedSegments);
-			if (!partThatContainsSegments.isEmpty()) {
-				LinkedList<Segment> contiguousSubpart = new LinkedList<Segment>();
-				moveSegments(partThatContainsSegments, contiguousSubpart, partThatContainsSegments.get(0), null);
-				// if partThatContainsSegments was contiguous before, it will now be empty as all segments
-				// connected to the first segment therein have been moved
-				if (!partThatContainsSegments.isEmpty()) {
-					JOptionPane.showMessageDialog(Main.parent, tr("Removing the selected segments would make a part of the way non-contiguous."));				
-					return;				
-				}
-			}
-
-			ArrayList<Segment> subSegments = new ArrayList<Segment>();
-			subSegments.addAll(selectedSegments);
-			allSegments.removeAll(selectedSegments);
-			segmentSets.add(subSegments);
-
-		} else {
-
-			// This is the "split way into contiguous parts" mode.
-			// We use a similar mechanism to splitting at nodes, but we do not 
-			// select split segments. Instead, we randomly grab a segment out 
-			// of the way and move all connecting segments to a new group. If
-			// segments remain in the original way, we repeat the procedure.
-
-			while (!allSegments.isEmpty()) {
-				LinkedList<Segment> subSegments = new LinkedList<Segment>();
-				moveSegments(allSegments, subSegments, allSegments.get(0), null);
-				segmentSets.add(subSegments);
-			}			
-		}
-
-		// We now have a number of segment groups.
-
-		// If segments remain in allSegments, this means that they were not reachable
-		// from any of the split nodes, and they will be made into an extra way.
-		if (!allSegments.isEmpty()) {
-			segmentSets.add(allSegments);
-		}
-
-		// If we do not have at least two parts, then the way was circular or the node(s)
-		// were at one end of the way. User error ;-)
-		if (segmentSets.size() < 2) {
-			if (selectedNodes != null) {
-				JOptionPane.showMessageDialog(Main.parent, tr("The way cannot be split at the selected node. (Hint: To split circular ways, select two nodes.)"));
-			} else {
-				JOptionPane.showMessageDialog(Main.parent, tr("The way cannot be split because it is contiguous. (Hint: To split at a node, select that node.)"));				
-			}
+			}
+
+		if (wayChunks.size() < 2) {
+			JOptionPane.showMessageDialog(Main.parent, tr("The way cannot be split at the selected nodes. (Hint: Select nodes in the middle of the way.)"));
 			return;
 		}
 
-		// sort the list of segment lists according to their number of elements, so that
-		// the biggest part of the way comes first. That way, we will "change" the largest
-		// part of the way by removing a few segments, and "add" new, smaller ways; looks
-		// nicer.
-		Collections.sort(segmentSets, new Comparator<Collection<Segment>>() {
-			public int compare(Collection<Segment> a, Collection<Segment> b) {
-				if (a.size() < b.size())
-					return 1;
-				if (b.size() < a.size())
-					return -1;
-				return 0;
-			}
-		});
-
-		// build a list of commands, and also a list of ways
-		Collection<Command> commandList = new ArrayList<Command>(segmentSets.size());
-		Collection<Way> newSelection = new ArrayList<Way>(segmentSets.size());
-		Iterator<List<Segment>> segsIt = segmentSets.iterator();
+		// build a list of commands, and also a new selection list
+		Collection<Command> commandList = new ArrayList<Command>(wayChunks.size());
+		Collection<Way> newSelection = new ArrayList<Way>(wayChunks.size());
 		
-		// the first is always a change to the existing way;
+		Iterator<List<Node>> chunkIt = wayChunks.iterator();
+		
+		// First, change the original way
 		Way changedWay = new Way(selectedWay);
-		changedWay.segments.clear();
-		changedWay.segments.addAll(segsIt.next());
+		changedWay.nodes.clear();
+		changedWay.nodes.addAll(chunkIt.next());
 		commandList.add(new ChangeCommand(selectedWay, changedWay));
 		newSelection.add(selectedWay);
 
-		// and commands 1...n are additions of new ways.
-		while (segsIt.hasNext()) {
+		// Second, create new ways
+		while (chunkIt.hasNext()) {
 			Way wayToAdd = new Way();
 			if (selectedWay.keys != null)
 				wayToAdd.keys = new HashMap<String, String>(selectedWay.keys);
-			wayToAdd.segments.clear();
-			wayToAdd.segments.addAll(segsIt.next());
+			wayToAdd.nodes.addAll(chunkIt.next());
 			commandList.add(new AddCommand(wayToAdd));
 			newSelection.add(wayToAdd);
@@ -455,5 +227,8 @@
 		NameVisitor v = new NameVisitor();
 		v.visit(selectedWay);
-		Main.main.undoRedo.add(new SequenceCommand(tr("Split way {0} into {1} parts",v.name, segmentSets.size()), commandList));
+		Main.main.undoRedo.add(
+			new SequenceCommand(tr("Split way {0} into {1} parts",
+				v.name, wayChunks.size()),
+			commandList));
 		Main.ds.setSelected(newSelection);
 	}
@@ -465,41 +240,3 @@
 		setEnabled(checkSelection(newSelection));
 	}
-
-	/**
-	 * Move contiguous segments from one collection to another. The given segment is moved first, and
-	 * then the procedure is recursively called for all segments that connect to the first segment at
-	 * either end.
-	 * 
-	 * @param source the source collection
-	 * @param destination the destination collection
-	 * @param start the first segment to be moved
-	 * @param stopNodes collection of nodes which should be considered end points for moving (may be null).
-	 */
-	private void moveSegments(Collection<Segment> source, LinkedList<Segment> destination, Segment start, Collection<Node> stopNodes) {
-		source.remove(start);
-		if (destination.isEmpty() || destination.iterator().next().from.equals(start.to))
-			destination.addFirst(start);
-		else
-			destination.addLast(start);
-		Segment moveSeg = start;
-		while(moveSeg != null) {
-			moveSeg = null;
-
-			for (Node node : new Node[] { start.from, start.to }) {
-				if (stopNodes != null && stopNodes.contains(node))
-					continue;
-				for (Segment sourceSeg : source) {
-					if (sourceSeg.from.equals(node) || sourceSeg.to.equals(node)) {
-						moveSeg = sourceSeg;
-						break;
-					}
-				}
-				if (moveSeg != null)
-					break;
-			}
-			if (moveSeg != null) {
-				moveSegments(source, destination, moveSeg, stopNodes);
-			}
-		}
-	}
 }
Index: branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 329)
@@ -24,6 +24,6 @@
 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.WaySegment;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -33,4 +33,6 @@
  * and there is it. Nothing more, nothing less.
  *
+ * FIXME: "nothing more, nothing less" is a bit out-of-date
+ *
  * Newly created nodes are selected. Shift modifier does not cancel the old
  * selection as usual.
@@ -41,5 +43,5 @@
 public class AddNodeAction extends MapMode {
 
-	enum Mode {node, nodesegment, autonode}
+	enum Mode {node, nodeway, autonode}
 	private final Mode mode;
 
@@ -49,6 +51,6 @@
 			putValue("help", "Action/AddNode");
 			actions.add(new AddNodeAction(mf,tr("Add node"), Mode.node, tr("Add a new node to the map")));
-			actions.add(new AddNodeAction(mf, tr("Add node into segment"), Mode.nodesegment,tr( "Add a node into an existing segment")));
-			actions.add(new AddNodeAction(mf, tr("Add node and connect"), Mode.autonode,tr( "Add a node and connect it to the selected node (with CTRL: add node into segment; with SHIFT: re-use existing node)")));
+			actions.add(new AddNodeAction(mf, tr("Add node into way"), Mode.nodeway,tr( "Add a node into an existing way")));
+			actions.add(new AddNodeAction(mf, tr("Add node and connect"), Mode.autonode,tr( "Add a node and connect it to the selected node (with CTRL: add node into way; with SHIFT: re-use existing node)")));
 			setCurrent(0);
 		}
@@ -83,7 +85,5 @@
 	 * position.
 	 *
-	 * If in nodesegment mode, add the node to the line segment by splitting the
-	 * segment. The new created segment will be inserted in every way the segment
-	 * was part of.
+	 * If in nodeway mode, insert the node into the way. 
 	 */
 	@Override public void mouseClicked(MouseEvent e) {
@@ -98,18 +98,22 @@
 
 		Command c = new AddCommand(n);
-		if (mode == Mode.nodesegment) {
-			Segment s = Main.map.mapView.getNearestSegment(e.getPoint());
-			if (s == null)
+		if (mode == Mode.nodeway) {
+			WaySegment ws = Main.map.mapView.getNearestWaySegment(e.getPoint());
+			if (ws == null)
 				return;
 			
 			// see if another segment is also near
-			Segment other = Main.map.mapView.getNearestSegment(e.getPoint(), Collections.singleton(s));
+			WaySegment other = Main.map.mapView.getNearestWaySegment(e.getPoint(),
+				Collections.singleton(ws));
+
+			Node n1 = ws.way.nodes.get(ws.lowerIndex),
+				n2 = ws.way.nodes.get(ws.lowerIndex + 1);
 
 			if (other == null && (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) == 0) {
 				// moving the new point to the perpendicular point
-				// FIXME: when two segments are split, should move the new point to the
+				// FIXME: when two way segments are split, should move the new point to the
 				// intersection point!
-				EastNorth A = s.from.eastNorth;
-				EastNorth B = s.to.eastNorth;
+				EastNorth A = n1.eastNorth;
+				EastNorth B = n2.eastNorth;
 				double ab = A.distance(B);
 				double nb = n.eastNorth.distance(B);
@@ -124,11 +128,11 @@
 			
 			// split the first segment
-			splitSegmentAtNode(s, n, cmds);
+			splitWaySegmentAtNode(ws, n, cmds);
 			
 			// if a second segment was found, split that as well
-			if (other != null) splitSegmentAtNode(other, n, cmds);
+			if (other != null) splitWaySegmentAtNode(other, n, cmds);
 
 			c = new SequenceCommand(tr((other == null) ? 
-				"Add node into segment" : "Add common node into two segments"), cmds);
+				"Add node into way" : "Add common node into two ways"), cmds);
 		}
 
@@ -136,10 +140,11 @@
 		if (mode == Mode.autonode) {
 
-			Segment insertInto = null;
+			WaySegment insertInto = null;
 			Node reuseNode = null;
 			
-			// If CTRL is held, insert the node into a potentially existing segment
+			// If CTRL is held, insert the node into a potentially existing way segment
 			if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0) {
-				insertInto = Main.map.mapView.getNearestSegment(e.getPoint());
+				insertInto = Main.map.mapView.getNearestWaySegment(e.getPoint());
+				if (insertInto == null) System.err.println("Couldn't find nearby way segment");
 				if (insertInto == null)
 					return;
@@ -150,5 +155,5 @@
 			// continuation of the "add node and connect" stuff)
 			else if ((e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0) {
-				OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint(), false);
+				OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint());
 				if (clicked == null || !(clicked instanceof Node))
 					return;
@@ -159,8 +164,10 @@
 			if (selection.size() == 1 && selection.iterator().next() instanceof Node) {
 				Node n1 = (Node)selection.iterator().next();
+
 				Collection<Command> cmds = new LinkedList<Command>();
 				
 				if (reuseNode != null) {
 					// in re-use node mode, n1 must not be identical to clicked node
+					if (n1 == reuseNode) System.err.println("n1 == reuseNode");
 					if (n1 == reuseNode) return;
 					// replace newly created node with existing node
@@ -171,25 +178,33 @@
 				}
 				
-				Segment s = new Segment(n1, n);
-				
+				/* Keep track of the way we change, it might be the same into
+				 * which we insert the node.
+				 */
+				Way newInsertInto = null;
 				if (insertInto != null)
-					splitSegmentAtNode(insertInto, n, cmds);
-				
-				cmds.add(new AddCommand(s));			
+					newInsertInto = splitWaySegmentAtNode(insertInto, n, cmds);
 
 				Way way = getWayForNode(n1);
-				if (way != null) {
-					Way newWay = new Way(way);
-					if (way.segments.get(0).from == n1) {
-						Node tmp = s.from;
-						s.from = s.to;
-						s.to = tmp;
-						newWay.segments.add(0, s);
-					} else
-						newWay.segments.add(s);
-					cmds.add(new ChangeCommand(way, newWay));
-				}
-
-				c = new SequenceCommand(tr((insertInto == null) ? "Add node and connect" : "Add node into segment and connect"), cmds);
+				if (way == null) {
+					way = new Way();
+					way.nodes.add(n1);
+					cmds.add(new AddCommand(way));
+				} else {
+					if (insertInto != null && way == insertInto.way) {
+						way = newInsertInto;
+					} else {
+						Way wnew = new Way(way);
+						cmds.add(new ChangeCommand(way, wnew));
+						way = wnew;
+					}
+				}
+
+				if (way.nodes.get(way.nodes.size() - 1) == n1) {
+					way.nodes.add(n);
+				} else {
+					way.nodes.add(0, n);
+				}
+
+				c = new SequenceCommand(tr((insertInto == null) ? "Add node and connect" : "Add node into way and connect"), cmds);
 			}	
 		}		
@@ -201,5 +216,5 @@
 	
 	/**
-	 * @return If the node is part of exactly one way, return this. 
+	 * @return If the node is the end of exactly one way, return this. 
 	 * 	<code>null</code> otherwise.
 	 */
@@ -207,42 +222,20 @@
 		Way way = null;
 		for (Way w : Main.ds.ways) {
-			for (Segment s : w.segments) {
-				if (s.from == n || s.to == n) {
+			int i = w.nodes.indexOf(n);
+			if (i == -1) continue;
+			if (i == 0 || i == w.nodes.size() - 1) {
 					if (way != null)
 						return null;
-					if (s.from == s.to)
-						return null;
 					way = w;
 				}
 			}
-		}
 		return way;
 	}
 	
-	private void splitSegmentAtNode(Segment s, Node n, Collection<Command> cmds) {
-		Segment s1 = new Segment(s);
-		s1.to = n;
-		Segment s2 = new Segment(s.from, s.to);
-		s2.from = n;
-		if (s.keys != null)
-			s2.keys = new HashMap<String, String>(s.keys);
-
-		cmds.add(new ChangeCommand(s, s1));
-		cmds.add(new AddCommand(s2));
-
-		// Add the segment to every way
-		for (Way wold : Main.ds.ways) {
-			if (wold.segments.contains(s)) {
-				Way wnew = new Way(wold);
-				Collection<Segment> segs = new ArrayList<Segment>(wnew.segments);
-				wnew.segments.clear();
-				for (Segment waySeg : segs) {
-					wnew.segments.add(waySeg);
-					if (waySeg == s)
-						wnew.segments.add(s2);
-				}
-				cmds.add(new ChangeCommand(wold, wnew));
-			}
-		}
+	private Way splitWaySegmentAtNode(WaySegment ws, Node n, Collection<Command> cmds) {
+		Way wnew = new Way(ws.way);
+		wnew.nodes.add(ws.lowerIndex + 1, n);
+		cmds.add(new ChangeCommand(ws.way, wnew));
+		return wnew;
 	}
 }
Index: branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddSegmentAction.java	(revision 329)
@@ -15,7 +15,8 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.ChangeCommand;
 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.gui.MapFrame;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -51,7 +52,7 @@
 	 */
 	public AddSegmentAction(MapFrame mapFrame) {
-		super(tr("Add segment"), 
+		super(tr("Connect two nodes"), 
 				"addsegment", 
-				tr("Add a segment between two nodes."), 
+				tr("Connect two nodes using ways."), 
 				KeyEvent.VK_G, 
 				mapFrame, 
@@ -72,5 +73,7 @@
 	}
 
-	
+	/**
+	 * Called when user hits space bar while dragging.
+	 */
 	@Override public void actionPerformed(ActionEvent e) {
 		super.actionPerformed(e);
@@ -85,10 +88,9 @@
 			return;
 
-		OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint(), true);
-		if (clicked == null || !(clicked instanceof Node))
-			return;
+		Node clicked = Main.map.mapView.getNearestNode(e.getPoint());
+		if (clicked == null) return;
 
 		drawHint(false);
-		first = second = (Node)clicked;
+		first = second = clicked;
 	}
 
@@ -101,11 +103,9 @@
 			return;
 
-		OsmPrimitive clicked = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
-		if (clicked == null || clicked == second || !(clicked instanceof Node))
-			return;
+		Node hovered = Main.map.mapView.getNearestNode(e.getPoint());
+		if (hovered == second) return;
 
 		drawHint(false);
-
-		second = (Node)clicked;
+		second = hovered;
 		drawHint(true);
 	}
@@ -116,7 +116,26 @@
 	@Override public void mouseReleased(MouseEvent e) {
 		if (e.getButton() == MouseEvent.BUTTON1) {
+			drawHint(false);
 			makeSegment();
-			first = null; // release segment drawing
+			first = null;
 		}
+	}
+
+	/**
+	 * @return If the node is the end of exactly one way, return this. 
+	 * 	<code>null</code> otherwise.
+	 */
+	private Way getWayForNode(Node n) {
+		Way way = null;
+		for (Way w : Main.ds.ways) {
+			int i = w.nodes.indexOf(n);
+			if (i == -1) continue;
+			if (i == 0 || i == w.nodes.size() - 1) {
+				if (way != null)
+					return null;
+				way = w;
+			}
+		}
+		return way;
 	}
 
@@ -126,27 +145,43 @@
 	 */
 	private void makeSegment() {
-		if (first == null || second == null) {
-			first = null;
-			second = null;
-			return;
-		}
-
-		drawHint(false);
+		Node n1 = first;
+		Node n2 = second;
 		
-		Node start = first;
-		Node end = second;
+		// this is to allow continued segment drawing by hitting the space bar
+		// at every intermediate node
 		first = second;
 		second = null;
+
+		if (n1 == null || n2 == null || n1 == n2) return;
+
+		Way w = getWayForNode(n1);
+		Way wnew;
+		Collection<OsmPrimitive> sel = Main.ds.getSelected();
 		
-		if (start != end) {
-			// try to find a segment
-			for (Segment ls : Main.ds.segments)
-				if (!ls.deleted && ((start == ls.from && end == ls.to) || (end == ls.from && start == ls.to)))
-					return; // already a segment here - be happy, do nothing.
-
-			Segment ls = new Segment(start, end);
-			Main.main.undoRedo.add(new AddCommand(ls));
-			Collection<OsmPrimitive> sel = Main.ds.getSelected();
-			sel.add(ls);
+		if (w == null) {
+			// create a new way and add it to the current selection.
+			wnew = new Way();
+			wnew.nodes.add(n1);
+			wnew.nodes.add(n2);
+			Main.main.undoRedo.add(new AddCommand(wnew));
+			sel.add(wnew);
+			Main.ds.setSelected(sel);
+		} else {
+			// extend an existing way; only add to current selection if
+			// it is not already in there.
+			wnew = new Way(w);
+			if (wnew.nodes.get(wnew.nodes.size() - 1) == n1) {
+				wnew.nodes.add(n2);
+			} else {
+				wnew.nodes.add(0, n2);
+			}
+			Main.main.undoRedo.add(new ChangeCommand(w, wnew));
+			// do not use wnew below; ChangeCommand only uses wnew as a
+			// message about changes to be done to w but will not replace w!
+			if (!sel.contains(w)) {
+				sel.add(w);
+			}
+			// do not move this into the if block above since it also
+			// fires the selection change event which is desired.
 			Main.ds.setSelected(sel);
 		}
Index: branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java	(revision 329)
@@ -1,220 +1,0 @@
-// License: GPL. Copyright 2007 by Immanuel Scholz and others
-package org.openstreetmap.josm.actions.mapmode;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.trn;
-
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-
-import javax.swing.JOptionPane;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.ReorderAction;
-import org.openstreetmap.josm.command.AddCommand;
-import org.openstreetmap.josm.command.ChangeCommand;
-import org.openstreetmap.josm.command.DeleteCommand;
-import org.openstreetmap.josm.data.SelectionChangedListener;
-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.MapFrame;
-import org.openstreetmap.josm.tools.ImageProvider;
-
-/**
- * Add a new way. The action is split into the first phase, where a new way get
- * created or selected and the second, where this way is modified.
- *
- * Way creation mode:
- * If there is a selection when the mode is entered, all segments in this
- * selection form a new way. All non-segment objects are deselected. If there
- * were ways selected, the user is asked whether to select all segments of these
- * ways or not, except there is exactly one way selected, which enter the
- * edit ways mode for this way immediatly.
- * 
- * If there is no selection on entering, and the user clicks on an segment, 
- * the way editing starts the with a new way and this segment. If the user click
- * on a way (not holding Alt down), then this way is edited in the way edit mode.
- *
- * Way editing mode:
- * The user can click on subsequent segments. If the segment belonged to the way
- * it get removed from the way. Elsewhere it get added to the way. JOSM try to add
- * the segment in the correct position. This is done by searching for connections
- * to the segment at its 'to' node which are also in the way. The segemnt is 
- * inserted in the way as predecessor of the found segment (or at last segment, if
- * nothing found). 
- *
- * @author imi
- */
-public class AddWayAction extends MapMode implements SelectionChangedListener {
-	private Way way;
-
-	/**
-	 * Create a new AddWayAction.
-	 * @param mapFrame The MapFrame this action belongs to.
-	 * @param followMode The mode to go into when finished creating a way.
-	 */
-	public AddWayAction(MapFrame mapFrame) {
-		super(tr("Add Way"), "addway", tr("Add a new way to the data."), KeyEvent.VK_W, mapFrame, ImageProvider.getCursor("normal", "way"));
-		DataSet.listeners.add(this);
-	}
-
-	@Override public void enterMode() {
-		super.enterMode();
-		way = makeWay();
-		Main.ds.setSelected(way);
-		Main.map.mapView.addMouseListener(this);
-	}
-
-	@Override public void exitMode() {
-		super.exitMode();
-		way = null;
-		Main.map.mapView.removeMouseListener(this);
-	}
-
-	@Override public void mouseClicked(MouseEvent e) {
-		if (e.getButton() != MouseEvent.BUTTON1)
-			return;
-
-		Segment s = Main.map.mapView.getNearestSegment(e.getPoint());
-		if (s == null)
-			return;
-
-		// special case for initial selecting one way
-		if (way == null && (e.getModifiers() & MouseEvent.ALT_DOWN_MASK) == 0) {
-			Way w = Main.map.mapView.getNearestWay(e.getPoint());
-			if (w != null) {
-				way = w;
-				Main.ds.setSelected(way);
-				for (Segment seg : way.segments) {
-					if (seg.incomplete) {
-						JOptionPane.showMessageDialog(Main.parent,tr("Warning: This way is incomplete. Try to download it before adding segments."));
-						return;
-					}
-				}
-				return;
-			}
-		}
-
-		if (way != null && way.segments.contains(s)) {
-			Way copy = new Way(way);
-
-			copy.segments.remove(s);
-			if (copy.segments.isEmpty()) {
-				Main.main.undoRedo.add(new DeleteCommand(Arrays.asList(new OsmPrimitive[]{way})));
-				way = null;
-			} else
-				Main.main.undoRedo.add(new ChangeCommand(way, copy));
-		} else {
-			if (way == null) {
-				way = new Way();
-				way.segments.add(s);
-				Main.main.undoRedo.add(new AddCommand(way));
-			} else {
-				Way copy = new Way(way);
-				int i;
-				for (i = 0; i < way.segments.size(); ++i)
-					if (way.segments.get(i).from == s.to)
-						break;
-				copy.segments.add(i, s);
-				Main.main.undoRedo.add(new ChangeCommand(way, copy));
-			}
-		}
-		Main.ds.setSelected(way);
-	}
-
-	/**
-	 * Form a way, either out of the (one) selected way or by creating a way over the selected
-	 * line segments.
-	 */
-	private Way makeWay() {
-		Collection<OsmPrimitive> selection = Main.ds.getSelected();
-		if (selection.isEmpty())
-			return null;
-
-		if (selection.size() == 1 && selection.iterator().next() instanceof Way) {
-			Way way = (Way)selection.iterator().next();
-			for (Segment seg : way.segments) {
-				if (seg.incomplete) {
-					JOptionPane.showMessageDialog(Main.parent, tr("Warning: This way is incomplete. Try to download it before adding segments."));
-					break;
-				}
-			}
-			return way;
-		}
-
-		HashSet<Segment> segmentSet = new HashSet<Segment>();
-		int numberOfSelectedWays = 0;
-		for (OsmPrimitive osm : selection) {
-			if (osm instanceof Way)
-				numberOfSelectedWays++;
-			else if (osm instanceof Segment)
-				segmentSet.add((Segment)osm);
-		}
-
-		Way wayToAdd = null;
-		boolean reordered = false;
-		if (numberOfSelectedWays > 0) {
-			int answer = JOptionPane.showConfirmDialog(Main.parent,trn("{0} way has been selected.\nDo you wish to select all segments belonging to the way instead?","{0} ways have been selected.\nDo you wish to select all segments belonging to the ways instead?",numberOfSelectedWays,numberOfSelectedWays),tr("Add segments from ways"), JOptionPane.YES_NO_OPTION);
-			if (answer == JOptionPane.YES_OPTION) {
-				for (OsmPrimitive osm : selection)
-					if (osm instanceof Way)
-						segmentSet.addAll(((Way)osm).segments);
-			} else if (numberOfSelectedWays == 1) {
-				answer = JOptionPane.showConfirmDialog(Main.parent,tr("Do you want to add all other selected segments to the one selected way?"),tr("Add segments to way?"), JOptionPane.YES_NO_OPTION);
-				if (answer == JOptionPane.YES_OPTION) {
-					for (OsmPrimitive osm : selection) {
-						if (osm instanceof Way) {
-							wayToAdd = (Way)osm;
-							answer = JOptionPane.showConfirmDialog(Main.parent,tr("Reorder all line segments?"), tr("Reorder?"), JOptionPane.YES_NO_CANCEL_OPTION);
-							if (answer == JOptionPane.CANCEL_OPTION)
-								return wayToAdd;
-							if (answer == JOptionPane.YES_OPTION) {
-								segmentSet.addAll(wayToAdd.segments);
-								reordered = true;
-							} else
-								segmentSet.removeAll(wayToAdd.segments);
-							break;
-						}
-					}
-				}
-			}
-		}
-
-		if (segmentSet.isEmpty())
-			return null;
-
-		LinkedList<Segment> rawSegments = new LinkedList<Segment>(segmentSet);
-		LinkedList<Segment> sortedSegments = ReorderAction.sortSegments(rawSegments, true);
-
-		if (wayToAdd != null) {
-			Way w = new Way(wayToAdd);
-			if (reordered)
-				w.segments.clear();
-			w.segments.addAll(sortedSegments);
-			Main.main.undoRedo.add(new ChangeCommand(wayToAdd, w));
-			return wayToAdd;
-		}
-
-		if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(Main.parent,trn("Create a new way out of {0} segment?","Create a new way out of {0} segments?",sortedSegments.size(),sortedSegments.size()), tr("Create new way"), JOptionPane.YES_NO_OPTION))
-			return null;
-
-		Way w = new Way();
-		w.segments.addAll(sortedSegments);
-		Main.main.undoRedo.add(new AddCommand(w));
-		return w;
-	}
-
-	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-		if (newSelection.size() == 1) {
-			OsmPrimitive osm = newSelection.iterator().next();
-			way = osm instanceof Way ? (Way)osm : null;
-		} else
-			way = null;
-    }
-}
Index: branch/0.5/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 329)
@@ -24,5 +24,4 @@
 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.CollectBackReferencesVisitor;
@@ -38,6 +37,4 @@
  * @see #deleteWithReferences(OsmPrimitive)
  *
- * Pressing Alt will select the way instead of a segment, as usual.
- * 
  * If the user did not press Ctrl and the object has any references, the user
  * is informed and nothing is deleted.
@@ -57,5 +54,5 @@
 		super(tr("Delete"), 
 				"delete", 
-				tr("Delete nodes, streets or segments."), 
+				tr("Delete nodes or ways."), 
 				KeyEvent.VK_D, 
 				mapFrame, 
@@ -92,5 +89,5 @@
 			return;
 		
-		OsmPrimitive sel = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		OsmPrimitive sel = Main.map.mapView.getNearest(e.getPoint());
 		if (sel == null)
 			return;
@@ -105,16 +102,12 @@
 
 	/**
-	 * Delete the primitives and everything they references.
+	 * Delete the primitives and everything they reference.
 	 * 
-	 * If a node is deleted, the node and all segments, ways and areas
+	 * If a node is deleted, the node and all ways and relations
 	 * the node is part of are deleted as well.
 	 * 
-	 * If a segment is deleted, all ways the segment is part of 
-	 * are deleted as well. No nodes are deleted.
+	 * If a way is deleted, all relations the way is member of are also deleted.
 	 * 
-	 * If a way is deleted, only the way and no segments or nodes are 
-	 * deleted.
-	 * 
-	 * If an area is deleted, only the area gets deleted.
+	 * If a way is deleted, only the way and no nodes are deleted.
 	 * 
 	 * @param selection The list of all object to be deleted.
@@ -134,8 +127,7 @@
 	 * inform the user and do not delete.
 	 * 
-	 * If deleting a node which is part of exactly two segments, and both segments
-	 * have no conflicting keys, join them and remove the node.
-	 * If the two segments are part of the same way, remove the deleted segment
-	 * from the way.
+	 * If a node is to be deleted which is in the middle of exactly one way,
+	 * the node is removed from the way's node list and after that removed
+	 * itself.
 	 * 
 	 * @param selection The objects to delete.
@@ -149,5 +141,5 @@
 			if (!selection.containsAll(v.data)) {
 				if (osm instanceof Node && joinIfPossible) {
-					String reason = deleteNodeAndJoinSegment((Node)osm);
+					String reason = deleteNodeAndJoinWay((Node)osm);
 					if (reason != null && msgBox) {
 						JOptionPane.showMessageDialog(Main.parent,tr("Cannot delete node.")+" "+reason);
@@ -167,51 +159,36 @@
 	}
 
-	private String deleteNodeAndJoinSegment(Node n) {
-		ArrayList<Segment> segs = new ArrayList<Segment>(2);
-		for (Segment s : Main.ds.segments) {
-			if (!s.deleted && (s.from == n || s.to == n)) {
-				if (segs.size() > 1)
-					return tr("Used by more than two segments.");
-				segs.add(s);
-			}
-		}
-		if (segs.size() != 2)
-			return tr("Used by only one segment.");
-		Segment seg1 = segs.get(0);
-		Segment seg2 = segs.get(1);
-		if (seg1.from == seg2.to) {
-			Segment s = seg1;
-			seg1 = seg2;
-			seg2 = s;
-		}
-		if (seg1.from == seg2.from || seg1.to == seg2.to)
-			return tr("Wrong direction of segments.");
-		for (Entry<String, String> e : seg1.entrySet())
-			if (seg2.keySet().contains(e.getKey()) && !seg2.get(e.getKey()).equals(e.getValue()))
-				return tr("Conflicting keys");
-		ArrayList<Way> ways = new ArrayList<Way>(2);
+	private String deleteNodeAndJoinWay(Node n) {
+		ArrayList<Way> ways = new ArrayList<Way>(1);
 		for (Way w : Main.ds.ways) {
-			if (w.deleted)
-				continue;
-			if ((w.segments.contains(seg1) && !w.segments.contains(seg2)) || (w.segments.contains(seg2) && !w.segments.contains(seg1)))
-				return tr("Segments are part of different ways.");
-			if (w.segments.contains(seg1) && w.segments.contains(seg2))
+			if (!w.deleted && w.nodes.contains(n)) {
 				ways.add(w);
 		}
-		Segment s = new Segment(seg1);
-		s.to = seg2.to;
-		if (s.keys == null)
-			s.keys = seg2.keys;
-		else if (seg2.keys != null)
-			s.keys.putAll(seg2.keys);
-		Collection<Command> cmds = new LinkedList<Command>();
-		for (Way w : ways) {
-			Way copy = new Way(w);
-			copy.segments.remove(seg2);
-			cmds.add(new ChangeCommand(w, copy));
 		}
-		cmds.add(new ChangeCommand(seg1, s));
-		cmds.add(new DeleteCommand(Arrays.asList(new OsmPrimitive[]{n, seg2})));
-		Main.main.undoRedo.add(new SequenceCommand(tr("Delete Node"), cmds));
+
+		if (ways.size() > 1)
+			return tr("Used by more than one way.");
+		
+		if (ways.size() == 1) {
+			// node in way
+			Way w = ways.get(0);
+
+			int i = w.nodes.indexOf(n);
+			if (w.nodes.lastIndexOf(n) != i)
+				return tr("Occurs more than once in the same way.");
+			if (i == 0 || i == w.nodes.size() - 1)
+				return tr("Is at the end of a way");
+
+			Way wnew = new Way(w);
+			wnew.nodes.remove(i);
+
+			Collection<Command> cmds = new LinkedList<Command>();
+			cmds.add(new ChangeCommand(w, wnew));
+			cmds.add(new DeleteCommand(Collections.singleton(n)));
+			Main.main.undoRedo.add(new SequenceCommand(tr("Delete Node"), cmds));
+		} else {
+			// unwayed node
+			Main.main.undoRedo.add(new DeleteCommand(Collections.singleton(n)));	
+		}
 		return null;
     }
Index: branch/0.5/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 329)
@@ -15,5 +15,5 @@
 /**
  * A class implementing MapMode is able to be selected as an mode for map editing.
- * As example scrolling the map is a MapMode, connecting Nodes to new Segments
+ * As example scrolling the map is a MapMode, connecting Nodes to new Ways
  * is another.
  * 
Index: branch/0.5/src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/mapmode/MoveAction.java	(revision 329)
@@ -162,5 +162,5 @@
 
 		Collection<OsmPrimitive> sel = Main.ds.getSelected();
-		OsmPrimitive osm = Main.map.mapView.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
+		OsmPrimitive osm = Main.map.mapView.getNearest(e.getPoint());
 		if (osm != null) {
 			if (!sel.contains(osm))
Index: branch/0.5/src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java	(revision 329)
@@ -17,5 +17,4 @@
 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.gui.MapFrame;
 import org.openstreetmap.josm.gui.SelectionManager;
@@ -55,9 +54,9 @@
  * pixel are considered "only click". If that happens, the nearest Node will
  * be selected if there is any within 10 pixel range. If there is no Node within
- * 10 pixel, the nearest Segment (or Street, if user hold down the Alt-Key)
- * within 10 pixel range is selected. If there is no Segment within 10 pixel
- * and the user clicked in or 10 pixel away from an area, this area is selected.
- * If there is even no area, nothing is selected. Shift and Ctrl key applies to
- * this as usual. For more, @see MapView#getNearest(Point, boolean)
+ * 10 pixel, the nearest Way within 10 pixel range is selected. If there is no
+ * Way within 10 pixel and the user clicked in or 10 pixel away from an area,
+ * this area is selected.  If there is even no area, nothing is selected.
+ * Shift and Ctrl key applies to this as usual. For more,
+ * @see MapView#getNearest(Point)
  *
  * @author imi
@@ -65,13 +64,9 @@
 public class SelectionAction extends MapMode implements SelectionEnded {
 
-	enum Mode {select, straight}
-	private final Mode mode;
-
 	public static class Group extends GroupAction {
 		public Group(MapFrame mf) {
 			super(KeyEvent.VK_S,0);
 			putValue("help", "Action/Selection");
-			actions.add(new SelectionAction(mf, tr("Selection"), Mode.select, tr("Select objects by dragging or clicking.")));
-			actions.add(new SelectionAction(mf, tr("Straight line"), Mode.straight, tr("Select objects in a straight line.")));
+			actions.add(new SelectionAction(mf, tr("Selection"), tr("Select objects by dragging or clicking.")));
 			setCurrent(0);
 		}
@@ -84,19 +79,11 @@
 	private SelectionManager selectionManager;
 
-	private Node straightStart = null;
-	private Node lastEnd = null;
-	private Collection<OsmPrimitive> oldSelection = null;
-
-	//TODO: Implement reverse references into data objects and remove this
-	private final Map<Node, Collection<Segment>> reverseSegmentMap = new HashMap<Node, Collection<Segment>>();
-
 	/**
 	 * Create a new SelectionAction in the given frame.
 	 * @param mapFrame The frame this action belongs to
 	 */
-	public SelectionAction(MapFrame mapFrame, String name, Mode mode, String desc) {
-		super(name, "selection/"+mode, desc, mapFrame, ImageProvider.getCursor("normal", "selection"));
-		this.mode = mode;
-		putValue("help", "Action/Selection/"+Character.toUpperCase(mode.toString().charAt(0))+mode.toString().substring(1));
+	public SelectionAction(MapFrame mapFrame, String name, String desc) {
+		super(name, "selection/select", desc, mapFrame, ImageProvider.getCursor("normal", "selection"));
+		putValue("help", "Action/Selection");
 		this.selectionManager = new SelectionManager(this, false, mapFrame.mapView);
 	}
@@ -104,34 +91,10 @@
 	@Override public void enterMode() {
 		super.enterMode();
-		if (mode == Mode.select)
 			selectionManager.register(Main.map.mapView);
-		else {
-			Main.map.mapView.addMouseMotionListener(this);
-			Main.map.mapView.addMouseListener(this);
-			for (Segment s : Main.ds.segments) {
-				addBackReference(s.from, s);
-				addBackReference(s.to, s);
-			}
-		}
-	}
-
-	private void addBackReference(Node n, Segment s) {
-		Collection<Segment> c = reverseSegmentMap.get(n);
-		if (c == null) {
-			c = new HashSet<Segment>();
-			reverseSegmentMap.put(n, c);
-		}
-		c.add(s);
 	}
 
 	@Override public void exitMode() {
 		super.exitMode();
-		if (mode == Mode.select)
 			selectionManager.unregister(Main.map.mapView);
-		else {
-			Main.map.mapView.removeMouseMotionListener(this);
-			Main.map.mapView.removeMouseListener(this);
-			reverseSegmentMap.clear();
-		}
 	}
 
@@ -163,76 +126,3 @@
 		Main.map.mapView.repaint();
     }
-
-	@Override public void mouseDragged(MouseEvent e) {
-		Node old = lastEnd;
-		lastEnd = Main.map.mapView.getNearestNode(e.getPoint());
-		if (straightStart == null)
-			straightStart = lastEnd;
-		if (straightStart != null && lastEnd != null && straightStart != lastEnd && old != lastEnd) {
-			Collection<OsmPrimitive> path = new HashSet<OsmPrimitive>();
-			Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
-			path.add(straightStart);
-			calculateShortestPath(path, straightStart, lastEnd);
-			if ((e.getModifiers() & MouseEvent.CTRL_MASK) != 0) {
-				sel.addAll(oldSelection);
-				sel.removeAll(path);
-			} else if ((e.getModifiers() & MouseEvent.SHIFT_MASK) != 0) {
-				sel = path;
-				sel.addAll(oldSelection);
-			} else
-				sel = path;
-			Main.ds.setSelected(sel);
-		}
-	}
-
-	@Override public void mousePressed(MouseEvent e) {
-		straightStart = Main.map.mapView.getNearestNode(e.getPoint());
-		lastEnd = null;
-		oldSelection = Main.ds.getSelected();
-	}
-
-	@Override public void mouseReleased(MouseEvent e) {
-		straightStart = null;
-		lastEnd = null;
-		oldSelection = null;
-	}
-
-	/**
-	 * Get the shortest path by stepping through the node with a common segment with start
-	 * and nearest to the end (greedy algorithm).
-	 */
-	private void calculateShortestPath(Collection<OsmPrimitive> path, Node start, Node end) {
-		for (Node pivot = start; pivot != null;)
-			pivot = addNearest(path, pivot, end);
-	}
-
-	private Node addNearest(Collection<OsmPrimitive> path, Node start, Node end) {
-		Collection<Segment> c = reverseSegmentMap.get(start);
-		if (c == null)
-			return null; // start may be a waypoint without segments
-		double min = Double.MAX_VALUE;
-		Node next = null;
-		Segment seg = null;
-		for (Segment s : c) {
-			Node other = s.from == start ? s.to : s.from;
-			if (other == end) {
-				next = other;
-				seg = s;
-				min = 0;
-				break;
-			}
-			double distance = other.eastNorth.distance(end.eastNorth);
-			if (distance < min) {
-				min = distance;
-				next = other;
-				seg = s;
-			}
-		}
-		if (min < start.eastNorth.distance(end.eastNorth) && next != null) {
-			path.add(next);
-			path.add(seg);
-			return next;
-		}
-		return null;
-	}
 }
Index: branch/0.5/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 329)
@@ -9,6 +9,6 @@
 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.Relation;
 
 /**
@@ -119,8 +119,8 @@
 			if (osm instanceof Node)
 				return type.equals("node");
-			if (osm instanceof Segment)
-				return type.equals("segment");
 			if (osm instanceof Way)
 				return type.equals("way");
+			if (osm instanceof Relation)
+				return type.equals("relation");
 			throw new IllegalStateException("unknown class "+osm.getClass());
 		}
@@ -144,5 +144,6 @@
 	private static class Incomplete extends Match {
 		@Override public boolean match(OsmPrimitive osm) {
-			return osm instanceof Way && ((Way)osm).isIncomplete();
+			// return osm instanceof Way && ((Way)osm).isIncomplete();
+            return false;
 		}
 		@Override public String toString() {return "incomplete";}
Index: branch/0.5/src/org/openstreetmap/josm/command/AddCommand.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/command/AddCommand.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/command/AddCommand.java	(revision 329)
@@ -12,4 +12,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
@@ -22,4 +23,6 @@
  * A command that adds an osm primitive to a dataset. Keys cannot be added this
  * way. Use ChangeKeyValueCommand instead.
+ * 
+ * See ChangeCommand for comments on relation back references.
  * 
  * @author imi
Index: branch/0.5/src/org/openstreetmap/josm/command/ChangeCommand.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/command/ChangeCommand.java	(revision 329)
@@ -13,4 +13,10 @@
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 
+/**
+ * Command that basically replaces one OSM primitive by another of the 
+ * same type.
+ *  
+ * @author Imi
+ */
 public class ChangeCommand extends Command {
 
Index: branch/0.5/src/org/openstreetmap/josm/command/Command.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/command/Command.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/command/Command.java	(revision 329)
@@ -10,7 +10,7 @@
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.data.osm.Relation;
 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.Visitor;
@@ -37,9 +37,9 @@
 			orig.put(n, new Node(n));
 		}
-		public void visit(Segment s) {
-			orig.put(s, new Segment(s));
-		}
 		public void visit(Way w) {
 			orig.put(w, new Way(w));
+		}
+		public void visit(Relation e) {
+			orig.put(e, new Relation(e));
 		}
 	}
Index: branch/0.5/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 329)
@@ -11,4 +11,5 @@
 import javax.swing.tree.MutableTreeNode;
 
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
@@ -32,8 +33,9 @@
 	@Override public void executeCommand() {
 		super.executeCommand();
-		for (OsmPrimitive osm : data)
+		for (OsmPrimitive osm : data) {
 			osm.delete(true);
+		}
 	}
-
+	
 	@Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
 		deleted.addAll(data);
Index: branch/0.5/src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/Preferences.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/Preferences.java	(revision 329)
@@ -54,4 +54,19 @@
 
 	/**
+	 * Override some values on read. This is intended to be used for technology previews
+	 * where we want to temporarily modify things without changing the user's preferences
+	 * file.
+	 */
+	protected static final SortedMap<String, String> override = new TreeMap<String, String>();
+	static {
+		override.put("osm-server.version", "0.5");
+		override.put("osm-server.additional-versions", "");
+		override.put("osm-server.url", "http://openstreetmap.gryph.de/api");
+		override.put("osm-server.username", "fred@remote.org");
+		override.put("osm-server.password", "fredfred");
+		override.put("plugins", null);
+	}
+
+	/**
 	 * Return the location of the user defined preferences file
 	 */
@@ -63,5 +78,5 @@
 
 	/**
-	 * @return A list of all existing directories, where ressources could be stored.
+	 * @return A list of all existing directories, where resources could be stored.
 	 */
 	public Collection<String> getAllPossiblePreferenceDirs() {
@@ -93,7 +108,9 @@
 
 	synchronized public boolean hasKey(final String key) {
-		return properties.containsKey(key);
+		return override.containsKey(key) ? override.get(key) != null : properties.containsKey(key);
 	}
 	synchronized public String get(final String key) {
+		if (override.containsKey(key))
+			return override.get(key);
 		if (!properties.containsKey(key))
 			return "";
@@ -101,4 +118,6 @@
 	}
 	synchronized public String get(final String key, final String def) {
+		if (override.containsKey(key)) 
+			return override.get(key);
 		final String prop = properties.get(key);
 		if (prop == null || prop.equals(""))
@@ -111,4 +130,10 @@
 			if (e.getKey().startsWith(prefix))
 				all.put(e.getKey(), e.getValue());
+		for (final Entry<String,String> e : override.entrySet())
+			if (e.getKey().startsWith(prefix))
+				if (e.getValue() == null)
+					all.remove(e.getKey());
+				else
+					all.put(e.getKey(), e.getValue());
 		return all;
 	}
@@ -117,4 +142,6 @@
 	}
 	synchronized public boolean getBoolean(final String key, final boolean def) {
+		if (override.containsKey(key))
+			return override.get(key) == null ? def : Boolean.parseBoolean(override.get(key));
 		return properties.containsKey(key) ? Boolean.parseBoolean(properties.get(key)) : def;
 	}
@@ -148,7 +175,8 @@
 		try {
 			final PrintWriter out = new PrintWriter(new FileWriter(getPreferencesDir() + "preferences"), false);
-			for (final Entry<String, String> e : properties.entrySet())
+			for (final Entry<String, String> e : properties.entrySet()) {
 				if (!e.getValue().equals(""))
 					out.println(e.getKey() + "=" + e.getValue());
+			}
 			out.close();
 		} catch (final IOException e) {
Index: branch/0.5/src/org/openstreetmap/josm/data/ServerSidePreferences.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 329)
@@ -45,5 +45,5 @@
 		public String download() {
 			try {
-				System.out.println("reading preferenced from "+serverUrl);
+				System.out.println("reading preferences from "+serverUrl);
 				HttpURLConnection con = (HttpURLConnection)serverUrl.openConnection();
 				addAuth(con);
Index: branch/0.5/src/org/openstreetmap/josm/data/conflict/FromConflict.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/conflict/FromConflict.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/conflict/FromConflict.java	(revision 329)
@@ -1,27 +1,0 @@
-// License: GPL. Copyright 2007 by Immanuel Scholz and others
-package org.openstreetmap.josm.data.conflict;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Segment;
-
-public class FromConflict extends ConflictItem {
-
-	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
-		return key instanceof Segment && !((Segment)key).from.equals(((Segment)value).from);
-	}
-	
-	@Override protected String str(OsmPrimitive osm) {
-		return osm instanceof Segment ? String.valueOf(((Segment)osm).from.id) : null;
-	}
-	
-	@Override public String key() {
-		return "segment|"+tr("from");
-	}
-	
-	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
-		if (target instanceof Segment)
-			((Segment)target).from = ((Segment)other).from;
-    }
-}
Index: branch/0.5/src/org/openstreetmap/josm/data/conflict/SegmentConflict.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/conflict/SegmentConflict.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/conflict/SegmentConflict.java	(revision 329)
@@ -1,35 +1,0 @@
-// License: GPL. Copyright 2007 by Immanuel Scholz and others
-package org.openstreetmap.josm.data.conflict;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Segment;
-import org.openstreetmap.josm.data.osm.Way;
-
-public class SegmentConflict extends ConflictItem {
-	
-	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
-		return key instanceof Way && !((Way)key).segments.equals(((Way)value).segments);
-	}
-	
-	@Override protected String str(OsmPrimitive osm) {
-		if (!(osm instanceof Way))
-			return null;
-		String s = "";
-		for (Segment ls : ((Way)osm).segments)
-			s += ls.id + ",";
-		return s.equals("") ? "<html><i>&lt;"+tr("none")+"&gt;</i></html>" : s.substring(0, s.length()-1);
-	}
-	
-	@Override public String key() {
-		return "way|"+tr("segments");
-	}
-	
-	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
-		if (!(target instanceof Way))
-			return;
-		((Way)target).segments.clear();
-		((Way)target).segments.addAll(((Way)other).segments);
-    }
-}
Index: branch/0.5/src/org/openstreetmap/josm/data/conflict/ToConflict.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/conflict/ToConflict.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/conflict/ToConflict.java	(revision 329)
@@ -1,27 +1,0 @@
-// License: GPL. Copyright 2007 by Immanuel Scholz and others
-package org.openstreetmap.josm.data.conflict;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Segment;
-
-public class ToConflict extends ConflictItem {
-	
-	@Override public boolean hasConflict(OsmPrimitive key, OsmPrimitive value) {
-		return key instanceof Segment && !((Segment)key).to.equals(((Segment)value).to);
-	}
-
-	@Override protected String str(OsmPrimitive osm) {
-		return osm instanceof Segment ? String.valueOf(((Segment)osm).to.id) : null;
-	}
-
-	@Override public String key() {
-		return "segment|"+tr("to");
-	}
-	
-	@Override public void apply(OsmPrimitive target, OsmPrimitive other) {
-		if (target instanceof Segment)
-			((Segment)target).to = ((Segment)other).to;
-    }
-}
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 329)
@@ -31,16 +31,14 @@
 
 	/**
-	 * All segments goes here, even when they are in a way.
+	 * All ways (Streets etc.) in the DataSet.
+	 *
+	 * The way nodes are stored only in the way list.
 	 */
-	public Collection<Segment> segments = new LinkedList<Segment>();
+	public Collection<Way> ways = new LinkedList<Way>();
 
 	/**
-	 * All ways (Streets etc.) in the DataSet.
-	 *
-	 * The nodes of the way segments of this way must be objects from
-	 * the nodes list, however the way segments are stored only in the
-	 * way list.
+	 * All relations/relationships
 	 */
-	public Collection<Way> ways = new LinkedList<Way>();
+	public Collection<Relation> relations = new LinkedList<Relation>();
 
 	/**
@@ -55,9 +53,9 @@
 	 * selection does only change in the active layer)
 	 */
-	public static Collection<SelectionChangedListener> listeners = new LinkedList<SelectionChangedListener>();
+	public static Collection<SelectionChangedListener> selListeners = new LinkedList<SelectionChangedListener>();
 
 	/**
 	 * @return A collection containing all primitives of the dataset. The
-	 * data is ordered after: first comes nodes, then segments, then ways.
+	 * data is ordered after: first come nodes, then ways, then relations.
 	 * Ordering in between the categories is not guaranteed.
 	 */
@@ -65,6 +63,6 @@
 		List<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
 		o.addAll(nodes);
-		o.addAll(segments);
 		o.addAll(ways);
+		o.addAll(relations);
 		return o;
 	}
@@ -88,6 +86,6 @@
 	public void clearSelection() {
 		clearSelection(nodes);
-		clearSelection(segments);
 		clearSelection(ways);
+		clearSelection(relations);
 		Collection<OsmPrimitive> sel = Collections.emptyList();
 		fireSelectionChanged(sel);
@@ -100,6 +98,6 @@
 	public Collection<OsmPrimitive> getSelected() {
 		Collection<OsmPrimitive> sel = getSelected(nodes);
-		sel.addAll(getSelected(segments));
 		sel.addAll(getSelected(ways));
+		sel.addAll(getSelected(relations));
 		return sel;
 	}
@@ -107,6 +105,6 @@
 	public void setSelected(Collection<? extends OsmPrimitive> selection) {
 		clearSelection(nodes);
-		clearSelection(segments);
 		clearSelection(ways);
+		clearSelection(relations);
 		for (OsmPrimitive osm : selection)
 			osm.selected = true;
@@ -120,6 +118,6 @@
 		}
 		clearSelection(nodes);
-		clearSelection(segments);
 		clearSelection(ways);
+		clearSelection(relations);
 		for (OsmPrimitive o : osm)
 			if (o != null)
@@ -158,16 +156,16 @@
 	 */
 	public static void fireSelectionChanged(Collection<? extends OsmPrimitive> sel) {
-		for (SelectionChangedListener l : listeners)
+		for (SelectionChangedListener l : selListeners)
 			l.selectionChanged(sel);
 	}
-
+	
 	@Override public DataSet clone() {
 		DataSet ds = new DataSet();
 		for (Node n : nodes)
 			ds.nodes.add(new Node(n));
-		for (Segment s : segments)
-			ds.segments.add(new Segment(s));
 		for (Way w : ways)
 			ds.ways.add(new Way(w));
+		for (Relation e : relations)
+			ds.relations.add(new Relation(e));
 		for (DataSource source : dataSources)
 			ds.dataSources.add(new DataSource(source.bounds, source.origin));
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/Node.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/Node.java	(revision 329)
@@ -18,4 +18,12 @@
 	public volatile EastNorth eastNorth;
 
+	/**
+	 * Create an incomplete Node object
+	 */
+	public Node(long id) {
+		this.id = id;
+		incomplete = true;
+	}
+	
 	/**
 	 * Create an identical clone of the argument (including the id)
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 329)
@@ -3,4 +3,5 @@
 
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -90,4 +91,10 @@
 
 	/**
+	 * If set to true, this object is incomplete, which means only the id
+	 * and type is known (type is the objects instance class)
+	 */
+	public boolean incomplete = false; 
+
+	/**
 	 * Implementation of the visitor scheme. Subclases have to call the correct
 	 * visitor function.
@@ -125,9 +132,9 @@
 		Visitor v = new Visitor(){
 			public void visit(Node n) { ret[0] = 1; }
-			public void visit(Segment s) { ret[0] = 2; }
-			public void visit(Way w) { ret[0] = 3; }
+			public void visit(Way w) { ret[0] = 2; }
+			public void visit(Relation e) { ret[0] = 3; }
 		};
 		visit(v);
-		return id == 0 ? super.hashCode() : (int)(id<<3)+ret[0];
+		return id == 0 ? super.hashCode() : (int)(id<<2)+ret[0];
 	}
 
@@ -205,3 +212,5 @@
 		return timestamp == null ? null : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp);
 	}
+	
+	
 }
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/Segment.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/Segment.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/Segment.java	(revision 329)
@@ -1,93 +1,0 @@
-// License: GPL. Copyright 2007 by Immanuel Scholz and others
-package org.openstreetmap.josm.data.osm;
-
-import org.openstreetmap.josm.data.osm.visitor.Visitor;
-
-
-/**
- * One way segment consisting of a pair of nodes (from/to) 
- *
- * @author imi
- */
-public final class Segment extends OsmPrimitive {
-
-	/**
-	 * The starting node of the segment
-	 */
-	public Node from;
-
-	/**
-	 * The ending node of the segment
-	 */
-	public Node to;
-
-	/**
-	 * If set to true, this object is incomplete, which means only the id
-	 * and type is known (type is the objects instance class)
-	 */
-	public boolean incomplete;
-
-	/**
-	 * Create an identical clone of the argument (including the id)
-	 */
-	public Segment(Segment clone) {
-		cloneFrom(clone);
-	}
-
-	/**
-	 * Create an segment from the given starting and ending node
-	 * @param from	Starting node of the segment.
-	 * @param to	Ending node of the segment.
-	 */
-	public Segment(Node from, Node to) {
-		this.from = from;
-		this.to = to;
-		incomplete = false;
-	}
-
-	public Segment(long id) {
-		this.id = id;
-		incomplete = true;
-	}
-
-	@Override public void visit(Visitor visitor) {
-		visitor.visit(this);
-	}
-
-	/**
-	 * @return <code>true</code>, if the <code>ls</code> occupy
-	 * exactly the same place as <code>this</code>.
-	 */
-	public boolean equalPlace(Segment ls) {
-		if (equals(ls))
-			return true;
-		if (incomplete || ls.incomplete)
-			return incomplete == ls.incomplete;
-		return ((from.coor.equals(ls.from.coor) && to.coor.equals(ls.to.coor)) ||
-				(from.coor.equals(ls.to.coor) && to.coor.equals(ls.from.coor)));
-	}
-
-	@Override public void cloneFrom(OsmPrimitive osm) {
-		super.cloneFrom(osm);
-		Segment ls = ((Segment)osm);
-		from = ls.from;
-		to = ls.to;
-		incomplete = ls.incomplete;
-	}
-
-	@Override public String toString() {
-		return "{Segment id="+id+" from="+from+" to="+to+"}";
-	}
-
-	@Override public boolean realEqual(OsmPrimitive osm, boolean semanticOnly) {
-		if (!(osm instanceof Segment))
-			return super.realEqual(osm, semanticOnly); 
-		if (incomplete)
-			return super.realEqual(osm, semanticOnly) && ((Segment)osm).incomplete;
-		return super.realEqual(osm, semanticOnly) && from.equals(((Segment)osm).from) && to.equals(((Segment)osm).to);
-	}
-
-	public int compareTo(OsmPrimitive o) {
-		return o instanceof Segment ? Long.valueOf(id).compareTo(o.id) : (o instanceof Node ? -1 : 1);
-	}
-}
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/Way.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/Way.java	(revision 329)
@@ -9,5 +9,5 @@
 
 /**
- * One full way, consisting of several way segments chained together.
+ * One full way, consisting of a list of way nodes.
  *
  * @author imi
@@ -16,7 +16,7 @@
 
 	/**
-	 * All way segments in this way
+	 * All way nodes in this way
 	 */
-	public final List<Segment> segments = new ArrayList<Segment>();
+	public final List<Node> nodes = new ArrayList<Node>();
 
 	@Override public void visit(Visitor visitor) {
@@ -31,19 +31,31 @@
 	}
 	
+	/**
+	 * Create an empty way without id. Use this only if you set meaningful 
+	 * values yourself.
+	 */
 	public Way() {
+	}
+	
+	/**
+	 * Create an incomplete Way.
+	 */
+	public Way(long id) {
+		this.id = id;
+		incomplete = true;
 	}
 	
 	@Override public void cloneFrom(OsmPrimitive osm) {
 		super.cloneFrom(osm);
-		segments.clear();
-		segments.addAll(((Way)osm).segments);
+		nodes.clear();
+		nodes.addAll(((Way)osm).nodes);
 	}
 
     @Override public String toString() {
-        return "{Way id="+id+" segments="+Arrays.toString(segments.toArray())+"}";
+        return "{Way id="+id+" nodes="+Arrays.toString(nodes.toArray())+"}";
     }
 
 	@Override public boolean realEqual(OsmPrimitive osm, boolean semanticOnly) {
-		return osm instanceof Way ? super.realEqual(osm, semanticOnly) && segments.equals(((Way)osm).segments) : false;
+		return osm instanceof Way ? super.realEqual(osm, semanticOnly) && nodes.equals(((Way)osm).nodes) : false;
     }
 
@@ -52,8 +64,6 @@
     }
 	
+	@Deprecated
 	public boolean isIncomplete() {
-		for (Segment s : segments)
-			if (s.incomplete)
-				return true;
 		return false;
 	}
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java	(revision 329)
@@ -1,9 +1,7 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
-/**
- */
 package org.openstreetmap.josm.data.osm.visitor;
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -27,9 +25,9 @@
 		ds.nodes.add(n);
 	}
-	public void visit(Segment s) {
-		ds.segments.add(s);
-	}
 	public void visit(Way w) {
 		ds.ways.add(w);
 	}
+	public void visit(Relation e) {
+		ds.relations.add(e);
+	}
 }
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 329)
@@ -5,5 +5,6 @@
 import java.util.HashSet;
 
-import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -30,21 +31,20 @@
 
 	/**
-	 * Line segments have exactly two nodes: from and to.
+	 * Ways have their way nodes.
 	 */
-	public void visit(Segment ls) {
-		if (!ls.incomplete) {
-			visit(ls.from);
-			visit(ls.to);
-		}
+	public void visit(Way w) {
+		for (Node n : w.nodes)
+			visit(n);
 	}
 
 	/**
-	 * Ways have all nodes from their segments.
+	 * Relations may have any number of nodes.
+	 * FIXME: do we want to collect nodes from segs/ways that are relation members?
+	 * if so, use AutomatchVisitor!
 	 */
-	public void visit(Way w) {
-		for (Segment ls : w.segments)
-			visit(ls);
+	public void visit(Relation e) {
+		for (RelationMember m : e.members)
+			if (m.member instanceof Node) visit((Node)m.member);
 	}
-
 	/**
 	 * @return All nodes the given primitive has.
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 329)
@@ -5,5 +5,5 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -22,14 +22,11 @@
 	}
 
-	public void visit(Segment ls) {
-		if (!ls.incomplete) {
-			visit(ls.from);
-			visit(ls.to);
-		}
+	public void visit(Way w) {
+		for (Node n : w.nodes)
+			visit(n);
 	}
 
-	public void visit(Way w) {
-		for (Segment ls : w.segments)
-			visit(ls);
+	public void visit(Relation e) {
+		// relations have no bounding box.
 	}
 
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java	(revision 329)
@@ -6,5 +6,6 @@
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -12,6 +13,5 @@
 
 /**
- * Helper that collect all segments a node is part of, all ways
- * a node or segment is part of and all areas a node is part of. 
+ * Helper that collect all ways a node is part of.
  * 
  * Deleted objects are not collected.
@@ -41,28 +41,36 @@
 			if (w.deleted)
 				continue;
-			for (Segment ls : w.segments) {
-				if (ls.incomplete)
-					continue;
-				if (ls.from == n || ls.to == n) {
+			for (Node n2 : w.nodes) {
+				if (n == n2) {
 					data.add(w);
+				}
+			}
+		}
+		checkRelationMembership(n);
+	}
+	
+	public void visit(Way w) {
+		checkRelationMembership(w);
+	}
+	
+	public void visit(Relation r) {
+		checkRelationMembership(r);
+	}
+	
+	private void checkRelationMembership(OsmPrimitive p) {
+		// FIXME - this might be a candidate for optimisation 
+		// if OSM primitives are made to hold a list of back
+		// references.
+		for (Relation r : ds.relations) {
+			for (RelationMember m : r.members) {
+				if (m.member == p) {
+					data.add(r);
+					// move up the tree (there might be relations
+					// referring to this relation)
+					checkRelationMembership(r);
 					break;
 				}
 			}
 		}
-		for (Segment ls : ds.segments) {
-			if (ls.deleted || ls.incomplete)
-				continue;
-			if (ls.from == n || ls.to == n)
-				data.add(ls);
-		}
 	}
-	public void visit(Segment ls) {
-		for (Way w : ds.ways) {
-			if (w.deleted)
-				continue;
-			if (w.segments.contains(ls))
-				data.add(w);
-		}
-	}
-	public void visit(Way w) {}
 }
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java	(revision 329)
@@ -1,9 +1,7 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
-/**
- */
 package org.openstreetmap.josm.data.osm.visitor;
 
 import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Segment;
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
@@ -27,9 +25,9 @@
 		ds.nodes.remove(n);
 	}
-	public void visit(Segment ls) {
-		ds.segments.remove(ls);
-	}
 	public void visit(Way w) {
 		ds.ways.remove(w);
 	}
+	public void visit(Relation e) {
+		ds.relations.remove(e);
+	}
 }
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java	(revision 329)
@@ -10,7 +10,8 @@
 
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 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;
 
@@ -25,5 +26,5 @@
 	/**
 	 * Map from primitives in the database to visited primitives. (Attention: The other way 
-	 * round than mergedNodes and mergedSegments)
+	 * round than mergedNodes)
 	 */
 	public Map<OsmPrimitive, OsmPrimitive> conflicts = new HashMap<OsmPrimitive, OsmPrimitive>();
@@ -38,10 +39,4 @@
 	 */
 	private final Map<Node, Node> mergedNodes = new HashMap<Node, Node>();
-	/**
-	 * A list of all segments that got replaced with others.
-	 * Key is the segment in the other's dataset and the value is the one that is now
-	 * in ds.segments.
-	 */
-	private final Map<Segment, Segment> mergedSegments = new HashMap<Segment, Segment>();
 
 	public MergeVisitor(DataSet ds, DataSet mergeds) {
@@ -81,64 +76,14 @@
 
 	/**
-	 * Merge the segment if id matches or if both nodes are the same (and the
-	 * id is zero of either segment). Nodes are the "same" when they @see match
-	 */
-	public void visit(Segment other) {
-		if (mergeAfterId(mergedSegments, ds.segments, other))
-			return;
-
-		Segment my = null;
-		for (Segment ls : ds.segments) {
-			if (match(other, ls) && ((mergeds == null) || (!mergeds.segments.contains(ls)))) {
-				my = ls;
-				break;
-			}
-		}
-		
-		if (my == null)
-			ds.segments.add(other);
-		else if (my.incomplete && !other.incomplete) {
-			mergedSegments.put(other, my);
-			my.cloneFrom(other);
-		} else if (!other.incomplete) {
-			mergedSegments.put(other, my);
-			mergeCommon(my, other);
-			if (my.modified && !other.modified)
-				return;
-			if (!match(my.from, other.from)) {
-				my.from = other.from;
-				my.modified = other.modified;
-			}
-			if (!match(my.to, other.to)) {
-				my.to = other.to;
-				my.modified = other.modified;
-			}
-		}
-	}
-
+	 * Simply calls cloneFrom() for now.
+	 * Might be useful to keep around to facilitate merge with the relations
+	 * branch.
+	 */
 	private <T extends OsmPrimitive> void cloneFromExceptIncomplete(T myOsm, T otherOsm) {
-		if (!(myOsm instanceof Way))
-			myOsm.cloneFrom(otherOsm);
-		else {
-			Way my = (Way)myOsm;
-			Way other = (Way)otherOsm;
-			HashMap<Long, Segment> copy = new HashMap<Long, Segment>();
-			for (Segment s : my.segments)
-				copy.put(s.id, s);
-			my.cloneFrom(other);
-			my.segments.clear();
-			for (Segment s : other.segments) {
-				Segment myS = copy.get(s.id);
-				if (s.incomplete && myS != null && !myS.incomplete) {
-					mergedSegments.put(s, myS);
-					my.segments.add(myS);
-				} else
-					my.segments.add(s);
-			}
-		}
+		myOsm.cloneFrom(otherOsm);
     }
 
 	/**
-	 * Merge the way if id matches or if all segments matches and the
+	 * Merge the way if id matches or if all nodes match and the
 	 * id is zero of either way.
 	 */
@@ -155,8 +100,46 @@
 		}
 		if (my == null) {
-			// Add the way and replace any incomplete segments that we already have
 			ds.ways.add(other);
-			for (Segment s : other.segments) {
-				if (s.incomplete) {
+		} else {
+			mergeCommon(my, other);
+			if (my.modified && !other.modified)
+				return;
+			boolean same = true;
+			Iterator<Node> it = other.nodes.iterator();
+			for (Node n : my.nodes) {
+				if (!match(n, it.next()))
+					same = false;
+			}
+			if (!same) {
+				my.nodes.clear();
+				my.nodes.addAll(other.nodes);
+				my.modified = other.modified;
+			}
+		}
+	}
+
+	/**
+	 * Merge the relation if id matches or if all members match and the
+	 * id of either relation is zero.
+	 */
+	public void visit(Relation other) {
+		if (mergeAfterId(null, ds.relations, other))
+			return;
+
+		Relation my = null;
+		for (Relation e : ds.relations) {
+			if (match(other, e) && ((mergeds == null) || (!mergeds.relations.contains(e)))) {
+				my = e;
+				break;
+			}
+		}
+		
+		if (my == null) {
+			// Add the relation and replace any incomplete segments that we already have
+			ds.relations.add(other);
+			// FIXME unclear!
+			/*
+			for (RelationMember em : other.getMembers()) {
+				if (em.member.incomplete) {
 					for (Segment ourSegment : ds.segments) {
 						if (ourSegment.id == s.id) {
@@ -166,5 +149,5 @@
 					}
 				}
-			}
+			}*/
 		} else {
 			mergeCommon(my, other);
@@ -172,9 +155,16 @@
 				return;
 			boolean same = true;
-			Iterator<Segment> it = other.segments.iterator();
-			for (Segment ls : my.segments) {
-				if (!match(ls, it.next()))
+			if (other.members.size() != my.members.size()) {
 					same = false;
-			}
+			} else {
+				for (RelationMember em : my.members) {
+					if (!other.members.contains(em)) {
+						same = false;
+						break;
+					}
+				}
+			}
+			// FIXME Unclear
+			/*
 			if (!same) {
 				HashMap<Long, Segment> copy = new HashMap<Long, Segment>();
@@ -192,4 +182,5 @@
 				my.modified = other.modified;
 			}
+			*/
 		}
 	}
@@ -200,9 +191,4 @@
 	 */
 	public void fixReferences() {
-		for (Segment s : ds.segments)
-			fixSegment(s);
-		for (OsmPrimitive osm : conflicts.values())
-			if (osm instanceof Segment)
-				fixSegment((Segment)osm);
 		for (Way w : ds.ways)
 			fixWay(w);
@@ -214,31 +200,19 @@
 	private void fixWay(Way w) {
 	    boolean replacedSomething = false;
-	    LinkedList<Segment> newSegments = new LinkedList<Segment>();
-	    for (Segment ls : w.segments) {
-	    	Segment otherLs = mergedSegments.get(ls);
-	    	newSegments.add(otherLs == null ? ls : otherLs);
-	    	if (otherLs != null)
+	    LinkedList<Node> newNodes = new LinkedList<Node>();
+	    for (Node n : w.nodes) {
+	    	Node otherN = mergedNodes.get(n);
+	    	newNodes.add(otherN == null ? n : otherN);
+	    	if (otherN != null)
 	    		replacedSomething = true;
 	    }
 	    if (replacedSomething) {
-	    	w.segments.clear();
-	    	w.segments.addAll(newSegments);
-	    }
-	    for (Segment ls : w.segments)
-	    	fixSegment(ls);
+	    	w.nodes.clear();
+	    	w.nodes.addAll(newNodes);
     }
-
-	private void fixSegment(Segment ls) {
-		
-	    if (mergedNodes.containsKey(ls.from)) 
-	    	ls.from = mergedNodes.get(ls.from);
-	    
-	    if (mergedNodes.containsKey(ls.to))  
-	    	ls.to = mergedNodes.get(ls.to);
-	   
     }
 
 	/**
-	 * @return Whether the nodes matches (in sense of "be mergable").
+	 * @return Whether the nodes match (in sense of "be mergable").
 	 */
 	private boolean match(Node n1, Node n2) {
@@ -249,26 +223,13 @@
 
 	/**
-	 * @return Whether the segments matches (in sense of "be mergable").
-	 */
-	private boolean match(Segment ls1, Segment ls2) {
-		if (ls1.id == ls2.id && ls1.id != 0)
-			return true;
-		//if (ls1.id != 0 && ls2.id != 0)
-		//	return false;
-		if (ls1.incomplete || ls2.incomplete)
-			return false;
-		return match(ls1.from, ls2.from) && match(ls1.to, ls2.to);
-	}
-
-	/**
-	 * @return Whether the ways matches (in sense of "be mergable").
+	 * @return Whether the ways match (in sense of "be mergable").
 	 */
 	private boolean match(Way w1, Way w2) {
 		if (w1.id == 0 || w2.id == 0) {
-			if (w1.segments.size() != w2.segments.size())
-				return false;
-			Iterator<Segment> it = w1.segments.iterator();
-			for (Segment ls : w2.segments)
-				if (!match(ls, it.next()))
+			if (w1.nodes.size() != w2.nodes.size())
+			return false;
+			Iterator<Node> it = w1.nodes.iterator();
+			for (Node n : w2.nodes)
+				if (!match(n, it.next()))
 					return false;
 			return true;
@@ -276,4 +237,22 @@
 		return w1.id == w2.id;
 	}
+	/**
+	 * @return Whether the relations match (in sense of "be mergable").
+	 */
+	private boolean match(Relation w1, Relation w2) {
+		// FIXME this is not perfect yet...
+		if (w1.id == 0 || w2.id == 0) {
+			if (w1.members.size() != w2.members.size())
+				return false;
+			for (RelationMember em : w1.members) {
+				if (!w2.members.contains(em)) {
+					return false;
+				}
+			}
+			return true;
+		}
+		return w1.id == w2.id;
+	}
+
 
 	/**
@@ -327,6 +306,4 @@
 			}
 			if (my.id == other.id && my.id != 0) {
-				if (my instanceof Segment && ((Segment)my).incomplete)
-					return false; // merge always over an incomplete
 				if (my.modified && other.modified) {
 					conflicts.put(my, other);
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/NameVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/NameVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/NameVisitor.java	(revision 329)
@@ -1,4 +1,3 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
-
 package org.openstreetmap.josm.data.osm.visitor;
 
@@ -13,7 +12,7 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Relation;
 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.tools.ImageProvider;
@@ -41,23 +40,4 @@
 	
 	/**
-	 * If the segment has a key named "name", its value is displayed. 
-	 * Otherwise, if it has "id", this is used. If none of these available, 
-	 * "(x1,y1) -> (x2,y2)" is displayed with the nodes coordinates.
-	 */
-	public void visit(Segment ls) {
-		name = ls.get("name");
-		if (name == null) {
-			if (ls.incomplete)
-				name = ls.id == 0 ? tr("new") : ls.id+" ("+tr("unknown")+")";
-			else
-				name = (ls.id==0?"":ls.id+" ")+"("+ls.from.coor.lat()+","+ls.from.coor.lon()+") -> ("+ls.to.coor.lat()+","+ls.to.coor.lon()+")";
-		}
-		addId(ls);
-		icon = ImageProvider.get("data", "segment");
-		trn("segment", "segments", 0); // no marktrn available
-		className = "segment";
-	}
-
-	/**
 	 * If the node has a name-key or id-key, this is displayed. If not, (lat,lon)
 	 * is displayed.
@@ -81,21 +61,24 @@
 		if (name == null) name = w.get("ref");
 		if (name == null) {
-			AllNodesVisitor.getAllNodes(w.segments);
-			Set<Node> nodes = new HashSet<Node>();
-			for (Segment ls : w.segments) {
-				if (!ls.incomplete) {
-					nodes.add(ls.from);
-					nodes.add(ls.to);
-				}
-			}
 			String what = (w.get("highway") != null) ? "highway " : (w.get("railway") != null) ? "railway " : (w.get("waterway") != null) ? "waterway " : "";
-			name = what + trn("{0} node", "{0} nodes", nodes.size(), nodes.size());
+			name = what + trn("{0} node", "{0} nodes", w.nodes.size(), w.nodes.size());
 		}
-		if (w.isIncomplete())
-			name += " ("+tr("incomplete")+")";
 		addId(w);
 		icon = ImageProvider.get("data", "way");
 		trn("way", "ways", 0); // no marktrn available
 		className = "way";
+	}
+	
+	/**
+	 */
+	public void visit(Relation e) {
+		name = e.get("type");
+		// FIXME add names of members
+		if (name == null)
+			name = "relation";
+		addId(e);
+		icon = ImageProvider.get("data", "relation");
+		trn("relation", "relations", 0); // no marktrn available
+		className = "relation";
 	}
 	
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java	(revision 329)
@@ -4,15 +4,13 @@
 import java.awt.Color;
 import java.awt.Graphics;
-import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.geom.GeneralPath;
 import java.awt.geom.Line2D;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
 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.gui.NavigatableComponent;
@@ -30,5 +28,5 @@
 	public final static Color darkblue = new Color(0,0,128);
 	public final static Color darkgreen = new Color(0,128,0);
-	
+
 	/**
 	 * The environment to paint to.
@@ -41,44 +39,11 @@
 	
 	public boolean inactive;
-	
+
 	protected static final double PHI = Math.toRadians(20);
 
-	/**
-	 * Preferences
-	 */
-	protected Color inactiveColor;
-	protected Color selectedColor;
-	protected Color nodeColor;
-	protected Color segmentColor;
-	protected Color dfltWayColor;
-	protected Color incompleteColor;
-	protected Color backgroundColor;
-	protected boolean showDirectionArrow;
-	protected boolean showOrderNumber;
-	
-	/**
-	 * Draw subsequent segments of same color as one Path
-	 */
-	protected Color currentColor = null;
-	protected GeneralPath currrentPath = new GeneralPath();
-	
 	public void visitAll(DataSet data) {
-		inactiveColor = getPreferencesColor("inactive", Color.DARK_GRAY);
-		selectedColor = getPreferencesColor("selected", Color.WHITE);
-		nodeColor = getPreferencesColor("node", Color.RED);
-		segmentColor = getPreferencesColor("segment", darkgreen);
-		dfltWayColor = getPreferencesColor("way", darkblue);
-		incompleteColor = getPreferencesColor("incomplete way", darkerblue);
-		backgroundColor = getPreferencesColor("background", Color.BLACK);
-		showDirectionArrow = Main.pref.getBoolean("draw.segment.direction");
-		showOrderNumber = Main.pref.getBoolean("draw.segment.order_number");
-		
-		for (final OsmPrimitive osm : data.segments)
-			if (!osm.deleted && !osm.selected)
-				osm.visit(this);
 		for (final OsmPrimitive osm : data.ways)
 			if (!osm.deleted && !osm.selected)
 				osm.visit(this);
-		displaySegments(null);	// Flush segment cache before nodes
 		for (final OsmPrimitive osm : data.nodes)
 			if (!osm.deleted && !osm.selected)
@@ -87,5 +52,4 @@
 			if (!osm.deleted)
 				osm.visit(this);
-		displaySegments(null);
 	}
 
@@ -99,25 +63,10 @@
 		Color color = null;
 		if (inactive)
-			color = inactiveColor;
+			color = getPreferencesColor("inactive", Color.DARK_GRAY);
 		else if (n.selected)
-			color = selectedColor;
+			color = getPreferencesColor("selected", Color.WHITE);
 		else
-			color = nodeColor;
+			color = getPreferencesColor("node", Color.RED);
 		drawNode(n, color);
-	}
-
-	/**
-	 * Draw just a line between the points.
-	 * White if selected (as always) or green otherwise.
-	 */
-	public void visit(Segment ls) {
-		Color color;
-		if (inactive)
-			color = inactiveColor;
-		else if (ls.selected)
-			color = selectedColor;
-		else
-			color = segmentColor;
-		drawSegment(ls, color, showDirectionArrow);
 	}
 
@@ -129,32 +78,37 @@
 		Color wayColor;
 		if (inactive)
-			wayColor = inactiveColor;
+			wayColor = getPreferencesColor("inactive", Color.DARK_GRAY);
 		else {
-			wayColor = dfltWayColor;
-			for (Segment ls : w.segments) {
-				if (ls.incomplete) {
-					wayColor = incompleteColor;
-					break;
-				}
-			}
+			wayColor = getPreferencesColor("way", darkblue);
 		}
 
+		boolean showDirectionArrow = Main.pref.getBoolean("draw.segment.direction");
+		boolean showOrderNumber = Main.pref.getBoolean("draw.segment.order_number");
 		int orderNumber = 0;
-		for (Segment ls : w.segments) {
+		Node lastN = null;
+		for (Node n : w.nodes) {
+			if (lastN == null) {
+				lastN = n;
+				continue;
+			}
 			orderNumber++;
-			if (!ls.selected) // selected already in good color
-				drawSegment(ls, w.selected && !inactive ? selectedColor : wayColor, showDirectionArrow);
-			if (!ls.incomplete && showOrderNumber)
-				drawOrderNumber(ls, orderNumber);
+			drawSegment(lastN, n, w.selected && !inactive ? getPreferencesColor("selected", Color.WHITE) : wayColor, showDirectionArrow);
+			if (showOrderNumber)
+				drawOrderNumber(lastN, n, orderNumber);
+			lastN = n;
 		}
 	}
 
+	public void visit(Relation e) {
+		// relations are not drawn.
+	}
 	/**
-	 * Draw an number of the order of the segment within the parents way
+	 * Draw an number of the order of the two consecutive nodes within the
+	 * parents way
 	 */
-	protected void drawOrderNumber(Segment ls, int orderNumber) {
+	protected void drawOrderNumber(Node n1, Node n2, int orderNumber) {
 		int strlen = (""+orderNumber).length();
-		Point p1 = nc.getPoint(ls.from.eastNorth);
-		Point p2 = nc.getPoint(ls.to.eastNorth);
+		Point p1 = nc.getPoint(n1.eastNorth);
+		Point p2 = nc.getPoint(n2.eastNorth);
 		int x = (p1.x+p2.x)/2 - 4*strlen;
 		int y = (p1.y+p2.y)/2 + 4;
@@ -163,5 +117,5 @@
 		if (screen.contains(x,y)) {
 			Color c = g.getColor();
-			g.setColor(backgroundColor);
+			g.setColor(getPreferencesColor("background", Color.BLACK));
 			g.fillRect(x-1, y-12, 8*strlen+1, 14);
 			g.setColor(c);
@@ -188,35 +142,20 @@
 	 * Draw a line with the given color.
 	 */
-	protected void drawSegment(Segment ls, Color col, boolean showDirection) {
-		if (ls.incomplete)
-			return;
-		if (col != currentColor) {
-			displaySegments(col);
-		}
+	protected void drawSegment(Node n1, Node n2, Color col, boolean showDirection) {
+		g.setColor(col);
+		Point p1 = nc.getPoint(n1.eastNorth);
+		Point p2 = nc.getPoint(n2.eastNorth);
 		
-		Point p1 = nc.getPoint(ls.from.eastNorth);
-		Point p2 = nc.getPoint(ls.to.eastNorth);
-		
-		Rectangle screen = g.getClipBounds();		
+		Rectangle screen = g.getClipBounds();
 		Line2D line = new Line2D.Double(p1.x, p1.y, p2.x, p2.y);
 		if (screen.contains(p1.x, p1.y, p2.x, p2.y) || screen.intersectsLine(line))
 		{
-			currrentPath.moveTo(p1.x, p1.y);
-			currrentPath.lineTo(p2.x, p2.y);
+			g.drawLine(p1.x, p1.y, p2.x, p2.y);
 	
 			if (showDirection) {
 				double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
-				currrentPath.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
-				currrentPath.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
-				currrentPath.lineTo(p2.x, p2.y);			}
-		}
-	}
-	
-	protected void displaySegments(Color newColor) {
-		if (currrentPath != null) {
-			g.setColor(currentColor);
-			((Graphics2D) g).draw(currrentPath);
-			currrentPath = new GeneralPath();
-			currentColor = newColor;
+		        g.drawLine(p2.x,p2.y, (int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
+		        g.drawLine(p2.x,p2.y, (int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
+			}
 		}
 	}
Index: branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/Visitor.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/Visitor.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/data/osm/visitor/Visitor.java	(revision 329)
@@ -2,6 +2,6 @@
 package org.openstreetmap.josm.data.osm.visitor;
 
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.Segment;
 import org.openstreetmap.josm.data.osm.Way;
 
@@ -14,5 +14,5 @@
 public interface Visitor {
 	void visit(Node n);
-	void visit(Segment s);
 	void visit(Way w);
+	void visit(Relation e);
 }
Index: branch/0.5/src/org/openstreetmap/josm/gui/ConflictResolver.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/ConflictResolver.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/ConflictResolver.java	(revision 329)
@@ -38,9 +38,6 @@
 import org.openstreetmap.josm.data.conflict.ConflictItem;
 import org.openstreetmap.josm.data.conflict.DeleteConflict;
-import org.openstreetmap.josm.data.conflict.FromConflict;
 import org.openstreetmap.josm.data.conflict.PositionConflict;
 import org.openstreetmap.josm.data.conflict.PropertyConflict;
-import org.openstreetmap.josm.data.conflict.SegmentConflict;
-import org.openstreetmap.josm.data.conflict.ToConflict;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.tools.GBC;
@@ -140,7 +137,4 @@
 		possibleConflicts.add(new DeleteConflict());
 		possibleConflicts.add(new PositionConflict());
-		possibleConflicts.add(new FromConflict());
-		possibleConflicts.add(new ToConflict());
-		possibleConflicts.add(new SegmentConflict());
 		TreeSet<String> allkeys = new TreeSet<String>();
 		for (Entry<OsmPrimitive, OsmPrimitive> e : conflicts.entrySet()) {
Index: branch/0.5/src/org/openstreetmap/josm/gui/GettingStarted.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/GettingStarted.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/GettingStarted.java	(revision 329)
@@ -48,4 +48,12 @@
 		panel = new JPanel(new GridBagLayout());
 		
+		panel.add(new JLabel("<html><h2>You are running a technology preview with support for <i>API 0.5</i>.</h2>" +
+				"<h3>API 0.5 supports object relationships, and segments have been removed.</h3>" +
+				"<h3>This version is hard-coded to use the API 0.5 running on <i>openstreetmap.gryph.de</i> which has data from a recent planet file."+
+				"<br>Please be gentle with that machine and request only moderate bounding boxes.<br>" +
+				"<br>Username and password are also hardcoded, so your real username and password are not transmitted.<br>" +
+		"</h3>"), GBC.eol());
+		
+		addLine("wiki", "Read the [Wiki page on API 0.5]");
 		addGettingStarted();
 		addGettingHelp();
@@ -86,4 +94,6 @@
 		else if (e.getActionCommand().equals("help"))
 			Main.main.menu.help.actionPerformed(e);
+		else if (e.getActionCommand().equals("wiki"))
+			OpenBrowser.displayUrl("http://wiki.openstreetmap.org/index.php?title=OSM_Protocol_Version_0.5");
 		else if (e.getActionCommand().equals("tutorial"))
 			OpenBrowser.displayUrl("http://josm.openstreetmap.de/wiki/TutorialVideos");
Index: branch/0.5/src/org/openstreetmap/josm/gui/MainMenu.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 329)
@@ -18,5 +18,4 @@
 import org.openstreetmap.josm.actions.CombineWayAction;
 import org.openstreetmap.josm.actions.DownloadAction;
-import org.openstreetmap.josm.actions.DownloadIncompleteAction;
 import org.openstreetmap.josm.actions.ExitAction;
 import org.openstreetmap.josm.actions.GpxExportAction;
@@ -26,6 +25,5 @@
 import org.openstreetmap.josm.actions.PreferencesAction;
 import org.openstreetmap.josm.actions.RedoAction;
-import org.openstreetmap.josm.actions.ReorderAction;
-import org.openstreetmap.josm.actions.ReverseSegmentAction;
+import org.openstreetmap.josm.actions.ReverseWayAction;
 import org.openstreetmap.josm.actions.SaveAction;
 import org.openstreetmap.josm.actions.SaveAsAction;
@@ -56,10 +54,9 @@
 	public final OpenAction open = new OpenAction();
 	public final DownloadAction download = new DownloadAction();
-	public final Action reverseSegment = new ReverseSegmentAction();
+	public final Action reverseWay = new ReverseWayAction();
 	public final Action splitWay = new SplitWayAction();
 	public final Action combineWay = new CombineWayAction();
 	public final Action alignInCircle = new AlignInCircleAction();
 	public final Action alignInLine = new AlignInLineAction();
-	public final Action reorder = new ReorderAction();
 	public final Action upload = new UploadAction();
 	public final Action save = new SaveAction(null);
@@ -70,5 +67,4 @@
 	public final HelpAction help = new HelpAction();
 	public final Action about = new AboutAction();
-	public final DownloadIncompleteAction downloadIncomplete = new DownloadIncompleteAction();
 	
 	public final JMenu layerMenu = new JMenu(tr("Layer"));
@@ -117,6 +113,5 @@
 		toolsMenu.add(alignInLine);
 		toolsMenu.addSeparator();
-		toolsMenu.add(reverseSegment);
-		toolsMenu.add(reorder);
+		toolsMenu.add(reverseWay);
 		toolsMenu.addSeparator();
 		toolsMenu.add(splitWay);
@@ -126,5 +121,4 @@
 		connectionMenu.setMnemonic('C');
 		connectionMenu.add(download);
-		connectionMenu.add(downloadIncomplete);
 		connectionMenu.add(upload);
 		add(connectionMenu);
Index: branch/0.5/src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 329)
@@ -15,5 +15,4 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.mapmode.AddSegmentAction;
-import org.openstreetmap.josm.actions.mapmode.AddWayAction;
 import org.openstreetmap.josm.actions.mapmode.DeleteAction;
 import org.openstreetmap.josm.actions.mapmode.MapMode;
@@ -24,4 +23,5 @@
 import org.openstreetmap.josm.gui.dialogs.CommandStackDialog;
 import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
+import org.openstreetmap.josm.gui.dialogs.RelationListDialog;
 import org.openstreetmap.josm.gui.dialogs.HistoryDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
@@ -85,5 +85,4 @@
 		toolBarActions.add(new IconToggleButton(new AddNodeGroup(this)));
 		toolBarActions.add(new IconToggleButton(new AddSegmentAction(this)));
-		toolBarActions.add(new IconToggleButton(new AddWayAction(this)));
 		toolBarActions.add(new IconToggleButton(new DeleteAction(this)));
 
@@ -104,4 +103,5 @@
 		addToggleDialog(conflictDialog = new ConflictDialog());
 		addToggleDialog(new CommandStackDialog(this));
+		addToggleDialog(new RelationListDialog());
 
 		// status line below the map
Index: branch/0.5/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 329)
@@ -126,5 +126,5 @@
 					OsmPrimitive osmNearest = null;
 					// Set the text label in the bottom status bar
-					osmNearest = mv.getNearest(ms.mousePos, (ms.modifiers & MouseEvent.ALT_DOWN_MASK) != 0);
+					osmNearest = mv.getNearest(ms.mousePos);
 					if (osmNearest != null) {
 						NameVisitor visitor = new NameVisitor();
Index: branch/0.5/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/MapView.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/MapView.java	(revision 329)
@@ -85,5 +85,5 @@
 
 		// listend to selection changes to redraw the map
-		DataSet.listeners.add(new SelectionChangedListener(){
+		DataSet.selListeners.add(new SelectionChangedListener(){
 			public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
 				repaint();
Index: branch/0.5/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 329)
@@ -4,7 +4,5 @@
 import java.awt.Point;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 
 import javax.swing.JComponent;
@@ -16,6 +14,6 @@
 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.WaySegment;
 import org.openstreetmap.josm.data.projection.Projection;
 
@@ -147,17 +145,32 @@
 
 	/**
-	 * @return the nearest way to the screen point given.
-	 */
-	public final Way getNearestWay(Point p) {
+	 * @return the nearest way segment to the screen point given that is not 
+	 * in ignore.
+	 * 
+	 * @param p the point for which to search the nearest segment.
+	 * @param ignore a collection of segments which are not to be returned.
+	 * May be null.
+	 */
+	public final WaySegment getNearestWaySegment(Point p, Collection<WaySegment> ignore) {
 		Way minPrimitive = null;
+		int minI = 0;
 		double minDistanceSq = Double.MAX_VALUE;
 		for (Way w : Main.ds.ways) {
 			if (w.deleted)
 				continue;
-			for (Segment ls : w.segments) {
-				if (ls.deleted || ls.incomplete)
+			Node lastN = null;
+			int i = -2;
+			for (Node n : w.nodes) {
+				i++;
+				if (n.deleted) continue;
+				if (lastN == null) {
+					lastN = n;
 					continue;
-				Point A = getPoint(ls.from.eastNorth);
-				Point B = getPoint(ls.to.eastNorth);
+				}
+				if (ignore != null && ignore.contains(new WaySegment(w, i))) {
+					continue;
+				}
+				Point A = getPoint(lastN.eastNorth);
+				Point B = getPoint(n.eastNorth);
 				double c = A.distanceSq(B);
 				double a = p.distanceSq(B);
@@ -167,46 +180,25 @@
 					minDistanceSq = perDist;
 					minPrimitive = w;
-				}
+					minI = i;
+				}
+				lastN = n;
 			}
 		}
-		return minPrimitive;
-	}
-
-	/**
-	 * @return the nearest segment to the screen point given 
-	 * 
-	 * @param p the point for which to search the nearest segment.
-	 */
-	public final Segment getNearestSegment(Point p) {
-		List<Segment> e = Collections.emptyList();
-		return getNearestSegment(p, e);
+		return minPrimitive == null ? null : new WaySegment(minPrimitive, minI);
+	}
+
+	/**
+	 * @return the nearest way segment to the screen point given.
+	 */
+	public final WaySegment getNearestWaySegment(Point p) {
+		return getNearestWaySegment(p, null);
 	}
 	
 	/**
-	 * @return the nearest segment to the screen point given that is not 
-	 * in ignoreThis.
-	 * 
-	 * @param p the point for which to search the nearest segment.
-	 * @param ignore a collection of segments which are not to be returned. Must not be null.
-	 */
-	public final Segment getNearestSegment(Point p, Collection<Segment> ignore) {
-		Segment minPrimitive = null;
-		double minDistanceSq = Double.MAX_VALUE;
-		// segments
-		for (Segment ls : Main.ds.segments) {
-			if (ls.deleted || ls.incomplete || ignore.contains(ls))
-				continue;
-			Point A = getPoint(ls.from.eastNorth);
-			Point B = getPoint(ls.to.eastNorth);
-			double c = A.distanceSq(B);
-			double a = p.distanceSq(B);
-			double b = p.distanceSq(A);
-			double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
-			if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
-				minDistanceSq = perDist;
-				minPrimitive = ls;
-			}
-		}
-		return minPrimitive;
+	 * @return the nearest way to the screen point given.
+	 */
+	public final Way getNearestWay(Point p) {
+		WaySegment nearestWaySeg = getNearestWaySegment(p);
+		return nearestWaySeg == null ? null : nearestWaySeg.way;
     }
 
@@ -217,43 +209,26 @@
 	 * nearest node is returned.
 	 *
-	 * If no node is found, search for pending segments.
-	 *
-	 * If no such segment is found, and a non-pending segment is
-	 * within 10 pixel to p, this segment is returned, except when
-	 * <code>wholeWay</code> is <code>true</code>, in which case the
-	 * corresponding Way is returned.
-	 *
-	 * If no segment is found and the point is within an area, return that
-	 * area.
-	 *
-	 * If no area is found, return <code>null</code>.
+	 * If no node is found, search for near ways.
+	 *
+	 * If nothing is found, return <code>null</code>.
 	 *
 	 * @param p				 The point on screen.
-	 * @param segmentInsteadWay Whether the segment (true) or only the whole
-	 * 					 	 way should be returned.
 	 * @return	The primitive, that is nearest to the point p.
 	 */
+	public OsmPrimitive getNearest(Point p) {
+		OsmPrimitive osm = getNearestNode(p);
+		if (osm == null)
+			osm = getNearestWay(p);
+		return osm;
+	}
+
+	@Deprecated
 	public OsmPrimitive getNearest(Point p, boolean segmentInsteadWay) {
-		OsmPrimitive osm = getNearestNode(p);
-		if (osm == null && !segmentInsteadWay)
-			osm = getNearestWay(p);
-		if (osm == null)
-			osm = getNearestSegment(p);
-		return osm;
+		return getNearest(p);
 	}
 
 	/**
 	 * @return A list of all objects that are nearest to
-	 * the mouse. To do this, first the nearest object is
-	 * determined.
-	 *
-	 * If its a node, return all segments and
-	 * streets the node is part of, as well as all nodes
-	 * (with their segments and ways) with the same
-	 * location.
-	 *
-	 * If its a segment, return all ways this segment
-	 * belongs to as well as all segments that are between
-	 * the same nodes (in both direction) with all their ways.
+	 * the mouse.  Does a simple sequential scan on all the data.
 	 *
 	 * @return A collection of all items or <code>null</code>
@@ -262,38 +237,33 @@
 	 */
 	public Collection<OsmPrimitive> getAllNearest(Point p) {
-		OsmPrimitive osm = getNearest(p, true);
-		if (osm == null)
-			return null;
-		Collection<OsmPrimitive> c = new HashSet<OsmPrimitive>();
-		c.add(osm);
-		if (osm instanceof Node) {
-			Node node = (Node)osm;
-			for (Node n : Main.ds.nodes)
-				if (!n.deleted && n.coor.equals(node.coor))
-					c.add(n);
-			for (Segment ls : Main.ds.segments)
-				// segments never match nodes, so they are skipped by contains
-				if (!ls.deleted && !ls.incomplete && (c.contains(ls.from) || c.contains(ls.to)))
-					c.add(ls);
-		}
-		if (osm instanceof Segment) {
-			Segment line = (Segment)osm;
-			for (Segment ls : Main.ds.segments)
-				if (!ls.deleted && ls.equalPlace(line))
-					c.add(ls);
-		}
-		if (osm instanceof Node || osm instanceof Segment) {
+		Collection<OsmPrimitive> nearest = new HashSet<OsmPrimitive>();
 			for (Way w : Main.ds.ways) {
-				if (w.deleted)
+			if (w.deleted) continue;
+			Node lastN = null;
+			for (Node n : w.nodes) {
+				if (n.deleted) continue;
+				if (lastN == null) {
+					lastN = n;
 					continue;
-				for (Segment ls : w.segments) {
-					if (!ls.deleted && !ls.incomplete && c.contains(ls)) {
-						c.add(w);
+				}
+				Point A = getPoint(lastN.eastNorth);
+				Point B = getPoint(n.eastNorth);
+				double c = A.distanceSq(B);
+				double a = p.distanceSq(B);
+				double b = p.distanceSq(A);
+				double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
+				if (perDist < 100 && a < c+100 && b < c+100) {
+					nearest.add(w);
 						break;
 					}
-				}
+				lastN = n;
+				}
+			}
+		for (Node n : Main.ds.nodes) {
+			if (!n.deleted && getPoint(n.eastNorth).distanceSq(p) < 100) {
+				nearest.add(n);
 			}
 		}
-		return c;
+		return nearest.isEmpty() ? null : nearest;
 	}
 
Index: branch/0.5/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java	(revision 329)
@@ -5,5 +5,10 @@
 
 import javax.swing.DefaultListCellRenderer;
+import javax.swing.JLabel;
 import javax.swing.JList;
+import javax.swing.JTable;
+import javax.swing.ListCellRenderer;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -12,18 +17,58 @@
 /**
  * Renderer that renders the objects from an OsmPrimitive as data.
+ * 
+ * Can be used in lists and tables.
+ * 
  * @author imi
+ * @author Frederik Ramm <frederik@remote.org>
  */
-public class OsmPrimitivRenderer extends DefaultListCellRenderer {
+public class OsmPrimitivRenderer implements ListCellRenderer, TableCellRenderer {
 
+	/**
+	 * NameVisitor provides proper names and icons for OsmPrimitives
+	 */
 	private NameVisitor visitor = new NameVisitor();
 
-	@Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
-		super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
-		if (value != null) {
+	/**
+	 * Default list cell renderer - delegate for ListCellRenderer operation
+	 */
+	private DefaultListCellRenderer defaultListCellRenderer = new DefaultListCellRenderer();
+	
+	/**
+	 * Default table cell renderer - delegate for TableCellRenderer operation
+	 */
+	private DefaultTableCellRenderer defaultTableCellRenderer = new DefaultTableCellRenderer();
+
+	/**
+	 * Adapter method supporting the ListCellRenderer interface.
+	 */
+	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+		Component def = defaultListCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+		return renderer(def, (OsmPrimitive) value);
+	}
+
+	/**
+	 * Adapter method supporting the TableCellRenderer interface. 
+	 */
+	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+		Component def = defaultTableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+		return renderer(def, (OsmPrimitive) value);
+	}
+	
+	/**
+	 * Internal method that stuffs information into the rendering component
+	 * provided that it's a kind of JLabel.
+	 * @param def the rendering component
+	 * @param value the OsmPrimtive to render
+	 * @return the modified rendering component
+	 */
+	private Component renderer(Component def, OsmPrimitive value) {
+		if (def != null && value != null && def instanceof JLabel) {
 			((OsmPrimitive)value).visit(visitor);
-			setText(visitor.name);
-			setIcon(visitor.icon);
+			((JLabel)def).setText(visitor.name);
+			((JLabel)def).setIcon(visitor.icon);
 		}
-		return this;
+		return def;
 	}
+	
 }
Index: branch/0.5/src/org/openstreetmap/josm/gui/SelectionManager.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 329)
@@ -25,5 +25,4 @@
 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;
 
@@ -282,6 +281,5 @@
 	 * modifier.
 	 * @param alt Whether the alt key was pressed, which means select all objects
-	 * 		that are touched, instead those which are completly covered. Also 
-	 * 		select whole ways instead of segments.
+	 * 		that are touched, instead those which are completly covered.
 	 */
 	public Collection<OsmPrimitive> getObjectsInRectangle(Rectangle r, boolean alt) {
@@ -293,5 +291,5 @@
 
 		if (clicked) {
-			OsmPrimitive osm = nc.getNearest(center, alt);
+			OsmPrimitive osm = nc.getNearest(center);
 			if (osm != null)
 				selection.add(osm);
@@ -303,54 +301,28 @@
 			}
 			
-			// pending segments
-			for (Segment s : Main.ds.segments)
-				if (!s.deleted && rectangleContainSegment(r, alt, s))
-					selection.add(s);
-
 			// ways
 			for (Way w : Main.ds.ways) {
-				if (w.deleted)
-					continue;
-				boolean someSelectableSegment = false;
-				boolean wholeWaySelected = true;
-				for (Segment s : w.segments) {
-					if (s.incomplete)
+				if (w.deleted || w.nodes.isEmpty())
 						continue;
-					someSelectableSegment = true;
-					if (!rectangleContainSegment(r, alt, s)) {
-						wholeWaySelected = false;
+				if (alt) {
+					for (Node n : w.nodes) {
+						if (r.contains(nc.getPoint(n.eastNorth))) {
+							selection.add(w);
 						break;
 					}
 				}
-				if (someSelectableSegment && wholeWaySelected)
-					selection.add(w);
+				} else {
+					boolean allIn = true;
+					for (Node n : w.nodes) {
+						if (!r.contains(nc.getPoint(n.eastNorth))) {
+							allIn = false;
+							break;
 			}
 		}
+					if (allIn) selection.add(w);
+				}
+	}
+		}
 		return selection;
-	}
-
-	/**
-	 * Decide whether the segment is in the rectangle Return 
-	 * <code>true</code>, if it is in or false if not.
-	 * 
-	 * @param r			The rectangle, in which the segment has to be.
-	 * @param alt		Whether user pressed the Alt key
-	 * @param ls		The segment.
-	 * @return <code>true</code>, if the Segment was added to the selection.
-	 */
-	private boolean rectangleContainSegment(Rectangle r, boolean alt, Segment ls) {
-		if (ls.incomplete)
-			return false;
-		if (alt) {
-			Point p1 = nc.getPoint(ls.from.eastNorth);
-			Point p2 = nc.getPoint(ls.to.eastNorth);
-			if (r.intersectsLine(p1.x, p1.y, p2.x, p2.y))
-				return true;
-		} else {
-			if (r.contains(nc.getPoint(ls.from.eastNorth))
-					&& r.contains(nc.getPoint(ls.to.eastNorth)))
-				return true;
-		}
-		return false;
 	}
 	
Index: branch/0.5/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 329)
@@ -33,7 +33,8 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 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.SimplePaintVisitor;
@@ -88,5 +89,5 @@
 		add(buttonPanel, BorderLayout.SOUTH);
 
-		DataSet.listeners.add(new SelectionChangedListener(){
+		DataSet.selListeners.add(new SelectionChangedListener(){
 			public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
 				displaylist.clearSelection();
@@ -130,7 +131,4 @@
 				model.addElement(osm);
 		for (OsmPrimitive osm : this.conflicts.keySet())
-			if (osm instanceof Segment)
-				model.addElement(osm);
-		for (OsmPrimitive osm : this.conflicts.keySet())
 			if (osm instanceof Way)
 				model.addElement(osm);
@@ -155,14 +153,23 @@
 				g.drawRect(p.x-1, p.y-1, 2, 2);
 			}
-			public void visit(Segment ls) {
-				if (ls.incomplete)
-					return;
-				Point p1 = nc.getPoint(ls.from.eastNorth);
-				Point p2 = nc.getPoint(ls.to.eastNorth);
+			public void visit(Node n1, Node n2) {
+				Point p1 = nc.getPoint(n1.eastNorth);
+				Point p2 = nc.getPoint(n2.eastNorth);
 				g.drawLine(p1.x, p1.y, p2.x, p2.y);
 			}
 			public void visit(Way w) {
-				for (Segment ls : w.segments)
-					visit(ls);
+				Node lastN = null;
+				for (Node n : w.nodes) {
+					if (lastN == null) {
+						lastN = n;
+						continue;
+					}
+					visit(lastN, n);
+					lastN = n;
+				}
+			}
+			public void visit(Relation e) {
+				for (RelationMember em : e.members)
+					em.member.visit(this);
 			}
 		};
Index: branch/0.5/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java	(revision 329)
@@ -144,5 +144,5 @@
 		revertButton.putClientProperty("help", "Dialog/History/Revert");
 		
-		DataSet.listeners.add(this);
+		DataSet.selListeners.add(this);
 	}
 
Index: branch/0.5/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 329)
@@ -48,8 +48,11 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.preferences.TaggingPresetPreference;
+import org.openstreetmap.josm.gui.tagging.ForwardActionListener;
 import org.openstreetmap.josm.gui.tagging.TaggingCellRenderer;
-import org.openstreetmap.josm.gui.tagging.ForwardActionListener;
 import org.openstreetmap.josm.gui.tagging.TaggingPreset;
 import org.openstreetmap.josm.tools.AutoCompleteComboBox;
@@ -77,4 +80,9 @@
 
 	/**
+	 * Used to display relation names in the membership table
+	 */
+	private NameVisitor nameVisitor = new NameVisitor();
+	
+	/**
 	 * Watches for double clicks and from editing or new property, depending on the
 	 * location, the click was.
@@ -85,19 +93,29 @@
 			if (e.getClickCount() < 2)
 				return;
-			if (e.getSource() instanceof JScrollPane)
-				add();
-			else {
+	
+			if (e.getSource() == propertyTable)
+			{
 				int row = propertyTable.rowAtPoint(e.getPoint());
-				edit(row);
-			}
-		}
-	}
-
-	/**
-	 * Edit the value in the table row
-	 * @param row 	The row of the table, from which the value is edited.
-	 */
-	void edit(int row) {
-		String key = data.getValueAt(row, 0).toString();
+				if (row > -1) {
+					propertyEdit(row);
+					return;
+			}
+			} else if (e.getSource() == membershipTable) {
+				int row = membershipTable.rowAtPoint(e.getPoint());
+				if (row > -1) {
+					membershipEdit(row);
+					return;
+				}
+			}
+			add();
+		}
+	}
+
+	/**
+	 * Edit the value in the properties table row
+	 * @param row The row of the table from which the value is edited.
+	 */
+	void propertyEdit(int row) {
+		String key = propertyData.getValueAt(row, 0).toString();
 		Collection<OsmPrimitive> sel = Main.ds.getSelected();
 		if (sel.isEmpty()) {
@@ -118,17 +136,17 @@
 		p.add(keyField, GBC.eol().fill(GBC.HORIZONTAL));
 				
-		final JComboBox combo = (JComboBox)data.getValueAt(row, 1);
+		final JTextField valueField = new JTextField((String)propertyData.getValueAt(row, 1));
 		p.add(new JLabel(tr("Value")), GBC.std());
 		p.add(Box.createHorizontalStrut(10), GBC.std());
-		p.add(combo, GBC.eol().fill(GBC.HORIZONTAL));
+		p.add(valueField, GBC.eol().fill(GBC.HORIZONTAL));
 
 		final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION){
 			@Override public void selectInitialValue() {
-				combo.requestFocusInWindow();
-				combo.getEditor().selectAll();
+				valueField.requestFocusInWindow();
+				valueField.selectAll();
 			}
 		};
 		final JDialog dlg = optionPane.createDialog(Main.parent, tr("Change values?"));
-		combo.getEditor().addActionListener(new ActionListener(){
+		valueField.addActionListener(new ActionListener(){
 			public void actionPerformed(ActionEvent e) {
 				optionPane.setValue(JOptionPane.OK_OPTION);
@@ -136,5 +154,4 @@
 			}
 		});
-		String oldComboEntry = combo.getEditor().getItem().toString();
 		dlg.setVisible(true);
 
@@ -142,9 +159,8 @@
 		if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE ||
 				(answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION)) {
-			combo.getEditor().setItem(oldComboEntry);
-			return;
-		}
-
-		String value = combo.getEditor().getItem().toString();
+			return;
+		}
+
+		String value = valueField.getText();
 		if (value.equals(tr("<different>")))
 			return;
@@ -164,8 +180,17 @@
 		}
 
-		if (!key.equals(newkey) || value == null)
 			selectionChanged(sel); // update whole table
-
 		Main.parent.repaint(); // repaint all - drawing could have been changed
+	}
+
+	/**
+	 * This simply fires up an relation editor for the relation shown; everything else
+	 * is the editor's business.
+	 * 
+	 * @param row
+	 */
+	void membershipEdit(int row) {	
+		final RelationEditor editor = new RelationEditor((Relation)membershipData.getValueAt(row, 0));
+		editor.setVisible(true);
 	}
 
@@ -197,6 +222,6 @@
 			}
 		}
-		for (int i = 0; i < data.getRowCount(); ++i)
-			allData.remove(data.getValueAt(i, 0));
+		for (int i = 0; i < propertyData.getRowCount(); ++i)
+			allData.remove(propertyData.getValueAt(i, 0));
 		final AutoCompleteComboBox keys = new AutoCompleteComboBox();
 		keys.setPossibleItems(allData.keySet());
@@ -249,5 +274,5 @@
 	 */
 	private void delete(int row) {
-		String key = data.getValueAt(row, 0).toString();
+		String key = propertyData.getValueAt(row, 0).toString();
 		Collection<OsmPrimitive> sel = Main.ds.getSelected();
 		Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, null));
@@ -258,16 +283,31 @@
 	 * The property data.
 	 */
-	private final DefaultTableModel data = new DefaultTableModel(){
+	private final DefaultTableModel propertyData = new DefaultTableModel() {
 		@Override public boolean isCellEditable(int row, int column) {
 			return false;
 		}
 		@Override public Class<?> getColumnClass(int columnIndex) {
-			return columnIndex == 1 ? JComboBox.class : String.class;
+			return String.class;
 		}
 	};
+
+	/**
+	 * The membership data.
+	 */
+	private final DefaultTableModel membershipData = new DefaultTableModel() {
+		@Override public boolean isCellEditable(int row, int column) {
+			return false;
+		}
+		@Override public Class<?> getColumnClass(int columnIndex) {
+			return columnIndex == 1 ? Relation.class : String.class;
+		}
+	};
+	
 	/**
 	 * The properties list.
 	 */
-	private final JTable propertyTable = new JTable(data);
+	private final JTable propertyTable = new JTable(propertyData);
+	private final JTable membershipTable = new JTable(membershipData);
+
 	public JComboBox taggingPresets = new JComboBox();
 
@@ -277,5 +317,5 @@
 	 */
 	public PropertiesDialog(MapFrame mapFrame) {
-		super(tr("Properties"), "propertiesdialog", tr("Properties for selected objects."), KeyEvent.VK_P, 150);
+		super(tr("Properties/Memberships"), "propertiesdialog", tr("Properties for selected objects."), KeyEvent.VK_P, 150);
 
 		if (TaggingPresetPreference.taggingPresets.size() > 0) {
@@ -300,11 +340,14 @@
 		taggingPresets.setRenderer(new TaggingCellRenderer());
 
-		data.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
+		// setting up the properties table
+		
+		propertyData.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
 		propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-		propertyTable.setDefaultRenderer(JComboBox.class, new DefaultTableCellRenderer(){
+	
+		propertyTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer(){
 			@Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 				Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
 				if (c instanceof JLabel) {
-					String str = ((JComboBox)value).getEditor().getItem().toString();
+					String str = (String) value;
 					((JLabel)c).setText(str);
 					if (str.equals(tr("<different>")))
@@ -314,12 +357,33 @@
 			}
 		});
-		propertyTable.setDefaultRenderer(String.class, new DefaultTableCellRenderer(){
+		
+		// setting up the membership table
+		
+		membershipData.setColumnIdentifiers(new String[]{tr("Member Of"),tr("Role")});
+		membershipTable.setRowSelectionAllowed(false);
+		
+		membershipTable.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
 			@Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
-				return super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
+				Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
+				if (c instanceof JLabel) {
+					nameVisitor.visit((Relation)value);
+					((JLabel)c).setText(nameVisitor.name);
+				}
+				return c;
 			}
 		});
+		
+		// combine both tables and wrap them in a scrollPane
+		JPanel bothTables = new JPanel();
+		bothTables.setLayout(new GridBagLayout());
+		bothTables.add(propertyTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
+		bothTables.add(propertyTable, GBC.eol().fill(GBC.BOTH));
+		bothTables.add(membershipTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
+		bothTables.add(membershipTable, GBC.eol().fill(GBC.BOTH));
+		
 		DblClickWatch dblClickWatch = new DblClickWatch();
 		propertyTable.addMouseListener(dblClickWatch);
-		JScrollPane scrollPane = new JScrollPane(propertyTable);
+		membershipTable.addMouseListener(dblClickWatch);
+		JScrollPane scrollPane = new JScrollPane(bothTables);
 		scrollPane.addMouseListener(dblClickWatch);
 		add(scrollPane, BorderLayout.CENTER);
@@ -335,5 +399,5 @@
 						JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to edit."));
 					else
-						edit(sel);
+						propertyEdit(sel);
 				} else if (e.getActionCommand().equals("Delete")) {
 					if (sel == -1)
@@ -344,4 +408,5 @@
 			}
 		};
+		
 		buttonPanel.add(createButton(marktr("Add"),tr("Add a new key/value pair to all objects"), KeyEvent.VK_A, buttonAction));
 		buttonPanel.add(createButton(marktr("Edit"),tr( "Edit the value of the selected key for all objects"), KeyEvent.VK_E, buttonAction));
@@ -349,5 +414,5 @@
 		add(buttonPanel, BorderLayout.SOUTH);
 
-		DataSet.listeners.add(this);
+		DataSet.selListeners.add(this);
 	}
 
@@ -375,5 +440,8 @@
 		if (propertyTable.getCellEditor() != null)
 			propertyTable.getCellEditor().cancelCellEditing();
-		data.setRowCount(0);
+
+		// re-load property data
+		
+		propertyData.setRowCount(0);
 
 		Map<String, Integer> valueCount = new HashMap<String, Integer>();
@@ -391,8 +459,36 @@
 		}
 		for (Entry<String, Collection<String>> e : props.entrySet()) {
-			JComboBox value = new JComboBox(e.getValue().toArray());
-			value.setEditable(true);
-			value.getEditor().setItem(e.getValue().size() > 1 || valueCount.get(e.getKey()) != newSelection.size() ? tr("<different>") : e.getValue().iterator().next());
-			data.addRow(new Object[]{e.getKey(), value});
+			String value=(e.getValue().size() > 1 || valueCount.get(e.getKey()) != newSelection.size() ? tr("<different>") : e.getValue().iterator().next());
+			propertyData.addRow(new Object[]{e.getKey(), value});
+		}
+		
+		// re-load membership data
+		// this is rather expensive since we have to walk through all members of all existing relationships.
+		// could use back references here for speed if necessary.
+		
+		membershipData.setRowCount(0);
+		
+		Map<Relation, Integer> valueCountM = new HashMap<Relation, Integer>();
+		TreeMap<Relation, Collection<String>> roles = new TreeMap<Relation, Collection<String>>();
+		for (Relation r : Main.ds.relations) {
+			for (RelationMember m : r.members) {
+				if (newSelection.contains(m.member)) {
+					Collection<String> value = roles.get(r);
+					if (value == null) {
+						value = new TreeSet<String>();
+						roles.put(r, value);
+					}
+					value.add(m.role);
+					valueCountM.put(r, valueCount.containsKey(r) ? valueCount.get(r)+1 : 1);
+				}
+			}
+		}
+		
+		for (Entry<Relation, Collection<String>> e : roles.entrySet()) {
+			//JComboBox value = new JComboBox(e.getValue().toArray());
+			//value.setEditable(true);
+			//value.getEditor().setItem(e.getValue().size() > 1 || valueCount.get(e.getKey()) != newSelection.size() ? tr("<different>") : e.getValue().iterator().next());
+			String value = e.getValue().size() > 1 || valueCountM.get(e.getKey()) != newSelection.size() ? tr("<different>") : e.getValue().iterator().next();
+			membershipData.addRow(new Object[]{e.getKey(), value});
 		}
 	}
Index: branch/0.5/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 329)
@@ -80,5 +80,5 @@
 		selectionChanged(Main.ds.getSelected());
 
-		DataSet.listeners.add(this);
+		DataSet.selListeners.add(this);
 	}
 
Index: branch/0.5/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 329)
@@ -54,5 +54,5 @@
 		selectionChanged(Main.ds.getSelected());
 		
-		DataSet.listeners.add(this);
+		DataSet.selListeners.add(this);
 	}
 
Index: branch/0.5/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 329)
@@ -34,7 +34,7 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DataSource;
+import org.openstreetmap.josm.data.osm.Relation;
 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.BoundingXYVisitor;
@@ -60,5 +60,5 @@
 		public final int[] normal = new int[3];		
 		public final int[] deleted = new int[3];
-		public final String[] names = {"node", "segment", "way"};
+		public final String[] names = {"node", "way", "relation"};
 
 		private void inc(final OsmPrimitive osm, final int i) {
@@ -72,9 +72,8 @@
 		}
 
-		public void visit(final Segment ls) {
-			inc(ls, 1);
-		}
-
 		public void visit(final Way w) {
+			inc(w, 1);
+		}
+		public void visit(final Relation w) {
 			inc(w, 2);
 		}
@@ -133,5 +132,5 @@
 	 * Draw all primitives in this layer but do not draw modified ones (they
 	 * are drawn by the edit layer).
-	 * Draw nodes last to overlap the segments they belong to.
+	 * Draw nodes last to overlap the ways they belong to.
 	 */
 	@Override public void paint(final Graphics g, final MapView mv) {
@@ -163,5 +162,4 @@
 		String tool = "";
 		tool += undeletedSize(data.nodes)+" "+trn("node", "nodes", undeletedSize(data.nodes))+", ";
-		tool += undeletedSize(data.segments)+" "+trn("segment", "segments", undeletedSize(data.segments))+", ";
 		tool += undeletedSize(data.ways)+" "+trn("way", "ways", undeletedSize(data.ways));
 		if (associatedFile != null)
@@ -222,6 +220,4 @@
 			for (final Iterator<Node> it = data.nodes.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
-			for (final Iterator<Segment> it = data.segments.iterator(); it.hasNext();)
-				cleanIterator(it, processedSet);
 			for (final Iterator<Way> it = data.ways.iterator(); it.hasNext();)
 				cleanIterator(it, processedSet);
Index: branch/0.5/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java	(revision 329)
@@ -38,5 +38,4 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 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.BoundingXYVisitor;
@@ -71,14 +70,8 @@
 			for (Collection<GpsPoint> c : data) {
 				Way w = new Way();
-				Node start = null;
 				for (GpsPoint p : c) {
-					Node end = new Node(p.latlon);
-					ds.nodes.add(end);
-					if (start != null) {
-						Segment segment = new Segment(start,end);
-						w.segments.add(segment);
-						ds.segments.add(segment);
-					}
-					start = end;
+					Node n = new Node(p.latlon);
+					ds.nodes.add(n);
+					w.nodes.add(n);
 				}
 				ds.ways.add(w);
Index: branch/0.5/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 329)
@@ -103,5 +103,5 @@
     		Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
     		final DataSet data = OsmReader.parseDataSet(in, null, Main.pleaseWaitDlg);
-    		String origin = Main.pref.get("osm-server.url")+"/"+Main.pref.get("osm-server.version", "0.4");
+    		String origin = Main.pref.get("osm-server.url")+"/"+Main.pref.get("osm-server.version", "0.5");
     		Bounds bounds = new Bounds(new LatLon(lat1, lon1), new LatLon(lat2, lon2));
 			DataSource src = new DataSource(bounds, origin);
Index: branch/0.5/src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 329)
@@ -11,5 +11,4 @@
 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.gui.layer.RawGpsLayer.GpsPoint;
@@ -32,9 +31,6 @@
 
 	/**
-	 * Export the dataset to gpx. Only the physical segment structure is
-	 * exported. To do this, the list of ways is processed. If a way span a 
-	 * sequence of segments, this is added as one trkseg.
-	 * Then, all remaining segments are added in one extra trk. Finally,
-	 * all remaining nodes are added as wpt.
+	 * Export the dataset to gpx.  The ways are converted to trksegs, each in
+	 * a seperate trk.  Finally, all remaining nodes are added as wpt.
 	 */
 	public static final class All implements XmlWriter.OsmWriterInterface {
@@ -106,50 +102,12 @@
 					continue;
 				out.println("  <trk>");
-				Segment oldLs = null;
-				for (Segment ls : w.segments) {
-					if (ls.incomplete)
-						continue;
-					// end old segemnt, if no longer match a chain
-					if (oldLs != null && !oldLs.to.coor.equals(ls.from.coor)) {
-						out.println("    </trkseg>");
-						writer.outputNode(oldLs.to, false);
-						all.remove(oldLs.to);
-						oldLs = null;
-					}
-					// start new segment if necessary
-					if (oldLs == null)
 						out.println("    <trkseg>");
-					writer.outputNode(ls.from, false);
-					all.remove(ls.from);
-					oldLs = ls;
-					all.remove(ls);
-				}
-				// write last node if there
-				if (oldLs != null) {
-					writer.outputNode(oldLs.to, false);
-					all.remove(oldLs.to);
+				for (Node n : w.nodes) {
+					writer.outputNode(n, false);
+					all.remove(n);
+			}
 					out.println("    </trkseg>");
-				}
 				out.println("  </trk>");
 				all.remove(w);
-			}
-
-			// add remaining segments
-			Collection<Segment> segments = new LinkedList<Segment>();
-			for (OsmPrimitive osm : all)
-				if (osm instanceof Segment && !((Segment)osm).incomplete)
-					segments.add((Segment)osm);
-			if (!segments.isEmpty()) {
-				out.println("  <trk>");
-				for (Segment ls : segments) {
-					out.println("    <trkseg>");
-					writer.outputNode(ls.from, false);
-					all.remove(ls.from);
-					writer.outputNode(ls.to, false);
-					all.remove(ls.to);
-					out.println("    </trkseg>");
-					all.remove(ls);
-				}
-				out.println("  </trk>");
 			}
 
Index: branch/0.5/src/org/openstreetmap/josm/io/OsmIdReader.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/OsmIdReader.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/OsmIdReader.java	(revision 329)
@@ -31,5 +31,5 @@
 
 	@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
-		if (qName.equals("node") || qName.equals("segment") || qName.equals("way")) {
+		if (qName.equals("node") || qName.equals("way")) {
 			try {
 				entries.put(Long.valueOf(atts.getValue("id")), qName);
Index: branch/0.5/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/OsmReader.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/OsmReader.java	(revision 329)
@@ -24,7 +24,8 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DataSource;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 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.User;
 import org.openstreetmap.josm.data.osm.Way;
@@ -44,7 +45,5 @@
  * all nodes are read and stored. Other information than nodes are stored in a raw list
  *
- * The second phase reads from the raw list all segments and create Segment objects.
- *
- * The third phase read all ways out of the remaining objects in the raw list.
+ * The second phase read all ways out of the remaining objects in the raw list.
  *
  * @author Imi
@@ -91,8 +90,12 @@
 
 	/**
-	 * Data structure for the remaining segment objects
-	 * Maps the raw attributes to key/value pairs.
-	 */
-	private Map<OsmPrimitiveData, long[]> segs = new HashMap<OsmPrimitiveData, long[]>();
+	 * Used as a temporary storage for relation members, before they
+	 * are resolved into pointers to real objects.
+	 */
+	private static class RelationMemberData {
+		public String type;
+		public long id;
+		public RelationMember relationMember;
+	}
 
 	/**
@@ -100,4 +103,9 @@
 	 */
 	private Map<OsmPrimitiveData, Collection<Long>> ways = new HashMap<OsmPrimitiveData, Collection<Long>>();
+
+	/** 
+	 * Data structure for relation objects
+	 */
+	private Map<OsmPrimitiveData, Collection<RelationMemberData>> relations = new HashMap<OsmPrimitiveData, Collection<RelationMemberData>>();
 
 	/** 
@@ -132,26 +140,50 @@
 						ds.dataSources.add(src);
 					}
+					
+				// ---- PARSING NODES AND WAYS ----
+					
 				} else if (qName.equals("node")) {
 					current = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")));
 					readCommon(atts, current);
 					nodes.put(current.id, (Node)current);
-				} else if (qName.equals("segment")) {
-					current = new OsmPrimitiveData();
-					readCommon(atts, current);
-					segs.put((OsmPrimitiveData)current, new long[]{getLong(atts, "from"), getLong(atts, "to")});
 				} else if (qName.equals("way")) {
 					current = new OsmPrimitiveData();
 					readCommon(atts, current);
 					ways.put((OsmPrimitiveData)current, new LinkedList<Long>());
-				} else if (qName.equals("seg")) {
+				} else if (qName.equals("nd")) {
 					Collection<Long> list = ways.get(current);
 					if (list == null)
-						throw new SAXException(tr("Found <seg> tag on non-way."));
-					long id = getLong(atts, "id");
+						throw new SAXException(tr("Found <nd> element in non-way."));
+					long id = getLong(atts, "ref");
 					if (id == 0)
-						throw new SAXException(tr("Incomplete segment with id=0"));
+						throw new SAXException(tr("<nd> has zero ref"));
 					list.add(id);
-				} else if (qName.equals("tag"))
+
+				// ---- PARSING RELATIONS ----			
+
+				} else if (qName.equals("relation")) {
+					current = new OsmPrimitiveData();
+					readCommon(atts, current);
+					relations.put((OsmPrimitiveData)current, new LinkedList<RelationMemberData>());
+				} else if (qName.equals("member")) {
+					Collection<RelationMemberData> list = relations.get(current);
+					if (list == null)
+						throw new SAXException(tr("Found <member> tag on non-relation."));
+					RelationMemberData emd = new RelationMemberData();
+					emd.relationMember = new RelationMember();
+					emd.id = getLong(atts, "ref");
+					emd.type=atts.getValue("type");
+					emd.relationMember.role = atts.getValue("role");
+					
+					if (emd.id == 0)
+						throw new SAXException(tr("Incomplete <member> specification with ref=0"));
+					
+					list.add(emd);
+					
+				// ---- PARSING TAGS (applicable to all objects) ----
+					
+				} else if (qName.equals("tag")) {
 					current.put(atts.getValue("k"), atts.getValue("v"));
+				}
 			} catch (NumberFormatException x) {
 				x.printStackTrace(); // SAXException does not chain correctly
@@ -173,8 +205,10 @@
 	public OsmReader() {
 		// first add the main server version
-		allowedVersions.add(Main.pref.get("osm-server.version", "0.4"));
+		allowedVersions.add(Main.pref.get("osm-server.version", "0.5"));
 		// now also add all compatible versions
 		String[] additionalVersions = 
-			Main.pref.get("osm-server.additional-versions", "0.3").split("/,/");
+			Main.pref.get("osm-server.additional-versions", "").split("/,/");
+		if (additionalVersions.length == 1 && additionalVersions[0].length() == 0)
+			additionalVersions = new String[] {};
 		allowedVersions.addAll(Arrays.asList(additionalVersions));	
 	}
@@ -224,17 +258,4 @@
 			throw new SAXException(tr("Missing required attribute \"{0}\".",value));
 		return Long.parseLong(s);
-	}
-
-	private void createSegments() {
-		for (Entry<OsmPrimitiveData, long[]> e : segs.entrySet()) {
-			Node from = findNode(e.getValue()[0]);
-			Node to = findNode(e.getValue()[1]);
-			if (from == null || to == null)
-				continue; //TODO: implement support for incomplete nodes.
-			Segment s = new Segment(from, to);
-			e.getKey().copyTo(s);
-			segments.put(s.id, s);
-			adder.visit(s);
-		}
 	}
 
@@ -253,29 +274,17 @@
     }
 
-	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;
-		// TODO: This has to be changed to support multiple layers.
-		for (Segment seg : Main.ds.segments)
-			if (seg.id == id)
-				return new Segment(seg);
-		return null;
-	}
-
 	private void createWays() {
 		for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) {
 			Way w = new Way();
+			boolean failed = false;
 			for (long id : e.getValue()) {
-				Segment s = findSegment(id);
-				if (s == null) {
-					s = new Segment(id); // incomplete line segment
-					adder.visit(s);
+				Node n = findNode(id);
+				if (n == null) {
+					failed = true;
+					break;
 				}
-				w.segments.add(s);
+				w.nodes.add(n);
 			}
+			if (failed) continue;
 			e.getKey().copyTo(w);
 			adder.visit(w);
@@ -284,7 +293,85 @@
 
 	/**
-	 * All read segments after phase 2.
-	 */
-	private Map<Long, Segment> segments = new HashMap<Long, Segment>();
+	 * Return the Way object with the given id, or null if it doesn't
+	 * exist yet. This method only looks at ways stored in the data set.
+	 * 
+	 * @param id
+	 * @return way object or null
+	 */
+	private Way findWay(long id) {
+		for (Way wy : ds.ways)
+			if (wy.id == id)
+				return wy;
+		for (Way wy : Main.ds.ways)
+			if (wy.id == id)
+				return wy;
+		return null;
+	}
+
+	/**
+	 * Return the Relation object with the given id, or null if it doesn't
+	 * exist yet. This method only looks at relations stored in the data set.
+	 * 
+	 * @param id
+	 * @return relation object or null
+	 */
+	private Relation findRelation(long id) {
+		for (Relation e : ds.relations)
+			if (e.id == id)
+				return e;
+		for (Relation e : Main.ds.relations)
+			if (e.id == id)
+				return e;
+		return null;
+	}
+
+	/**
+	 * Create relations. This is slightly different than n/s/w because 
+	 * unlike other objects, relations may reference other relations; it
+	 * is not guaranteed that a referenced relation will have been created
+	 * before it is referenced. So we have to create all relations first,
+	 * and populate them later.
+	 */
+	private void createRelations() {
+		
+		// pass 1 - create all relations
+		for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) {
+			Relation en = new Relation();
+			e.getKey().copyTo(en);
+			adder.visit(en);
+		}
+
+		// pass 2 - sort out members
+		for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) {
+			Relation en = findRelation(e.getKey().id);
+			if (en == null) throw new Error("Failed to create relation " + e.getKey().id);
+			
+			for (RelationMemberData emd : e.getValue()) {
+				RelationMember em = emd.relationMember;
+				if (emd.type.equals("node")) {
+					em.member = findNode(emd.id);
+					if (em.member == null) {
+						em.member = new Node(emd.id);
+						adder.visit((Node)em.member);
+					}
+				} else if (emd.type.equals("way")) {
+					em.member = findWay(emd.id);
+					if (em.member == null) {
+						em.member = new Way(emd.id);
+						adder.visit((Way)em.member);
+					}
+				} else if (emd.type.equals("relation")) {
+					em.member = findRelation(emd.id);
+					if (em.member == null) {
+						em.member = new Relation(emd.id);
+						adder.visit((Relation)em.member);
+					}
+				} else {
+					// this is an error.
+				}
+				en.members.add(em);
+			}
+		}
+	}
 
 	/**
@@ -298,5 +385,5 @@
 		osm.references = ref == null ? new DataSet() : ref;
 
-		// phase 1: Parse nodes and read in raw segments and ways
+		// phase 1: Parse nodes and read in raw ways
 		InputSource inputSource = new InputSource(new InputStreamReader(source, "UTF-8"));
 		try {
@@ -314,6 +401,6 @@
 
 		try {
-			osm.createSegments();
 			osm.createWays();
+			osm.createRelations();
 		} catch (NumberFormatException e) {
 			e.printStackTrace();
Index: branch/0.5/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 329)
@@ -30,5 +30,5 @@
 	 */
 	protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException {
-		String version = Main.pref.get("osm-server.version", "0.4");
+		String version = Main.pref.get("osm-server.version", "0.5");
 		urlStr = Main.pref.get("osm-server.url")+"/"+version+"/" + urlStr;
 		System.out.println("download: "+urlStr);
Index: branch/0.5/src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 329)
@@ -17,7 +17,7 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Relation;
 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.NameVisitor;
@@ -96,20 +96,5 @@
 
 	/**
-	 * Upload a segment (without the nodes).
-	 */
-	public void visit(Segment ls) {
-		if (ls.id == 0 && !ls.deleted && ls.get("created_by") == null) {
-			ls.put("created_by", "JOSM");
-			sendRequest("PUT", "segment", ls, true);
-		} else if (ls.deleted) {
-			sendRequest("DELETE", "segment", ls, false);
-		} else {
-			sendRequest("PUT", "segment", ls, true);
-		}
-		processed.add(ls);
-	}
-
-	/**
-	 * Upload a whole way with the complete segment id list.
+	 * Upload a whole way with the complete node id list.
 	 */
 	public void visit(Way w) {
@@ -125,4 +110,18 @@
 	}
 
+	/**
+	 * Upload an relation with all members.
+	 */
+	public void visit(Relation e) {
+		if (e.id == 0 && !e.deleted && e.get("created_by") == null) {
+			e.put("created_by", "JOSM");
+			sendRequest("PUT", "relation", e, true);
+		} else if (e.deleted) {
+			sendRequest("DELETE", "relation", e, false);
+		} else {
+			sendRequest("PUT", "relation", e, true);
+		}
+		processed.add(e);
+	}
 	/**
 	 * Read a long from the input stream and return it.
@@ -154,10 +153,10 @@
 			OsmPrimitive osm, boolean addBody) {
 		try {
-			String version = Main.pref.get("osm-server.version", "0.4");
+			String version = Main.pref.get("osm-server.version", "0.5");
 			URL url = new URL(
 					Main.pref.get("osm-server.url") +
 					"/" + version +
 					"/" + urlSuffix + 
-					"/" + ((version.equals("0.4") && osm.id==0) ? "create":osm.id));
+					"/" + (osm.id==0 ? "create" : osm.id));
 			System.out.println("upload to: "+url);
 			activeConnection = (HttpURLConnection)url.openConnection();
Index: branch/0.5/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 329)
@@ -9,7 +9,8 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DataSource;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 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.Visitor;
@@ -37,5 +38,5 @@
 		public void header(PrintWriter out) {
 			out.print("<osm version='");
-			out.print(Main.pref.get("osm-server.version", "0.4"));
+			out.print(Main.pref.get("osm-server.version", "0.5"));
 			out.println("' generator='JOSM'>");
 		}
@@ -44,4 +45,11 @@
 		}
 	}
+	
+	// simple helper to write the object's class to the out stream
+	private Visitor typeWriteVisitor = new Visitor() {
+		public void visit(Node n) { out.print("node"); }
+		public void visit(Way w) { out.print("way"); }
+		public void visit(Relation e) { out.print("relation"); }
+	};
 	
 	/**
@@ -69,10 +77,10 @@
 				if (shouldWrite(n))
 					writer.visit(n);
-			for (Segment ls : ds.segments)
-				if (shouldWrite(ls))
-					writer.visit(ls);
 			for (Way w : ds.ways)
 				if (shouldWrite(w))
 					writer.visit(w);
+			for (Relation e : ds.relations)
+				if (shouldWrite(e))
+					writer.visit(e);
         }
 
@@ -123,19 +131,24 @@
 	}
 
-	public void visit(Segment ls) {
-		if (ls.incomplete)
-			return; // Do not write an incomplete segment
-		addCommon(ls, "segment");
-		out.print(" from='"+getUsedId(ls.from)+"' to='"+getUsedId(ls.to)+"'");
-		addTags(ls, "segment", true);
-	}
-
 	public void visit(Way w) {
 		addCommon(w, "way");
 		out.println(">");
-		for (Segment ls : w.segments)
-			out.println("    <seg id='"+getUsedId(ls)+"' />");
+		for (Node n : w.nodes)
+			out.println("    <nd ref='"+getUsedId(n)+"' />");
 		addTags(w, "way", false);
 	}
+
+	public void visit(Relation e) {
+		addCommon(e, "relation");
+		out.println(">");
+		for (RelationMember em : e.members) {
+			out.print("    <member type='");
+			em.member.visit(typeWriteVisitor);
+			out.println("' ref='"+getUsedId(em.member)+"' role='" + 
+				XmlWriter.encode(em.role) + "' />");
+		}
+		addTags(e, "relation", false);
+	}
+	
 
 	/**
Index: branch/0.5/src/org/openstreetmap/josm/io/XmlWriter.java
===================================================================
--- branch/0.5/src/org/openstreetmap/josm/io/XmlWriter.java	(revision 326)
+++ branch/0.5/src/org/openstreetmap/josm/io/XmlWriter.java	(revision 329)
@@ -67,6 +67,4 @@
 	}
 
-
-
 	/**
 	 * The output writer to save the values to.
