Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/CreateOsmChangeVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/CreateOsmChangeVisitor.java	(revision 1071)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/CreateOsmChangeVisitor.java	(revision 1071)
@@ -0,0 +1,116 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm.visitor;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Map;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Changeset;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.io.OsmWriter;
+
+/**
+ * Creates an OsmChange document from JOSM edits.
+ * See http://wiki.openstreetmap.org/index.php/OsmChange for a documentation of the 
+ * OsmChange format.
+ * 
+ * @author fred
+ *
+ */
+public class CreateOsmChangeVisitor implements Visitor {
+
+    StringBuffer document;
+    String currentMode;
+    Changeset changeset;
+    PrintWriter writer;
+    StringWriter swriter;
+    OsmWriter osmwriter;
+    
+    public CreateOsmChangeVisitor(Changeset changeset) {
+        writer = new PrintWriter(swriter = new StringWriter());
+        writer.write("<osmChange version=\"");
+        writer.write(Main.pref.get("osm-server.version", "0.6"));
+        writer.write("\" generator=\"JOSM\">\n"); 
+        this.changeset = changeset;
+        osmwriter = new OsmWriter(writer, false, changeset);
+    }
+    
+    public void visit(Node n) {
+        if (n.deleted) {
+            switchMode("delete");
+            writer.write("<node id=\"");
+            writer.write(Long.toString(n.id));
+            writer.write("\" version=\"");
+            writer.write(Long.toString(n.version));
+            writer.write("\" changeset=\"");
+            writer.write(Long.toString(changeset.id));
+            writer.write("\" />\n");
+        } else {
+            switchMode((n.id == 0) ? "create" : "modify");
+            n.visit(osmwriter);
+        }
+    }
+    
+    public void visit(Way w) {
+        if (w.deleted) {
+            switchMode("delete");
+            writer.write("<way id=\"");
+            writer.write(Long.toString(w.id));
+            writer.write("\" version=\"");
+            writer.write(Long.toString(w.version));
+            writer.write("\" changeset=\"");
+            writer.write(Long.toString(changeset.id));
+            writer.write("\" />\n");
+        } else {
+            switchMode((w.id == 0) ? "create" : "modify");
+            w.visit(osmwriter);
+        }        
+    }
+    
+    public void visit(Relation r) {
+        if (r.deleted) {
+            switchMode("delete");
+            writer.write("<relation id=\"");
+            writer.write(Long.toString(r.id));
+            writer.write("\" version=\"");
+            writer.write(Long.toString(r.version));
+            writer.write("\" changeset=\"");
+            writer.write(Long.toString(changeset.id));
+            writer.write("\" />\n");
+        } else {
+            switchMode((r.id == 0) ? "create" : "modify");
+            r.visit(osmwriter);
+        }           
+    }
+    
+    private void switchMode(String newMode) {
+        if ((newMode != null && !newMode.equals(currentMode))||(newMode == null && currentMode != null)) {
+            if (currentMode != null) {
+                writer.write("</");
+                writer.write(currentMode);
+                writer.write(">\n");
+            }
+            if (newMode != null) {
+                writer.write("<");
+                writer.write(newMode);
+                writer.write(" version=\"");
+                writer.write(Main.pref.get("osm-server.version", "0.6"));
+                writer.write("\" generator=\"JOSM\">\n");
+            }
+            currentMode = newMode;
+        }
+    }
+    
+    public String getDocument() {
+        switchMode(null);
+        return swriter.toString() + "</osmChange>\n";
+    }
+    
+    public Map<OsmPrimitive,Long> getNewIdMap() {
+        return osmwriter.usedNewIds;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/io/DiffResultReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/DiffResultReader.java	(revision 1071)
+++ trunk/src/org/openstreetmap/josm/io/DiffResultReader.java	(revision 1071)
@@ -0,0 +1,141 @@
+//License: GPL. Copyright 2007 by Immanuel Scholz and others
+package org.openstreetmap.josm.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.DataSource;
+import org.openstreetmap.josm.data.osm.Node;
+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.User;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
+import org.openstreetmap.josm.gui.PleaseWaitDialog;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ */
+public class DiffResultReader implements Visitor {
+    
+    /**
+     * mapping from old id to new id/version
+     */
+    private Map<String, Long[]> versions = new HashMap<String, Long[]>();
+    private Collection<OsmPrimitive> processed;
+    private Map<OsmPrimitive,Long> newIdMap; 
+
+    /** 
+     * List of protocol versions that will be accepted on reading
+     */
+    
+    private class Parser extends DefaultHandler {
+
+        @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+            try {
+                if (qName.equals("osm")) {
+                } else if (qName.equals("node") || qName.equals("way") || qName.equals("relation")) {
+                    String key = qName + ":" + atts.getValue("old_id");
+                    String newid = atts.getValue("new_id");
+                    String newver = atts.getValue("new_version");
+                    Long[] value = new Long[] { newid == null ? null : new Long(newid), newver == null ? null : new Long(newver) };
+                    versions.put(key, value);
+                }
+            } catch (NumberFormatException x) {
+                x.printStackTrace(); // SAXException does not chain correctly
+                throw new SAXException(x.getMessage(), x);
+            } catch (NullPointerException x) {
+                x.printStackTrace(); // SAXException does not chain correctly
+                throw new SAXException(tr("NullPointerException, Possibly some missing tags."), x);
+            }
+        }
+    }
+
+    /**
+     * Parse the given input source and return the dataset.
+     * @param ref The dataset that is search in for references first. If
+     *      the Reference is not found here, Main.ds is searched and a copy of the
+     *  elemet found there is returned.
+     */
+    public static void parseDiffResult(InputStream source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, PleaseWaitDialog pleaseWaitDlg) 
+    throws SAXException, IOException {
+
+       DiffResultReader drr = new DiffResultReader();
+       drr.processed = processed;
+       drr.newIdMap = newIdMap;
+       InputSource inputSource = new InputSource(new InputStreamReader(source, "UTF-8"));
+       try {
+           SAXParserFactory.newInstance().newSAXParser().parse(inputSource, drr.new Parser());
+       } catch (ParserConfigurationException e1) {
+           e1.printStackTrace(); // broken SAXException chaining
+           throw new SAXException(e1);
+       }
+
+       if (pleaseWaitDlg != null) {
+           pleaseWaitDlg.progress.setValue(0);
+           pleaseWaitDlg.currentAction.setText(tr("Preparing data..."));
+       }
+
+       for (OsmPrimitive p : osm) {
+           System.out.println("old: "+ p);
+           p.visit(drr);
+           System.out.println("new: "+ p);
+           System.out.println("");
+       }
+    }
+    
+    public void visit(Node n) {
+        String key = "node:" + (newIdMap.containsKey(n) ? newIdMap.get(n) : n.id);
+        System.out.println("key: "+key);
+        Long[] nv = versions.get(key);
+        if (nv != null) {
+            processed.add(n);
+            if (!n.deleted) {
+                n.id = nv[0]; n.version = nv[1].intValue();
+            }
+        }
+    }
+    public void visit(Way w) {
+        String key = "way:" + (newIdMap.containsKey(w) ? newIdMap.get(w) : w.id);
+        Long[] nv = versions.get(key);
+        if (nv != null) {
+            processed.add(w);
+            if (!w.deleted) {
+                w.id = nv[0]; w.version = nv[1].intValue();
+            }
+        }        
+    }
+    public void visit(Relation r) {
+        String key = "relation:" + (newIdMap.containsKey(r) ? newIdMap.get(r) : r.id);
+        Long[] nv = versions.get(key);
+        if (nv != null) {
+            processed.add(r);
+            if (!r.deleted) {
+                r.id = nv[0]; r.version = nv[1].intValue();
+            }
+        }   
+    }
+}
Index: trunk/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 1070)
+++ trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 1071)
@@ -87,5 +87,5 @@
                osm.version = version;
                osm.checkTagged();
