Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java	(revision 5680)
@@ -11,4 +11,5 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerBadRequestException;
 
 /**
@@ -17,5 +18,11 @@
 public class AddNodeHandler extends RequestHandler {
 
+    /**
+     * The remote control command name used to add a node.
+     */
     public static final String command = "add_node";
+    
+    private double lat;
+    private double lon;
 
     @Override
@@ -32,5 +39,6 @@
     @Override
     public String getPermissionMessage() {
-        return tr("Remote Control has been asked to create a new node.");
+        return tr("Remote Control has been asked to create a new node.") +
+                "<br>" + tr("Coordinates: ") + args.get("lat") + ", " + args.get("lon");
     }
 
@@ -47,6 +55,4 @@
 
         // Parse the arguments
-        double lat = Double.parseDouble(args.get("lat"));
-        double lon = Double.parseDouble(args.get("lon"));
         System.out.println("Adding node at (" + lat + ", " + lon + ")");
 
@@ -64,3 +70,13 @@
         }
     }
+
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        try {
+            lat = Double.parseDouble(args.get("lat"));
+            lon = Double.parseDouble(args.get("lon"));
+        } catch (NumberFormatException e) {
+            throw new RequestHandlerBadRequestException("NumberFormatException ("+e.getMessage()+")");
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java	(revision 5680)
@@ -3,6 +3,9 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AutoScaleAction;
@@ -14,4 +17,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerBadRequestException;
 
 /**
@@ -20,5 +24,10 @@
 public class AddWayHandler extends RequestHandler {
 
+    /**
+     * The remote control command name used to add a way.
+     */
     public static final String command = "add_way";
+    
+    private final List<LatLon> allCoordinates = new ArrayList<LatLon>();
 
     @Override
@@ -31,12 +40,10 @@
         Way way = new Way();
         List<Command> commands = new LinkedList<Command>();
-        for (String coordinatesString : args.get("way").split(";\\s*")) {
-            String[] coordinates = coordinatesString.split(",\\s*", 2);
-            double lat = Double.parseDouble(coordinates[0]);
-            double lon = Double.parseDouble(coordinates[1]);
-            Node node = new Node(new LatLon(lat, lon));
+        for (LatLon ll : allCoordinates) {
+            Node node = new Node(ll);
             way.addNode(node);
             commands.add(new AddCommand(node));
         }
+        allCoordinates.clear();
         commands.add(new AddCommand(way));
         Main.main.undoRedo.add(new SequenceCommand(tr("Add way"), commands));
@@ -58,3 +65,27 @@
         return PermissionPrefWithDefault.CREATE_OBJECTS;
     }
+
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        allCoordinates.clear();
+        for (String coordinatesString : args.get("way").split(";\\s*")) {
+            String[] coordinates = coordinatesString.split(",\\s*", 2);
+            if (coordinates.length < 2) {
+                throw new RequestHandlerBadRequestException(
+                        tr("Invalid coordinates: {0}", Arrays.toString(coordinates)));
+            }
+            try {
+                double lat = Double.parseDouble(coordinates[0]);
+                double lon = Double.parseDouble(coordinates[1]);
+                allCoordinates.add(new LatLon(lat, lon));
+            } catch (NumberFormatException e) {
+                throw new RequestHandlerBadRequestException("NumberFormatException ("+e.getMessage()+")");
+            }
+        }
+        if (allCoordinates.isEmpty()) {
+            throw new RequestHandlerBadRequestException(tr("Empty ways"));
+        } else if (allCoordinates.size() == 1) {
+            throw new RequestHandlerBadRequestException(tr("One node ways"));
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java	(revision 5680)
@@ -4,6 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
 import java.util.HashMap;
 
@@ -59,5 +57,5 @@
                 imgInfo.setDefaultMinZoom(Integer.parseInt(min_zoom));
             } catch (NumberFormatException e) {
-                System.err.println(e.getMessage());
+                System.err.println("NumberFormatException ("+e.getMessage()+")");
             }
         }
@@ -67,5 +65,5 @@
                 imgInfo.setDefaultMaxZoom(Integer.parseInt(max_zoom));
             } catch (NumberFormatException e) {
-                System.err.println(e.getMessage());
+                System.err.println("NumberFormatException ("+e.getMessage()+")");
             }
         }
@@ -102,10 +100,7 @@
     }
 
-    private String decodeParam(String param) {
-        try {
-            return URLDecoder.decode(param, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException();
-        }
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        // Nothing to do
     }
 }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java	(revision 5680)
@@ -4,6 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
 import java.util.HashMap;
 
