Index: test/data/__files/api/0.6/capabilities
===================================================================
--- test/data/__files/api/0.6/capabilities	(revision 18368)
+++ test/data/__files/api/0.6/capabilities	(working copy)
@@ -6,6 +6,7 @@
     <note_area maximum="25"/>
     <tracepoints per_page="5000"/>
     <waynodes maximum="2000"/>
+    <relationmembers maximum="32000"/>
     <changesets maximum_elements="10000"/>
     <timeout seconds="300"/>
     <status database="online" api="online" gpx="online"/>
@@ -15,4 +16,4 @@
       <blacklist regex=".*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*"/>
     </imagery>
   </policy>
-</osm>
+</osm>
\ No newline at end of file
Index: src/org/openstreetmap/josm/io/Capabilities.java
===================================================================
--- src/org/openstreetmap/josm/io/Capabilities.java	(revision 18368)
+++ src/org/openstreetmap/josm/io/Capabilities.java	(working copy)
@@ -24,12 +24,15 @@
  *
  * Example capabilities document:
  * <pre>
- * &lt;osm version="0.6" generator="OpenStreetMap server"&gt;
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ * &lt;osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/"&gt;
  *   &lt;api&gt;
  *     &lt;version minimum="0.6" maximum="0.6"/&gt;
  *     &lt;area maximum="0.25"/&gt;
+ *     &lt;note_area maximum="25"/&gt;
  *     &lt;tracepoints per_page="5000"/&gt;
  *     &lt;waynodes maximum="2000"/&gt;
+ *     &lt;relationmembers maximum="32000"/&gt;
  *     &lt;changesets maximum_elements="10000"/&gt;
  *     &lt;timeout seconds="300"/&gt;
  *     &lt;status database="online" api="online" gpx="online"/&gt;
@@ -36,16 +39,15 @@
  *   &lt;/api&gt;
  *   &lt;policy&gt;
  *     &lt;imagery&gt;
- *       &lt;blacklist regex=".*\.google\.com/.*"/&gt;
- *       &lt;blacklist regex=".*209\.85\.2\d\d.*"/&gt;
- *       &lt;blacklist regex=".*209\.85\.1[3-9]\d.*"/&gt;
- *       &lt;blacklist regex=".*209\.85\.12[89].*"/&gt;
+ *       &lt;blacklist regex=".*\.google(apis)?\..*(vt|kh)[\?/].*([xyz]=.*){3}.*"/&gt;
+ *       &lt;blacklist regex="http://xdworld\.vworld\.kr:8080/.*"/&gt;
+ *       &lt;blacklist regex=".*\.here\.com[/:].*"/&gt;
  *     &lt;/imagery&gt;
  *   &lt;/policy&gt;
  * &lt;/osm&gt;
  * </pre>
  * This class is used in conjunction with a very primitive parser
- * and simply stuffs the each tag and its attributes into a hash
+ * and simply stuffs each tag and its attributes into a hash
  * of hashes, with the exception of the "blacklist" tag which gets
  * a list of its own. The DOM hierarchy is disregarded.
  */
@@ -188,6 +190,31 @@
     }
 
     /**
+     * Returns the max number of members in a relation. -1 if either the capabilities
+     * don't include this parameter or if the parameter value is illegal (not a number,
+     * a negative number)
+     *
+     * @return the max number of members in a relation
+     * @since xxx
+     */
+    public long getMaxRelationMembers() {
+        String v = get("relationmembers", "maximum");
+        if (v != null) {
+            try {
+                long n = Long.parseLong(v);
+                if (n <= 0) {
+                    warnIllegalValue("relationmembers", "maximum", n);
+                } else {
+                    return n;
+                }
+            } catch (NumberFormatException e) {
+                warnIllegalValue("relationmembers", "maximum", v);
+            }
+        }
+        return -1;
+    }
+    
+    /**
      * Returns the max number of nodes in a way. -1 if either the capabilities
      * don't include this parameter or if the parameter value is illegal (not a number,
      * a negative number)
Index: src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java
===================================================================
--- src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(revision 18368)
+++ src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(working copy)
@@ -11,6 +11,7 @@
 
 import org.openstreetmap.josm.data.APIDataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Tagged;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.ExceptionDialogUtil;
@@ -36,9 +37,11 @@
             if (NetworkManager.isOffline(OnlineResource.OSM_API)) {
                 return false;
             }
+
             // FIXME: this should run asynchronously and a progress monitor
-            // should be displayed.
+            //  should be displayed.
             api.initialize(NullProgressMonitor.INSTANCE);
+
             long maxNodes = api.getCapabilities().getMaxWayNodes();
             if (maxNodes > 0) {
                 if (!checkMaxNodes(apiData.getPrimitivesToAdd(), maxNodes))
@@ -48,6 +51,16 @@
                 if (!checkMaxNodes(apiData.getPrimitivesToDelete(), maxNodes))
                     return false;
             }
+
+            long maxMembers = api.getCapabilities().getMaxRelationMembers();
+            if (maxMembers > 0) {
+                if (!checkMaxMembers(apiData.getPrimitivesToAdd(), maxNodes))
+                    return false;
+                if (!checkMaxMembers(apiData.getPrimitivesToUpdate(), maxNodes))
+                    return false;
+                if (!checkMaxMembers(apiData.getPrimitivesToDelete(), maxNodes))
+                    return false;
+            }
         } catch (OsmTransferCanceledException e) {
             Logging.trace(e);
             return false;
@@ -58,6 +71,26 @@
         return true;
     }
 
+    private static boolean checkMaxMembers(Collection<OsmPrimitive> primitives, long maxMembers) {
+        for (OsmPrimitive osmPrimitive : primitives) {
+            if (osmPrimitive instanceof Relation && ((Relation) osmPrimitive).getMembersCount() > maxMembers) {
+                JOptionPane.showMessageDialog(
+                        MainApplication.getMainFrame(),
+                        tr("{0} members in relation {1} exceed the max. allowed number of members {2}",
+                                ((Relation) osmPrimitive).getMembersCount(),
+                                Long.toString(osmPrimitive.getId()),
+                                maxMembers
+                        ),
+                        tr("API Capabilities Violation"),
+                        JOptionPane.ERROR_MESSAGE
+                );
+                MainApplication.getLayerManager().getEditDataSet().setSelected(Collections.singleton(osmPrimitive));
+                return false;
+            }
+        }
+        return true;
+    }
+
     private static boolean checkMaxNodes(Collection<OsmPrimitive> primitives, long maxNodes) {
         for (OsmPrimitive osmPrimitive : primitives) {
             for (Map.Entry<String, String> entry: osmPrimitive.getKeys().entrySet()) {