-                        osm.checkDirectionTagged();
+               osm.checkDirectionTagged();
           }
      }
Index: trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java	(revision 1070)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java	(revision 1071)
@@ -1,3 +1,3 @@
-// License: GPL. For details, see LICENSE file.
+//License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.io;
 
@@ -12,58 +12,56 @@
 
 public class OsmServerObjectReader extends OsmServerReader {
-    
-     public final static  String TYPE_WAY = "way";
-     public final static  String TYPE_REL = "relation";
-     public final static  String TYPE_NODE = "node";
-     
-     /**
-      * Method to download single objects from OSM server. ways, relations, nodes
-      * @param id Object ID
-      * @param type way node relation
-      * @param full download with or without child objects
-      * @return the data requested
-      * @throws SAXException
-      * @throws IOException
-      */
-     public DataSet parseOsm(long id, String type, boolean full) throws SAXException, IOException {
-            try {
-                
-                Main.pleaseWaitDlg.progress.setValue(0);
-                Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
-                StringBuffer sb = new StringBuffer();
-                sb.append(type);
-                sb.append("/");
-                sb.append(id);
-                if (full)
-                {
-                    sb.append("/full");
-                }
-                
-                final InputStream in = getInputStream(sb.toString(), Main.pleaseWaitDlg);
-                if (in == null)
-                    return null;
-                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.5");
-//                Bounds bounds = new Bounds(new LatLon(lat1, lon1), new LatLon(lat2, lon2));
-//                DataSource src = new DataSource(bounds, origin);
-//                data.dataSources.add(src);
-                in.close();
-                activeConnection = null;
-                return data;
-            } catch (IOException e) {
-                if (cancel)
-                    return null;
-                throw e;
-            } catch (SAXException e) {
-                throw e;
-            } catch (Exception e) {
-                if (cancel)
-                    return null;
-                if (e instanceof RuntimeException)
-                    throw (RuntimeException)e;
-                throw new RuntimeException(e);
-            }
+
+    public final static  String TYPE_WAY = "way";
+    public final static  String TYPE_REL = "relation";
+    public final static  String TYPE_NODE = "node";
+
+    /**
+     * Method to download single objects from OSM server. ways, relations, nodes
+     * @param id Object ID
+     * @param type way node relation
+     * @param full download with or without child objects
+     * @return the data requested
+     * @throws SAXException
+     * @throws IOException
+     */
+    public DataSet parseOsm(long id, String type, boolean full) throws SAXException, IOException {
+        try {
+
+            Main.pleaseWaitDlg.progress.setValue(0);
+            Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
+            StringBuffer sb = new StringBuffer();
+            sb.append(type);
+            sb.append("/");
+            sb.append(id);
+            if (full)
+                sb.append("/full");
+
+            final InputStream in = getInputStream(sb.toString(), Main.pleaseWaitDlg);
+            if (in == null)
+                return null;
+            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.5");
+//          Bounds bounds = new Bounds(new LatLon(lat1, lon1), new LatLon(lat2, lon2));
+//          DataSource src = new DataSource(bounds, origin);
+//          data.dataSources.add(src);
+            in.close();
+            activeConnection = null;
+            return data;
+        } catch (IOException e) {
+            if (cancel)
+                return null;
+            throw e;
+        } catch (SAXException e) {
+            throw e;
+        } catch (Exception e) {
+            if (cancel)
+                return null;
+            if (e instanceof RuntimeException)
+                throw (RuntimeException)e;
+            throw new RuntimeException(e);
         }
+    }
 
 }
Index: trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 1070)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 1071)
@@ -35,5 +35,5 @@
 		String version = Main.pref.get("osm-server.version", "0.5");
 		urlStr = Main.pref.get("osm-server.url")+"/"+version+"/" + urlStr;