@@ -17,4 +15,7 @@
 public class ImportHandler extends RequestHandler {
 
+    /**
+     * The remote control command name used to import data.
+     */
     public static final String command = "import";
 
@@ -39,5 +40,5 @@
     public String getPermissionMessage() {
         return tr("Remote Control has been asked to import data from the following URL:")
-                + "<br>" + request;
+                + "<br>" + args.get("url");
     }
 
@@ -53,10 +54,10 @@
             String query = request.substring(request.indexOf('?') + 1);
             if (query.indexOf("url=") == 0) {
-                args.put("url", decodeURL(query.substring(4)));
+                args.put("url", decodeParam(query.substring(4)));
             } else {
                 int urlIdx = query.indexOf("&url=");
                 if (urlIdx != -1) {
-                    String url = query.substring(urlIdx + 1);
-                    args.put("url", decodeURL(query.substring(urlIdx + 5)));
+                    /*String url =*/ query.substring(urlIdx + 1);
+                    args.put("url", decodeParam(query.substring(urlIdx + 5)));
                     query = query.substring(0, urlIdx);
                 } else {
@@ -77,10 +78,7 @@
     }
 
-    private String decodeURL(String url) {
-        try {
-            return URLDecoder.decode(url, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException();
-        }
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        // Nothing to do
     }
 }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java	(revision 5680)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.BBox;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -35,12 +36,34 @@
 public class LoadAndZoomHandler extends RequestHandler
 {
+    /**
+     * The remote control command name used to load data and zoom.
+     */
     public static final String command = "load_and_zoom";
+    
+    /**
+     * The remote control command name used to zoom.
+     */
     public static final String command2 = "zoom";
+
+    // Mandatory arguments
+    private double minlat;
+    private double maxlat;
+    private double minlon;
+    private double maxlon;
+
+    // Optional argument 'select'
+    private final Set<Long> ways = new HashSet<Long>();
+    private final Set<Long> nodes = new HashSet<Long>();
+    private final Set<Long> relations = new HashSet<Long>();
 
     @Override
     public String getPermissionMessage()
     {
-        return tr("Remote Control has been asked to load data from the API.") +
-                "<br>" + tr("Request details: {0}", request);
+        String msg = tr("Remote Control has been asked to load data from the API.") +
+                "<br>" + tr("Bounding box: ") + new BBox(minlon, minlat, maxlon, maxlat).toStringCSV(", ");
+        if (args.containsKey("select") && ways.size()+nodes.size()+relations.size() > 0) {
+            msg += "<br>" + tr("Sel.: Rel.:{0} / Ways:{1} / Nodes:{2}", relations.size(), ways.size(), nodes.size());
+        }
+        return msg;
     }
 
@@ -55,13 +78,5 @@
     {
         DownloadTask osmTask = new DownloadOsmTask();
-        double minlat = 0;
-        double maxlat = 0;
-        double minlon = 0;
-        double maxlon = 0;
         try {
-            minlat = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("bottom")));
-            maxlat = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("top")));
-            minlon = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("left")));
-            maxlon = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("right")));
             boolean newLayer = isLoadInNewLayer();
 
