Index: trunk/src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 1663)
+++ trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 1664)
@@ -21,4 +21,5 @@
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Properties;
 import java.util.StringTokenizer;
@@ -51,4 +52,39 @@
     static public final int DEFAULT_MAX_NUM_RETRIES = 5;
 
+    /** the collection of instantiated OSM APIs */
+    private static HashMap<String, OsmApi> instances = new HashMap<String, OsmApi>();
+
+    /**
+     * replies the {@see OsmApi} for a given server URL
+     * 
+     * @param serverUrl  the server URL
+     * @return the OsmApi
+     * @throws IllegalArgumentException thrown, if serverUrl is null
+     * 
+     */
+    static public OsmApi getOsmApi(String serverUrl) {
+        OsmApi api = instances.get(serverUrl);
+        if (api == null) {
+            api = new OsmApi(serverUrl);
+        }
+        return api;
+    }
+    /**
+     * replies the {@see OsmApi} for the URL given by the preference <code>osm-server.url</code>
+     * 
+     * @return the OsmApi
+     * @exception IllegalStateException thrown, if the preference <code>osm-server.url</code> is not set
+     * 
+     */
+    static public OsmApi getOsmApi() {
+        String serverUrl = Main.pref.get("osm-server.url");
+        if (serverUrl == null)
+            throw new IllegalStateException(tr("preference {0} missing. Can't initialize OsmApi", "osm-server.url"));
+        return getOsmApi(serverUrl);
+    }
+
+    /** the server URL */
+    private String serverUrl;
+
     /**
      * Object describing current changeset
@@ -64,10 +100,10 @@
      * Minimum API version accepted by server, from capabilities response
      */
-    private String minVersion = null;
+    //private String minVersion = null;
 
     /**
      * Maximum API version accepted by server, from capabilities response
      */
-    private String maxVersion = null;
+    //private String maxVersion = null;
 
     /**
@@ -77,4 +113,7 @@
     private String maxArea = null;
 
+    /** the api capabilities */
+    private Capabilities capabilities = new Capabilities();
+
     /**
      * true if successfully initialized
@@ -89,12 +128,38 @@
      */
     private class CapabilitiesParser extends DefaultHandler {
+        @Override
+        public void startDocument() throws SAXException {
+            capabilities.clear();
+        }
+
         @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
-            if (qName.equals("version")) {
-                minVersion = atts.getValue("minimum");
-                maxVersion = atts.getValue("maximum");
-            } else if (qName.equals("area")) {
-                maxArea = atts.getValue("maximum");
+            for (int i=0; i< qName.length(); i++) {
+                capabilities.put(qName, atts.getQName(i), atts.getValue(i));
             }
         }
+    }
+
+    /**
+     * creates an OSM api for a specific server URL
+     * 
+     * @param serverUrl the server URL. Must not be null
+     * @exception IllegalArgumentException thrown, if serverUrl is null
+     */
+    protected OsmApi(String serverUrl)  {
+        if (serverUrl == null)
+            throw new IllegalArgumentException(tr("parameter '{0} must not be null", "serverUrl"));
+        this.serverUrl = serverUrl;
+    }
+
+    /**
+     * creates an instance of the OSM API. Initializes the server URL with the
+     * value of the preference <code>osm-server.url</code>
+     * 
+     * @exception IllegalStateException thrown, if the preference <code>osm-server.url</code> is not set
+     */
+    protected OsmApi() {
+        this.serverUrl = Main.pref.get("osm-server.url");
+        if (serverUrl == null)
+            throw new IllegalStateException(tr("preference {0} missing. Can't initialize OsmApi", "osm-server.url"));
     }
 
@@ -136,28 +201,30 @@
      * @exception Exception any other exception
      */
-    public void initialize() throws UnknownHostException,SocketTimeoutException, ConnectException,Exception {
+    public void initialize() throws OsmApiInitializationException {
+        if (initialized)
+            return;
         initAuthentication();
         try {
-            initialized = true; // note: has to be before the sendRequest or that will throw!
-            String capabilities = sendRequest("GET", "capabilities", null);
-            InputSource inputSource = new InputSource(new StringReader(capabilities));
+            String s = sendRequest("GET", "capabilities", null);
+            InputSource inputSource = new InputSource(new StringReader(s));
             SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new CapabilitiesParser());
-            if (maxVersion.compareTo("0.6") >= 0) {
+            if (capabilities.supportsVersion("0.6")) {
                 version = "0.6";
-            } else if (minVersion.compareTo("0.5") <= 0) {
+            } else if (capabilities.supportsVersion("0.5")) {
                 version = "0.5";
             } else {
                 System.err.println(tr("This version of JOSM is incompatible with the configured server."));
                 System.err.println(tr("It supports protocol versions 0.5 and 0.6, while the server says it supports {0} to {1}.",
-                        minVersion, maxVersion));
+                        capabilities.get("version", "minimum"), capabilities.get("version", "maximum")));
                 initialized = false;
             }
             System.out.println(tr("Communications with {0} established using protocol version {1}",
-                    Main.pref.get("osm-server.url"),
+                    serverUrl,
                     version));
             osmWriter.setVersion(version);
+            initialized = true;
         } catch (Exception ex) {
             initialized = false;
-            throw ex;
+            throw new OsmApiInitializationException(ex);
         }
     }