-//		System.out.println("download: "+urlStr);
+		System.out.println("download: "+urlStr);
 		initAuthentication();
 		URL url = new URL(urlStr);
Index: trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1070)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1071)
@@ -4,4 +4,5 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
@@ -10,4 +11,8 @@
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
 import java.net.ConnectException;
 import java.net.HttpURLConnection;
@@ -25,4 +30,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.Changeset;
+import org.openstreetmap.josm.data.osm.visitor.CreateOsmChangeVisitor;
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
@@ -73,4 +79,5 @@
 
 	long uploadStartTime;
+    
 	public String timeLeft(int progress, int list_size) {
 		long now = System.currentTimeMillis();
@@ -88,5 +95,6 @@
 		time_left_str += Integer.toString(seconds_left);
 		return time_left_str;
-	}	
+	}
+    
 	public void uploadOsm(Collection<OsmPrimitive> list) throws SAXException {
 		processed = new LinkedList<OsmPrimitive>();
@@ -96,11 +104,15 @@
 		Main.pleaseWaitDlg.progress.setValue(0);
 		
+        // controls whether or not we open and close a changeset. API 0.6 requires changesets.
 		boolean useChangesets = Main.pref.get("osm-server.version", "0.5").equals("0.6");
-
+        
+        // controls whether or not we try and uplaod the whole bunch in one go
+        boolean useDiffUploads = Main.pref.getBoolean("osm-server.atomic-upload", 
+            Main.pref.get("osm-server.version", "0.5").equals("0.6"));
+        
 		String comment = null;
-		while( useChangesets && comment == null)
-		{
+		while (useChangesets && comment == null) {
 			comment = JOptionPane.showInputDialog(Main.parent, tr("Provide a brief comment as to the changes to you are uploading:"),
-		                                             tr("Commit comment"), JOptionPane.QUESTION_MESSAGE);
+		         tr("Commit comment"), JOptionPane.QUESTION_MESSAGE);
 			if( comment == null )
 				return;
@@ -111,32 +123,36 @@
 		}
 		try {
-			if( useChangesets && !startChangeset(10, comment) )
+			if (useChangesets && !startChangeset(10, comment))
 				return;
 		}
 		catch (OsmTransferException ex) {
-			dealWithTransferException (ex);
+			dealWithTransferException(ex);
 			return;
 		}
-		
-		NameVisitor v = new NameVisitor();
-		try {
-			uploadStartTime = System.currentTimeMillis();
-			for (OsmPrimitive osm : list) {
-				if (cancel)
-					return;
-				osm.visit(v);
-				int progress = Main.pleaseWaitDlg.progress.getValue();
-				String time_left_str = timeLeft(progress, list.size());
-				Main.pleaseWaitDlg.currentAction.setText(tr("Upload {0} {1} (id: {2}) {3}% {4}/{5} ({6} left)...",
-					tr(v.className), v.name, osm.id, 100.0*progress/list.size(), progress, list.size(), time_left_str));
-				osm.visit(this);
-				Main.pleaseWaitDlg.progress.setValue(Main.pleaseWaitDlg.progress.getValue()+1);
-				Main.pleaseWaitDlg.progress.setValue(progress+1);
-			}
-				if( useChangesets ) 
-					stopChangeset(10);
+	
+		try {
+            if (useDiffUploads) {
+                uploadDiff(10, list);
+            } else {
+                NameVisitor v = new NameVisitor();
+                uploadStartTime = System.currentTimeMillis();
+                for (OsmPrimitive osm : list) {
+                    if (cancel)
+                        return;
+                    osm.visit(v);
+                    int progress = Main.pleaseWaitDlg.progress.getValue();
+                    String time_left_str = timeLeft(progress, list.size());
+                    Main.pleaseWaitDlg.currentAction.setText(tr("Upload {0} {1} (id: {2}) {3}% {4}/{5} ({6} left)...",
+                            tr(v.className), v.name, osm.id, 100.0*progress/list.size(), progress, list.size(), time_left_str));
+                    osm.visit(this);
+                    Main.pleaseWaitDlg.progress.setValue(progress+1);
+                }
+            }
+			if (useChangesets) 
+			    stopChangeset(10);
 		} catch (RuntimeException e) {
 			try {
-				if( useChangesets ) stopChangeset(10);
+				if (useChangesets) 
+                    stopChangeset(10);
 			}
 			catch (OsmTransferException ex) {
@@ -211,4 +227,5 @@
 			}
 			if (retCode != 200 && retCode != 412) {
+                
 				if (retries >= 0) {
 					retries--;
@@ -217,16 +234,17 @@
 					System.out.println("retrying ("+retries+" left)");
 					return startChangeset(retries, comment);
-				} else { 
-					// Look for a detailed error message from the server
-					if (activeConnection.getHeaderField("Error") != null)
-						retMsg += "\n" + activeConnection.getHeaderField("Error");
-
-					// Report our error
-					ByteArrayOutputStream o = new ByteArrayOutputStream();
-					OsmWriter.output(o, changeset);
-					System.out.println(new String(o.toByteArray(), "UTF-8").toString());
-					//throw new RuntimeException(retCode+" "+retMsg);
-					throw new OsmTransferException (retCode + " " + retMsg);
 				}
+                
+				// Look for a detailed error message from the server
+				if (activeConnection.getHeaderField("Error") != null)
+				    retMsg += "\n" + activeConnection.getHeaderField("Error");
+
+				// Report our error
+				ByteArrayOutputStream o = new ByteArrayOutputStream();
+				OsmWriter.output(o, changeset);
+				System.out.println(new String(o.toByteArray(), "UTF-8").toString());
+				//throw new RuntimeException(retCode+" "+retMsg);
+				throw new OsmTransferException (retCode + " " + retMsg);
+			
 			}
 		} catch (UnknownHostException e) {
@@ -265,5 +283,109 @@
 		return true;
 	}
-
+    
+    private void uploadDiff(int retries, Collection<OsmPrimitive> list) throws OsmTransferException {
+        
+        CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset);
+
+        for (OsmPrimitive osm : list) {
+            int progress = Main.pleaseWaitDlg.progress.getValue();
+            Main.pleaseWaitDlg.currentAction.setText(tr("Preparing..."));
+            if (cancel)
+                return;
+            osm.visit(duv);
+            Main.pleaseWaitDlg.progress.setValue(progress+1);
+        }
+        System.out.println("the document:\n");
+        String diff = duv.getDocument();
+        System.out.println(diff);
+        
+        Main.pleaseWaitDlg.currentAction.setText(tr("Uploading..."));
+        try {
+            if (cancel)
+                return; // assume cancel
+            String version = Main.pref.get("osm-server.version", "0.6");
+            URL url = new URL(
+                    Main.pref.get("osm-server.url") +
+                    "/" + version +
+                    "/" + "changeset" + 
+                    "/" + changeset.id +
+                    "/upload" );
+            System.out.print("upload to: "+url+ "..." );
+            activeConnection = (HttpURLConnection)url.openConnection();
+            activeConnection.setConnectTimeout(15000);
+            activeConnection.setRequestMethod("POST");
+            addAuth(activeConnection);
+            
+            activeConnection.setDoOutput(true);
+            PrintWriter out;
+            try {
+                out = new PrintWriter(new OutputStreamWriter(activeConnection.getOutputStream(), "UTF-8"));
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            out.print(diff);
+            out.close();
+            
+            activeConnection.connect();
+            System.out.println("connected");
+
+            int retCode = activeConnection.getResponseCode();
+            String retMsg = "";
+            
+            if (retCode == 200) {
+                DiffResultReader.parseDiffResult(activeConnection.getInputStream(), list, processed, duv.getNewIdMap(), Main.pleaseWaitDlg);
+            } else if (retCode != 200 && retCode != 412) {
+                if (retries >= 0) {
+                    retries--;
+                    System.out.print("backing off for 10 seconds...");
+                    Thread.sleep(10000);
+                    System.out.println("retrying ("+retries+" left)");
+                    stopChangeset(retries);
+                } else { 
+                    // Look for a detailed error message from the server
+                    if (activeConnection.getHeaderField("Error") != null)
+                        retMsg += "\n" + activeConnection.getHeaderField("Error");
+
+                    // Report our error
+                    ByteArrayOutputStream o = new ByteArrayOutputStream();
+                    OsmWriter.output(o, changeset);
+                    System.out.println(new String(o.toByteArray(), "UTF-8").toString());
+                    //throw new RuntimeException(retCode+" "+retMsg);
+                    throw new OsmTransferException(retCode+" "+retMsg);
+                }
+            }
+        } catch (UnknownHostException e) {
+            //throw new RuntimeException(tr("Unknown host")+": "+e.getMessage(), e);
+            throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
+        } catch(SocketTimeoutException e) {
+            System.out.println(" timed out, retries left: " + retries);
+            if (cancel)
+                return; // assume cancel
+            if (retries-- > 0)
+                stopChangeset(retries);
+            else
+                //throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
+                throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
+        } catch(ConnectException e) {
+            System.out.println(" timed out, retries left: " + retries);
+            if (cancel)
+                return; // assume cancel
+            if (retries-- > 0)
+                stopChangeset(retries);
+            else
+                //throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
+                throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
+        } catch (Exception e) {
+            if (cancel)
+                return; // assume cancel
+            if (e instanceof OsmTransferException)
+                throw (OsmTransferException)e;
+            if (e instanceof RuntimeException)
+                throw (RuntimeException)e;
+            throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
+        }
+    }
+    
+    
 	private void stopChangeset(int retries) throws OsmTransferException {
 		Main.pleaseWaitDlg.currentAction.setText(tr("Closing changeset..."));
@@ -443,20 +565,14 @@
 			int retCode = activeConnection.getResponseCode();
 			/* When creating new, the returned value is the new id, otherwise it is the new version */
-			if (retCode == 200)
-			{
-				if(osm.id == 0)
-				{
+			if (retCode == 200)	{
+				if (osm.id == 0) {
 					osm.id = readId(activeConnection.getInputStream());
 					osm.version = 1;
-				}
-				else
-				{
+				} else {
 					int read_version = (int)readId(activeConnection.getInputStream());
-					if( read_version > 0 )
+					if (read_version > 0)
 						osm.version = read_version;
 				}
-			}
-			else
-			{
+			} else {
 				System.out.println("got return: "+retCode+" with id "+osm.id);
 			}
@@ -464,8 +580,6 @@
 			if (retCode == 410 && requestMethod.equals("DELETE"))
 				return; // everything fine.. was already deleted.
-			else if (retCode != 200)
-			{
-				if (retries >= 0 && retCode != 412)
-				{
+			else if (retCode != 200) {
+				if (retries >= 0 && retCode != 412)	{
 					retries--;
 					System.out.print("backing off for 10 seconds...");
Index: trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 1070)
+++ trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 1071)
@@ -32,5 +32,5 @@
 	 * map to allow references to use the correnct primitives.
 	 */
-	private HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();
+	public HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();
 
 	private final boolean osmConform;
@@ -131,5 +131,5 @@
 	}
 
-	private OsmWriter(PrintWriter out, boolean osmConform, Changeset changeset) {
+	public OsmWriter(PrintWriter out, boolean osmConform, Changeset changeset) {
 		super(out);
 		this.osmConform = osmConform;
@@ -178,5 +178,4 @@
 		return osmConform ? 0 : newIdCounter--;
 	}
-
 
 	private void addTags(OsmPrimitive osm, String tagname, boolean tagOpen) {