@@ -130,24 +145,7 @@
         if (args.containsKey("select") && PermissionPrefWithDefault.CHANGE_SELECTION.isAllowed()) {
             // select objects after downloading, zoom to selection.
-            final String selection = args.get("select");
-            Main.worker.execute(new Runnable() {
-                public void run() {
-                    HashSet<Long> ways = new HashSet<Long>();
-                    HashSet<Long> nodes = new HashSet<Long>();
-                    HashSet<Long> relations = new HashSet<Long>();
+            Main.worker.execute(new Runnable() {
+                public void run() {
                     HashSet<OsmPrimitive> newSel = new HashSet<OsmPrimitive>();
-                    for (String item : selection.split(",")) {
-                        if (item.startsWith("way")) {
-                            ways.add(Long.parseLong(item.substring(3)));
-                        } else if (item.startsWith("node")) {
-                            nodes.add(Long.parseLong(item.substring(4)));
-                        } else if (item.startsWith("relation")) {
-                            relations.add(Long.parseLong(item.substring(8)));
-                        } else if (item.startsWith("rel")) {
-                            relations.add(Long.parseLong(item.substring(3)));
-                        } else {
-                            System.out.println("RemoteControl: invalid selection '"+item+"' ignored");
-                        }
-                    }
                     DataSet ds = Main.main.getCurrentDataSet();
                     if(ds == null) // e.g. download failed
@@ -158,4 +156,5 @@
                         }
                     }
+                    ways.clear();
                     for (Node n : ds.getNodes()) {
                         if (nodes.contains(n.getId())) {
@@ -163,4 +162,5 @@
                         }
                     }
+                    nodes.clear();
                     for (Relation r : ds.getRelations()) {
                         if (relations.contains(r.getId())) {
@@ -168,4 +168,5 @@
                         }
                     }
+                    relations.clear();
                     ds.setSelected(newSel);
                     if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) {
@@ -190,5 +191,4 @@
 
         addTags(args);
-
     }
 
@@ -245,3 +245,44 @@
         return null;
     }
+
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        // Process mandatory arguments
+        minlat = 0;
+        maxlat = 0;
+        minlon = 0;
+        maxlon = 0;
+        try {
+            minlat = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("bottom")));
+            maxlat = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("top")));
+            minlon = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("left")));
+            maxlon = LatLon.roundToOsmPrecision(Double.parseDouble(args.get("right")));
+        } catch (NumberFormatException e) {
+            throw new RequestHandlerBadRequestException("NumberFormatException ("+e.getMessage()+")");
+        }
+
+        // Process optional argument 'select'
+        if (args.containsKey("select")) {
+            ways.clear();
+            nodes.clear();
+            relations.clear();
+            for (String item : args.get("select").split(",")) {
+                try {
+                    if (item.startsWith("way")) {
+                        ways.add(Long.parseLong(item.substring(3)));
+                    } else if (item.startsWith("node")) {
+                        nodes.add(Long.parseLong(item.substring(4)));
+                    } else if (item.startsWith("relation")) {
+                        relations.add(Long.parseLong(item.substring(8)));
+                    } else if (item.startsWith("rel")) {
+                        relations.add(Long.parseLong(item.substring(3)));
+                    } else {
+                        System.out.println("RemoteControl: invalid selection '"+item+"' ignored");
+                    }
+                } catch (NumberFormatException e) {
+                    System.out.println("RemoteControl: invalid selection '"+item+"' ignored");
+                }
+            }
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java	(revision 5680)
@@ -18,5 +18,10 @@
 public class LoadObjectHandler extends RequestHandler {
 
+    /**
+     * The remote control command name used to load objects using their ID.
+     */
     public static final String command = "load_object";
+    
+    private final List<PrimitiveId> ps = new LinkedList<PrimitiveId>();
 
     @Override
@@ -30,19 +35,18 @@
             System.out.println("RemoteControl: download forbidden by preferences");
         }
-        final List<PrimitiveId> ps = new LinkedList<PrimitiveId>();
-        for (String i : args.get("objects").split(",\\s*")) {
-            ps.add(SimplePrimitiveId.fromString(i));
+        if (!ps.isEmpty()) {
+            boolean newLayer = isLoadInNewLayer();
+            boolean relationMembers = Boolean.parseBoolean(args.get("relation_members"));
+            DownloadPrimitiveAction.processItems(newLayer, ps, true, relationMembers);
+            Main.worker.submit(new Runnable() {
+    
+                @Override
+                public void run() {
+                    Main.main.getCurrentDataSet().setSelected(ps);
+                    LoadAndZoomHandler.addTags(args);
+                    ps.clear();
+                }
+            });
         }
-        boolean newLayer = isLoadInNewLayer();
-        boolean relationMembers = Boolean.parseBoolean(args.get("relation_members"));
-        DownloadPrimitiveAction.processItems(newLayer, ps, true, relationMembers);
-        Main.worker.submit(new Runnable() {
-
-            @Override
-            public void run() {
-                Main.main.getCurrentDataSet().setSelected(ps);
-                LoadAndZoomHandler.addTags(args);
-            }
-        });
     }
 
@@ -56,3 +60,15 @@
         return PermissionPrefWithDefault.LOAD_DATA;
     }
+
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        ps.clear();
+        for (String i : args.get("objects").split(",\\s*")) {
+            try {
+                ps.add(SimplePrimitiveId.fromString(i));
+            } catch (IllegalArgumentException e) {
+                System.out.println("RemoteControl: invalid selection '"+i+"' ignored");
+            }
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java	(revision 5680)
@@ -7,6 +7,12 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+/**
+ * Opens a local file
+ */
 public class OpenFileHandler extends RequestHandler {
 
+    /**
+     * The remote control command name used to open a local file.
+     */
     public static final String command = "open_file";
 
@@ -30,3 +36,8 @@
         return tr("Remote Control has been asked to open a local file.");
     }
+
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        // Nothing to do
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java	(revision 5680)
@@ -53,7 +53,15 @@
     {
         checkMandatoryParams();
+        validateRequest();
         checkPermission();
         handleRequest();
     }
+
+    /**
+     * Validates the request before attempting to perform it.
+     * @throws RequestHandlerBadRequestException
+     * @since 5678
+     */
+    protected abstract void validateRequest() throws RequestHandlerBadRequestException;
 
     /**
@@ -219,4 +227,12 @@
     }
 
+    protected final String decodeParam(String param) {
+        try {
+            return URLDecoder.decode(param, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException();
+        }
+    }
+
     public static class RequestHandlerException extends Exception {
 
Index: /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java	(revision 5679)
+++ /trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java	(revision 5680)
@@ -12,4 +12,7 @@
 public class VersionHandler extends RequestHandler {
 
+    /**
+     * The remote control command name used to reply version.
+     */
     public static final String command = "version";
 
@@ -38,3 +41,8 @@
         return null;
     }
+
+    @Override
+    protected void validateRequest() throws RequestHandlerBadRequestException {
+        // Nothing to do
+    }
 }