@@ -215,5 +282,5 @@
      */
     public String getBaseUrl() {
-        StringBuffer rv = new StringBuffer(Main.pref.get("osm-server.url"));
+        StringBuffer rv = new StringBuffer(serverUrl);
         if (version != null) {
             rv.append("/");
@@ -235,4 +302,5 @@
      */
     public void createPrimitive(OsmPrimitive osm) throws OsmTransferException {
+        initialize();
         osm.id = parseLong(sendRequest("PUT", which(osm)+"/create", toXml(osm, true)));
         osm.version = 1;
@@ -248,4 +316,5 @@
      */
     public void modifyPrimitive(OsmPrimitive osm) throws OsmTransferException {
+        initialize();
         if (version.equals("0.5")) {
             // legacy mode does not return the new object version.
@@ -263,4 +332,5 @@
      */
     public void deletePrimitive(OsmPrimitive osm) throws OsmTransferException {
+        initialize();
         // legacy mode does not require payload. normal mode (0.6 and up) requires payload for version matching.
         sendRequest("DELETE", which(osm)+"/" + osm.id, version.equals("0.5") ? null : toXml(osm, false));
@@ -288,4 +358,5 @@
      */
     public void stopChangeset() throws OsmTransferException {
+        initialize();
         Main.pleaseWaitDlg.currentAction.setText(tr("Closing changeset..."));
         sendRequest("PUT", "changeset" + "/" + changeset.id + "/close", null);
@@ -306,6 +377,6 @@
             throw new OsmTransferException(tr("No changeset present for diff upload"));
 
+        initialize();
         final ArrayList<OsmPrimitive> processed = new ArrayList<OsmPrimitive>();
-
 
         CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset, OsmApi.this);
@@ -362,11 +433,8 @@
             String requestBody) throws OsmTransferException {
 
-        if (!initialized) throw new OsmTransferException(tr("Not initialized"));
-
         StringBuffer responseBody = new StringBuffer();
 
         int retries = Main.pref.getInteger("osm-server.max-num-retries", DEFAULT_MAX_NUM_RETRIES);
         retries = Math.max(0,retries);
-
 
         while(true) { // the retry loop
Index: trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 1663)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 1664)
@@ -29,7 +29,7 @@
  */
 public abstract class OsmServerReader extends OsmConnection {
-    
-    private OsmApi api = new OsmApi();
-    
+
+    private OsmApi api = OsmApi.getOsmApi();
+
     /**
      * Open a connection to the given url and return a reader on the input stream
@@ -40,5 +40,5 @@
      */
     protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException {
-       
+
         // initialize API. Abort download in case of configuration or network
         // errors
@@ -48,11 +48,11 @@
         } catch(Exception e) {
             JOptionPane.showMessageDialog(
-                null,
-                tr(   "Failed to initialize communication with the OSM server {0}.\n"
-                    + "Check the server URL in your preferences and your internet connection.",
-                    Main.pref.get("osm-server.url")
-                ),
-                tr("Error"),
-                JOptionPane.ERROR_MESSAGE
+                    null,
+                    tr(   "Failed to initialize communication with the OSM server {0}.\n"
+                            + "Check the server URL in your preferences and your internet connection.",
+                            Main.pref.get("osm-server.url")
+                    ),
+                    tr("Error"),
+                    JOptionPane.ERROR_MESSAGE
             );
             e.printStackTrace();
@@ -66,5 +66,5 @@
     protected InputStream getInputStreamRaw(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException {
 
-//        System.out.println("download: "+urlStr);
+        //        System.out.println("download: "+urlStr);
         URL url = new URL(urlStr);
         activeConnection = (HttpURLConnection)url.openConnection();
@@ -74,6 +74,7 @@
         }
 
-        if (Main.pref.getBoolean("osm-server.use-compression", true))
+        if (Main.pref.getBoolean("osm-server.use-compression", true)) {
             activeConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
+        }
 
         activeConnection.setConnectTimeout(15000);
@@ -89,8 +90,5 @@
             return null;
         if (activeConnection.getResponseCode() == 500)
-        {
             throw new IOException(tr("Server returned internal error. Try a reduced area or retry after waiting some time."));
-        }
-//      System.out.println("got return: "+activeConnection.getResponseCode());
 
         String encoding = activeConnection.getContentEncoding();
Index: trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1663)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1664)
@@ -33,5 +33,5 @@
     public Collection<OsmPrimitive> processed;
 
-    private OsmApi api = new OsmApi();
+    private OsmApi api = OsmApi.getOsmApi();
 
     private static final int MSECS_PER_SECOND = 1000;
