Index: trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 7573)
+++ trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 7574)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.actions.ValidateAction;
 import org.openstreetmap.josm.data.validation.tests.Addresses;
+import org.openstreetmap.josm.data.validation.tests.ApiCapabilitiesTest;
 import org.openstreetmap.josm.data.validation.tests.BarriersEntrances;
 import org.openstreetmap.josm.data.validation.tests.Coastlines;
@@ -123,4 +124,5 @@
         ConditionalKeys.class, // 3200 .. 3299
         InternetTags.class, // 3300 .. 3399
+        ApiCapabilitiesTest.class, // 3400 .. 3499
     };
 
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/ApiCapabilitiesTest.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/ApiCapabilitiesTest.java	(revision 7574)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/ApiCapabilitiesTest.java	(revision 7574)
@@ -0,0 +1,55 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.validation.tests;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.validation.Severity;
+import org.openstreetmap.josm.data.validation.Test;
+import org.openstreetmap.josm.data.validation.TestError;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.io.Capabilities;
+import org.openstreetmap.josm.io.OsmApi;
+
+/**
+ * Performs validation tests against OSM API capabilities. This class does not test length
+ * of key/values (limited to 255 characters) because it's done by {@code TagChecker}.
+ * @since 7574
+ */
+public class ApiCapabilitiesTest extends Test {
+
+    private static final int MAX_WAY_NODES_ERROR = 3401;
+
+    private long maxNodes = -1;
+
+    /**
+     * Constructs a new {@code ApiCapabilitiesTest}.
+     */
+    public ApiCapabilitiesTest() {
+        super(tr("API Capabilities"), tr("Checks for errors against API capabilities"));
+    }
+
+    @Override
+    public void initialize() throws Exception {
+        super.initialize();
+        OsmApi api = OsmApi.getOsmApi();
+        api.initialize(NullProgressMonitor.INSTANCE);
+        Capabilities capabilities = api.getCapabilities();
+        if (capabilities != null) {
+            maxNodes = capabilities.getMaxWayNodes();
+        }
+    }
+
+    @Override
+    public void visit(Way w) {
+        if (maxNodes > 1 && w.getNodesCount() > maxNodes) {
+            String message;
+            if (w.isClosed()) {
+                message = tr("Way contains more than {0} nodes. It should be replaced by a multipolygon", maxNodes);
+            } else {
+                message = tr("Way contains more than {0} nodes. It should be split or simplified", maxNodes);
+            }
+            errors.add(new TestError(this, Severity.ERROR, message, MAX_WAY_NODES_ERROR, w));
+        }
+    }
+}
