diff --git a/src/org/openstreetmap/josm/gui/preferences/RemoteControlPreference.java b/src/org/openstreetmap/josm/gui/preferences/RemoteControlPreference.java
index c38c523..ef636b0 100644
--- a/src/org/openstreetmap/josm/gui/preferences/RemoteControlPreference.java
+++ b/src/org/openstreetmap/josm/gui/preferences/RemoteControlPreference.java
@@ -8,6 +8,9 @@ import java.awt.Font;
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
@@ -15,17 +18,12 @@ import javax.swing.JCheckBox;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JSeparator;
-import javax.swing.UIManager;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
-import org.openstreetmap.josm.io.remotecontrol.handler.AddNodeHandler;
-import org.openstreetmap.josm.io.remotecontrol.handler.ImageryHandler;
-import org.openstreetmap.josm.io.remotecontrol.handler.ImportHandler;
-import org.openstreetmap.josm.io.remotecontrol.handler.LoadAndZoomHandler;
 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler;
-import org.openstreetmap.josm.io.remotecontrol.handler.VersionHandler;
 import org.openstreetmap.josm.tools.GBC;
 
 /**
@@ -33,35 +31,46 @@ import org.openstreetmap.josm.tools.GBC;
  *
  * @author Frederik Ramm
  */
-public class RemoteControlPreference extends DefaultTabPreferenceSetting
-{
+public class RemoteControlPreference extends DefaultTabPreferenceSetting {
+
     public static class Factory implements PreferenceSettingFactory {
+
         @Override
         public PreferenceSetting createPreferenceSetting() {
             return new RemoteControlPreference();
         }
     }
-    
+
     private RemoteControlPreference() {
         super("remotecontrol", tr("Remote Control"), tr("Settings for the remote control feature."));
+        for (PermissionPrefWithDefault p : PermissionPrefWithDefault.getPermissionPrefs()) {
+            JCheckBox cb = new JCheckBox(p.preferenceText);
+            cb.setSelected(p.isAllowed());
+            prefs.put(p, cb);
+        }
     }
-
+    private final Map<PermissionPrefWithDefault, JCheckBox> prefs =
+            new LinkedHashMap<PermissionPrefWithDefault, JCheckBox>();
     private JCheckBox enableRemoteControl;
-
-    private JCheckBox permissionLoadData = new JCheckBox(tr("Load data from API"));
-    private JCheckBox permissionImportData = new JCheckBox(tr("Import data from URL"));
-    private JCheckBox permissionLoadImagery = new JCheckBox(tr("Load imagery layers"));
-    private JCheckBox permissionCreateObjects = new JCheckBox(tr("Create new objects"));
-    private JCheckBox permissionChangeSelection = new JCheckBox(tr("Change the selection"));
-    private JCheckBox permissionChangeViewport = new JCheckBox(tr("Change the viewport"));
-    private JCheckBox permissionReadProtocolversion = new JCheckBox(tr("Read protocol version"));
     private JCheckBox loadInNewLayer = new JCheckBox(tr("Download objects to new layer"));
     private JCheckBox alwaysAskUserConfirm = new JCheckBox(tr("Confirm all Remote Control actions manually"));
 
+    @Override
     public void addGui(final PreferenceTabbedPane gui) {
 
         JPanel remote = new JPanel(new GridBagLayout());
 
+        final JLabel descLabel = new JLabel("<html>"
+                + tr("Allows JOSM to be controlled from other applications, e.g. from a web browser.")
+                + "</html>");
+        descLabel.setFont(descLabel.getFont().deriveFont(Font.PLAIN));
+        remote.add(descLabel, GBC.eol().insets(5, 5, 0, 10).fill(GBC.HORIZONTAL));
+
+        final JLabel portLabel = new JLabel("<html>" + tr("JOSM will always listen at <b>port 8111</b> on localhost. "
+                + "<br>This port is not configurable because it is referenced by external applications talking to JOSM.") + "</html>");
+        portLabel.setFont(portLabel.getFont().deriveFont(Font.PLAIN));
+        remote.add(portLabel, GBC.eol().insets(5, 5, 0, 10).fill(GBC.HORIZONTAL));
+
         remote.add(enableRemoteControl = new JCheckBox(tr("Enable remote control"), RemoteControl.PROP_REMOTECONTROL_ENABLED.get()), GBC.eol());
 
         final JPanel wrapper = new JPanel();
@@ -70,53 +79,27 @@ public class RemoteControlPreference extends DefaultTabPreferenceSetting
 
         remote.add(wrapper, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 5));
 
-        final JLabel descLabel = new JLabel("<html>"+
-                tr("The remote control feature allows JOSM to be controlled from other applications, e.g. from a web browser.")
-                + "</html>");
-        wrapper.add(descLabel, GBC.eol().insets(5,5,0,10).fill(GBC.HORIZONTAL));
-        descLabel.setFont(descLabel.getFont().deriveFont(Font.PLAIN));
-
         wrapper.add(new JLabel(tr("Permitted actions:")), GBC.eol());
         int INDENT = 15;
-        wrapper.add(permissionLoadData, GBC.eol().insets(INDENT,5,0,0).fill(GBC.HORIZONTAL));
-        wrapper.add(permissionImportData, GBC.eol().insets(INDENT,5,0,0).fill(GBC.HORIZONTAL));
-        wrapper.add(permissionLoadImagery, GBC.eol().insets(INDENT,5,0,0).fill(GBC.HORIZONTAL));
-        wrapper.add(permissionChangeSelection, GBC.eol().insets(INDENT,5,0,0).fill(GBC.HORIZONTAL));
-        wrapper.add(permissionChangeViewport, GBC.eol().insets(INDENT,5,0,0).fill(GBC.HORIZONTAL));
-        wrapper.add(permissionCreateObjects, GBC.eol().insets(INDENT,5,0,0).fill(GBC.HORIZONTAL));
-        wrapper.add(permissionReadProtocolversion, GBC.eol().insets(INDENT,5,0,0).fill(GBC.HORIZONTAL));
+        for (JCheckBox p : prefs.values()) {
+            wrapper.add(p, GBC.eol().insets(INDENT, 5, 0, 0).fill(GBC.HORIZONTAL));
+        }
 
         wrapper.add(new JSeparator(), GBC.eop().fill(GBC.HORIZONTAL).insets(15, 5, 15, 5));
-
         wrapper.add(loadInNewLayer, GBC.eol().fill(GBC.HORIZONTAL));
-
         wrapper.add(alwaysAskUserConfirm, GBC.eol().fill(GBC.HORIZONTAL));
 
-        final JLabel portLabel = new JLabel("<html>"+tr("JOSM will always listen at port 8111 on localhost. " +
-                "This port is not configurable because it is referenced by external applications talking to JOSM.") + "</html>");
-        portLabel.setFont(portLabel.getFont().deriveFont(Font.PLAIN));
-
-        wrapper.add(portLabel, GBC.eol().insets(5,5,0,10).fill(GBC.HORIZONTAL));
-
         remote.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
 
-        permissionLoadData.setSelected(Main.pref.getBoolean(LoadAndZoomHandler.loadDataPermissionKey, LoadAndZoomHandler.loadDataPermissionDefault));
-        permissionImportData.setSelected(Main.pref.getBoolean(ImportHandler.permissionKey, ImportHandler.permissionDefault));
-        permissionLoadImagery.setSelected(Main.pref.getBoolean(ImageryHandler.permissionKey, ImageryHandler.permissionDefault));
-        permissionChangeSelection.setSelected(Main.pref.getBoolean(LoadAndZoomHandler.changeSelectionPermissionKey, LoadAndZoomHandler.changeSelectionPermissionDefault));
-        permissionChangeViewport.setSelected(Main.pref.getBoolean(LoadAndZoomHandler.changeViewportPermissionKey, LoadAndZoomHandler.changeViewportPermissionDefault));
-        permissionCreateObjects.setSelected(Main.pref.getBoolean(AddNodeHandler.permissionKey, AddNodeHandler.permissionDefault));
-        permissionReadProtocolversion.setSelected(Main.pref.getBoolean(VersionHandler.permissionKey, VersionHandler.permissionDefault));
         loadInNewLayer.setSelected(Main.pref.getBoolean(RequestHandler.loadInNewLayerKey, RequestHandler.loadInNewLayerDefault));
         alwaysAskUserConfirm.setSelected(Main.pref.getBoolean(RequestHandler.globalConfirmationKey, RequestHandler.globalConfirmationDefault));
 
         ActionListener remoteControlEnabled = new ActionListener() {
+
+            @Override
             public void actionPerformed(ActionEvent e) {
-                boolean enabled = enableRemoteControl.isSelected();
                 GuiHelper.setEnabledRec(wrapper, enableRemoteControl.isSelected());
                 // 'setEnabled(false)' does not work for JLabel with html text, so do it manually
-                portLabel.setForeground(enabled ? UIManager.getColor("Label.foreground") : UIManager.getColor("Label.disabledForeground"));
-                descLabel.setForeground(enabled ? UIManager.getColor("Label.foreground") : UIManager.getColor("Label.disabledForeground"));
                 // FIXME: use QuadStateCheckBox to make checkboxes unset when disabled
             }
         };
@@ -125,17 +108,14 @@ public class RemoteControlPreference extends DefaultTabPreferenceSetting
         createPreferenceTabWithScrollPane(gui, remote);
     }
 
+    @Override
     public boolean ok() {
         boolean enabled = enableRemoteControl.isSelected();
         boolean changed = RemoteControl.PROP_REMOTECONTROL_ENABLED.put(enabled);
         if (enabled) {
-            Main.pref.put(LoadAndZoomHandler.loadDataPermissionKey, permissionLoadData.isSelected());
-            Main.pref.put(ImportHandler.permissionKey, permissionImportData.isSelected());
-            Main.pref.put(ImageryHandler.permissionKey, permissionLoadImagery.isSelected());
-            Main.pref.put(LoadAndZoomHandler.changeSelectionPermissionKey, permissionChangeSelection.isSelected());
-            Main.pref.put(LoadAndZoomHandler.changeViewportPermissionKey, permissionChangeViewport.isSelected());
-            Main.pref.put(AddNodeHandler.permissionKey, permissionCreateObjects.isSelected());
-            Main.pref.put(VersionHandler.permissionKey, permissionReadProtocolversion.isSelected());
+            for (Entry<PermissionPrefWithDefault, JCheckBox> p : prefs.entrySet()) {
+                Main.pref.put(p.getKey().pref, p.getValue().isSelected());
+            }
             Main.pref.put(RequestHandler.loadInNewLayerKey, loadInNewLayer.isSelected());
             Main.pref.put(RequestHandler.globalConfirmationKey, alwaysAskUserConfirm.isSelected());
         }
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/PermissionPrefWithDefault.java b/src/org/openstreetmap/josm/io/remotecontrol/PermissionPrefWithDefault.java
index 9ab7335..6a37dd3 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/PermissionPrefWithDefault.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/PermissionPrefWithDefault.java
@@ -1,25 +1,63 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.io.remotecontrol;
 
+import java.util.Arrays;
+import java.util.List;
+import org.openstreetmap.josm.Main;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
 /**
  * Contains a preference name to control permission for the operation
- * implemented by the RequestHandler, and an error message to be displayed
- * if not permitted.
+ * implemented by the RequestHandler, and an error message to be displayed if
+ * not permitted.
  *
  * @author Bodo Meissner
  */
 public class PermissionPrefWithDefault {
 
-    /** name of the preference setting to permit the remote operation */
-    public String pref;
-    /** message to be displayed if operation is not permitted */
-    public String message;
-
-    public boolean defaultVal = true;
+    public static final PermissionPrefWithDefault LOAD_DATA =
+            new PermissionPrefWithDefault("remotecontrol.permission.load-data", true, tr("Load data from API"));
+    public static final PermissionPrefWithDefault IMPORT_DATA =
+            new PermissionPrefWithDefault("remotecontrol.permission.import", true, tr("Import data from URL"));
+    public static final PermissionPrefWithDefault OPEN_FILES =
+            new PermissionPrefWithDefault("remotecontrol.permission.open-files", false, tr("Open local files"));
+    public static final PermissionPrefWithDefault LOAD_IMAGERY =
+            new PermissionPrefWithDefault("remotecontrol.permission.imagery", true, tr("Load imagery layers"));
+    public static final PermissionPrefWithDefault CHANGE_SELECTION =
+            new PermissionPrefWithDefault("remotecontrol.permission.change-selection", true, tr("Change the selection"));
+    public static final PermissionPrefWithDefault CHANGE_VIEWPORT =
+            new PermissionPrefWithDefault("remotecontrol.permission.change-viewport", true, tr("Change the viewport"));
+    public static final PermissionPrefWithDefault CREATE_OBJECTS =
+            new PermissionPrefWithDefault("remotecontrol.permission.create-objects", true, tr("Create new objects"));
+    public static final PermissionPrefWithDefault READ_PROTOCOL_VERSION =
+            new PermissionPrefWithDefault("remotecontrol.permission.read-protocolversion", true, tr("Read protocol version"));
+    /**
+     * name of the preference setting to permit the remote operation
+     */
+    public final String pref;
+    /**
+     * default preference setting
+     */
+    public final boolean defaultVal;
+    /**
+     * text for the preference dialog checkbox
+     */
+    public final String preferenceText;
 
-    public PermissionPrefWithDefault(String pref, boolean defaultVal, String message) {
+    public PermissionPrefWithDefault(String pref, boolean defaultVal, String preferenceText) {
         this.pref = pref;
-        this.message = message;
         this.defaultVal = defaultVal;
+        this.preferenceText = preferenceText;
+    }
+
+    public boolean isAllowed() {
+        return Main.pref.getBoolean(pref, defaultVal);
+    }
+
+    public static List<PermissionPrefWithDefault> getPermissionPrefs() {
+        return Arrays.asList(
+                LOAD_DATA, IMPORT_DATA, OPEN_FILES, LOAD_IMAGERY,
+                CHANGE_SELECTION, CHANGE_VIEWPORT,
+                CREATE_OBJECTS, READ_PROTOCOL_VERSION);
     }
 }
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java b/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java
index 6bedb97..a7b35b2 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java
@@ -12,12 +12,10 @@ import java.io.Writer;
 import java.net.Socket;
 import java.util.Arrays;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.StringTokenizer;
 import java.util.TreeMap;
-import java.util.TreeSet;
 
 import org.openstreetmap.josm.io.remotecontrol.handler.AddNodeHandler;
 import org.openstreetmap.josm.io.remotecontrol.handler.AddWayHandler;
@@ -25,6 +23,7 @@ import org.openstreetmap.josm.io.remotecontrol.handler.ImageryHandler;
 import org.openstreetmap.josm.io.remotecontrol.handler.ImportHandler;
 import org.openstreetmap.josm.io.remotecontrol.handler.LoadAndZoomHandler;
 import org.openstreetmap.josm.io.remotecontrol.handler.LoadObjectHandler;
+import org.openstreetmap.josm.io.remotecontrol.handler.OpenFileHandler;
 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler;
 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerBadRequestException;
 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerErrorException;
@@ -116,16 +115,15 @@ public class RequestProcessor extends Thread {
 
     /** Add default request handlers */
     static {
-        addRequestHandlerClass(LoadAndZoomHandler.command,
-                LoadAndZoomHandler.class, true);
-        addRequestHandlerClass(LoadAndZoomHandler.command2,
-                LoadAndZoomHandler.class, true);
+        addRequestHandlerClass(LoadAndZoomHandler.command, LoadAndZoomHandler.class, true);
+        addRequestHandlerClass(LoadAndZoomHandler.command2, LoadAndZoomHandler.class, true);
         addRequestHandlerClass(ImageryHandler.command, ImageryHandler.class, true);
         addRequestHandlerClass(AddNodeHandler.command, AddNodeHandler.class, true);
         addRequestHandlerClass(AddWayHandler.command, AddWayHandler.class, true);
         addRequestHandlerClass(ImportHandler.command, ImportHandler.class, true);
         addRequestHandlerClass(VersionHandler.command, VersionHandler.class, true);
         addRequestHandlerClass(LoadObjectHandler.command, LoadObjectHandler.class, true);
+        addRequestHandlerClass(OpenFileHandler.command, OpenFileHandler.class, true);
     }
 
     /**
@@ -202,7 +200,6 @@ public class RequestProcessor extends Thread {
                 try {
                     handler.setCommand(command);
                     handler.setUrl(url);
-                    handler.checkPermission();
                     handler.handle();
                     sendHeader(out, "200 OK", handler.getContentType(), false);
                     out.write("Content-length: " + handler.getContent().length()
@@ -215,7 +212,7 @@ public class RequestProcessor extends Thread {
                 } catch (RequestHandlerBadRequestException ex) {
                     sendBadRequest(out, ex.getMessage());
                 } catch (RequestHandlerForbiddenException ex) {
-                    sendForbidden(out);
+                    sendForbidden(out, ex.getMessage());
                 }
             }
 
@@ -280,13 +277,16 @@ public class RequestProcessor extends Thread {
      * @throws IOException
      *             If the error can not be written
      */
-    private void sendForbidden(Writer out) throws IOException {
+    private void sendForbidden(Writer out, String help) throws IOException {
         sendHeader(out, "403 Forbidden", "text/html", true);
         out.write("<HTML>\r\n");
         out.write("<HEAD><TITLE>Forbidden</TITLE>\r\n");
         out.write("</HEAD>\r\n");
         out.write("<BODY>");
         out.write("<H1>HTTP Error 403: Forbidden</h2>\r\n");
+        if (help != null) {
+            out.write(help);
+        }
         out.write("</BODY></HTML>\r\n");
         out.flush();
     }
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java
index 09d7971..4ed5bc6 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java
@@ -17,8 +17,6 @@ import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 public class AddNodeHandler extends RequestHandler {
 
     public static final String command = "add_node";
-    public static final String permissionKey = "remotecontrol.permission.create-objects";
-    public static final boolean permissionDefault = false;
 
     @Override
     protected void handleRequest() {
@@ -38,8 +36,7 @@ public class AddNodeHandler extends RequestHandler {
 
     @Override
     public PermissionPrefWithDefault getPermissionPref() {
-        return new PermissionPrefWithDefault(permissionKey, permissionDefault,
-                "RemoteControl: creating objects forbidden by preferences");
+        return PermissionPrefWithDefault.CREATE_OBJECTS;
     }
 
     /**
@@ -60,7 +57,7 @@ public class AddNodeHandler extends RequestHandler {
         // Now execute the commands to add this node.
         Main.main.undoRedo.add(new AddCommand(nnew));
         Main.main.getCurrentDataSet().setSelected(nnew);
-        if (Main.pref.getBoolean(LoadAndZoomHandler.changeViewportPermissionKey, LoadAndZoomHandler.changeViewportPermissionDefault)) {
+        if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) {
             AutoScaleAction.autoScale("selection");
         } else {
             Main.map.mapView.repaint();
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java
index df43c09..c1cab8c 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java
@@ -12,6 +12,7 @@ import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 
 /**
  * Adds a way to the current dataset. For instance, {@code /add_way?way=lat1,lon2;lat2,lon2}.
@@ -40,7 +41,7 @@ public class AddWayHandler extends RequestHandler {
         commands.add(new AddCommand(way));
         Main.main.undoRedo.add(new SequenceCommand(tr("Add way"), commands));
         Main.main.getCurrentDataSet().setSelected(way);
-        if (Main.pref.getBoolean(LoadAndZoomHandler.changeViewportPermissionKey, LoadAndZoomHandler.changeViewportPermissionDefault)) {
+        if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) {
             AutoScaleAction.autoScale("selection");
         } else {
             Main.map.mapView.repaint();
@@ -51,4 +52,9 @@ public class AddWayHandler extends RequestHandler {
     public String getPermissionMessage() {
         return tr("Remote Control has been asked to create a new way.");
     }
+
+    @Override
+    public PermissionPrefWithDefault getPermissionPref() {
+        return PermissionPrefWithDefault.CREATE_OBJECTS;
+    }
 }
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java
index c0a825b..25c3194 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java
@@ -6,7 +6,6 @@ import static org.openstreetmap.josm.tools.I18n.tr;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.HashMap;
-import java.util.StringTokenizer;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
@@ -14,38 +13,35 @@ import org.openstreetmap.josm.gui.layer.ImageryLayer;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 
 public class ImageryHandler extends RequestHandler {
+
     public static final String command = "imagery";
-    public static final String permissionKey = "remotecontrol.permission.imagery";
-    public static final boolean permissionDefault = true;
 
     @Override
     public String getPermissionMessage() {
-        return tr("Remote Control has been asked to load an imagery layer from the following URL:") +
-        "<br>" + args.get("url");
+        return tr("Remote Control has been asked to load an imagery layer from the following URL:")
+                + "<br>" + args.get("url");
     }
 
     @Override
-    public String[] getMandatoryParams()
-    {
-        return new String[] { "url" };
+    public String[] getMandatoryParams() {
+        return new String[]{"url"};
     }
 
     @Override
-    public PermissionPrefWithDefault getPermissionPref()
-    {
-        return new PermissionPrefWithDefault(permissionKey, permissionDefault,
-        "RemoteControl: import forbidden by preferences");
+    public PermissionPrefWithDefault getPermissionPref() {
+        return PermissionPrefWithDefault.LOAD_IMAGERY;
     }
 
     @Override
     protected void handleRequest() throws RequestHandlerErrorException {
         if (Main.map == null) //Avoid exception when creating ImageryLayer with null MapFrame
+        {
             throw new RequestHandlerErrorException();
+        }
         String url = args.get("url");
         String title = args.get("title");
         String type = args.get("type");
-        if((title == null) || (title.length() == 0))
-        {
+        if ((title == null) || (title.length() == 0)) {
             title = tr("Remote imagery");
         }
         String cookies = args.get("cookies");
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java
index edc5690..4175a51 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java
@@ -17,8 +17,6 @@ import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 public class ImportHandler extends RequestHandler {
 
     public static final String command = "import";
-    public static final String permissionKey = "remotecontrol.permission.import";
-    public static final boolean permissionDefault = true;
 
     @Override
     protected void handleRequest() throws RequestHandlerErrorException {
@@ -33,22 +31,19 @@ public class ImportHandler extends RequestHandler {
     }
 
     @Override
-    public String[] getMandatoryParams()
-    {
-        return new String[] { "url" };
+    public String[] getMandatoryParams() {
+        return new String[]{"url"};
     }
 
     @Override
     public String getPermissionMessage() {
-        return tr("Remote Control has been asked to import data from the following URL:") +
-        "<br>" + request;
+        return tr("Remote Control has been asked to import data from the following URL:")
+                + "<br>" + request;
     }
 
     @Override
-    public PermissionPrefWithDefault getPermissionPref()
-    {
-        return new PermissionPrefWithDefault(permissionKey, permissionDefault,
-                "RemoteControl: import forbidden by preferences");
+    public PermissionPrefWithDefault getPermissionPref() {
+        return PermissionPrefWithDefault.IMPORT_DATA;
     }
 
     @Override
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
index bf27616..98c903a 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
@@ -24,6 +24,7 @@ import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
+import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -34,13 +35,6 @@ public class LoadAndZoomHandler extends RequestHandler
     public static final String command = "load_and_zoom";
     public static final String command2 = "zoom";
 
-    public static final String loadDataPermissionKey = "remotecontrol.permission.load-data";
-    public static final boolean loadDataPermissionDefault = true;
-    public static final String changeSelectionPermissionKey = "remotecontrol.permission.change-selection";
-    public static final boolean changeSelectionPermissionDefault = true;
-    public static final String changeViewportPermissionKey = "remotecontrol.permission.change-viewport";
-    public static final boolean changeViewportPermissionDefault = true;
-
     @Override
     public String getPermissionMessage()
     {
@@ -71,7 +65,7 @@ public class LoadAndZoomHandler extends RequestHandler
 
             if(command.equals(myCommand))
             {
-                if (!Main.pref.getBoolean(loadDataPermissionKey, loadDataPermissionDefault))
+                if (!PermissionPrefWithDefault.LOAD_DATA.isAllowed())
                 {
                     System.out.println("RemoteControl: download forbidden by preferences");
                 }
@@ -130,7 +124,7 @@ public class LoadAndZoomHandler extends RequestHandler
             });
         }
 
-        if (args.containsKey("select") && Main.pref.getBoolean(changeSelectionPermissionKey, changeSelectionPermissionDefault)) {
+        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() {
@@ -171,7 +165,7 @@ public class LoadAndZoomHandler extends RequestHandler
                         }
                     }
                     ds.setSelected(newSel);
-                    if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) {
+                    if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) {
                         AutoScaleAction.autoScale("selection");
                     }
                     if (Main.map != null && Main.map.relationListDialog != null) {
@@ -181,7 +175,7 @@ public class LoadAndZoomHandler extends RequestHandler
                     }
                 }
             });
-        } else if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) {
+        } else if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) {
             // after downloading, zoom to downloaded area.
             zoom(minlat, maxlat, minlon, maxlon);
         }
@@ -231,4 +225,9 @@ public class LoadAndZoomHandler extends RequestHandler
             });
         }
     }
+
+    @Override
+    public PermissionPrefWithDefault getPermissionPref() {
+        return null;
+    }
 }
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
index fe38e39..011860c 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
@@ -4,10 +4,10 @@ import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.util.LinkedList;
 import java.util.List;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.DownloadPrimitiveAction;
 import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
+import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 
 /**
  * Loads OSM primitives using their ID
@@ -25,7 +25,7 @@ public class LoadObjectHandler extends RequestHandler {
 
     @Override
     protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException {
-        if (!Main.pref.getBoolean(LoadAndZoomHandler.loadDataPermissionKey, LoadAndZoomHandler.loadDataPermissionDefault)) {
+        if (!PermissionPrefWithDefault.LOAD_DATA.isAllowed()) {
             System.out.println("RemoteControl: download forbidden by preferences");
         }
         List<PrimitiveId> ps = new LinkedList<PrimitiveId>();
@@ -41,4 +41,9 @@ public class LoadObjectHandler extends RequestHandler {
     public String getPermissionMessage() {
         return tr("Remote Control has been asked to load objects (specified by their id) from the API.");
     }
+
+    @Override
+    public PermissionPrefWithDefault getPermissionPref() {
+        return PermissionPrefWithDefault.LOAD_DATA;
+    }
 }
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java
new file mode 100644
index 0000000..a049045
--- /dev/null
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/OpenFileHandler.java
@@ -0,0 +1,32 @@
+package org.openstreetmap.josm.io.remotecontrol.handler;
+
+import java.io.File;
+import java.util.Arrays;
+import org.openstreetmap.josm.actions.OpenFileAction;
+import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+public class OpenFileHandler extends RequestHandler {
+
+    public static final String command = "open_file";
+
+    @Override
+    public String[] getMandatoryParams() {
+        return new String[]{"filename"};
+    }
+
+    @Override
+    public PermissionPrefWithDefault getPermissionPref() {
+        return PermissionPrefWithDefault.OPEN_FILES;
+    }
+
+    @Override
+    protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException {
+        OpenFileAction.openFiles(Arrays.asList(new File(args.get("filename"))));
+    }
+
+    @Override
+    public String getPermissionMessage() {
+        return tr("Remote Control has been asked to open a local file.");
+    }
+}
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
index 77d12d4..052493f 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
@@ -3,10 +3,10 @@ package org.openstreetmap.josm.io.remotecontrol.handler;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.text.MessageFormat;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.StringTokenizer;
 
 import javax.swing.JOptionPane;
 
@@ -49,8 +49,8 @@ public abstract class RequestHandler {
      */
     public final void handle() throws RequestHandlerForbiddenException, RequestHandlerBadRequestException, RequestHandlerErrorException
     {
-        checkPermission();
         checkMandatoryParams();
+        checkPermission();
         handleRequest();
     }
 
@@ -85,19 +85,9 @@ public abstract class RequestHandler {
      *
      * @return the preference name and error message or null
      */
-    public PermissionPrefWithDefault getPermissionPref()
-    {
-        /* Example:
-        return new PermissionPrefWithDefault("fooobar.remotecontrol",
-        true
-        "RemoteControl: foobar forbidden by preferences");
-        */
-        return null;
-    }
+    abstract public PermissionPrefWithDefault getPermissionPref();
 
-    public String[] getMandatoryParams() {
-        return null;
-    }
+    abstract public String[] getMandatoryParams();
 
     /**
      * Check permissions in preferences and display error message
@@ -118,8 +108,9 @@ public abstract class RequestHandler {
         if((permissionPref != null) && (permissionPref.pref != null))
         {
             if (!Main.pref.getBoolean(permissionPref.pref, permissionPref.defaultVal)) {
-                System.out.println(permissionPref.message);
-                throw new RequestHandlerForbiddenException();
+                String err = MessageFormat.format("RemoteControl: ''{0}'' forbidden by preferences", myCommand);
+                System.out.println(err);
+                throw new RequestHandlerForbiddenException(err);
             }
         }
 
@@ -132,7 +123,8 @@ public abstract class RequestHandler {
                 "<br>" + tr("Do you want to allow this?"),
                 tr("Confirm Remote Control action"),
                 JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
-                    throw new RequestHandlerForbiddenException();
+                    String err = MessageFormat.format("RemoteControl: ''{0}'' forbidden by user''s choice", myCommand);
+                    throw new RequestHandlerForbiddenException(err);
             }
         }
     }
@@ -177,8 +169,7 @@ public abstract class RequestHandler {
 
         List<String> missingKeys = new LinkedList<String>();
         boolean error = false;
-        for (int i = 0; i < mandatory.length; ++i) {
-            String key = mandatory[i];
+        for (String key : mandatory) {
             String value = args.get(key);
             if ((value == null) || (value.length() == 0)) {
                 error = true;
@@ -242,5 +233,9 @@ public abstract class RequestHandler {
 
     public static class RequestHandlerForbiddenException extends RequestHandlerException {
         private static final long serialVersionUID = 2263904699747115423L;
+
+        public RequestHandlerForbiddenException(String message) {
+            super(message);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java
index 44dda58..baf1783 100644
--- a/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java
+++ b/src/org/openstreetmap/josm/io/remotecontrol/handler/VersionHandler.java
@@ -12,8 +12,6 @@ import org.openstreetmap.josm.io.remotecontrol.RequestProcessor;
 public class VersionHandler extends RequestHandler {
 
     public static final String command = "version";
-    public static final String permissionKey = "remotecontrol.permission.read-protocolversion";
-    public static final boolean permissionDefault = true;
 
     @Override
     protected void handleRequest() throws RequestHandlerErrorException,
@@ -21,7 +19,7 @@ public class VersionHandler extends RequestHandler {
         content = RequestProcessor.PROTOCOLVERSION;
         contentType = "application/json";
         if (args.containsKey("jsonp")) {
-            content = args.get("jsonp")+ " && " + args.get("jsonp") + "(" + content + ")";
+            content = args.get("jsonp") + " && " + args.get("jsonp") + "(" + content + ")";
         }
     }
 
@@ -31,9 +29,12 @@ public class VersionHandler extends RequestHandler {
     }
 
     @Override
-    public PermissionPrefWithDefault getPermissionPref()
-    {
-        return new PermissionPrefWithDefault(permissionKey, permissionDefault,
-                "RemoteControl: /version forbidden by preferences");
+    public PermissionPrefWithDefault getPermissionPref() {
+        return PermissionPrefWithDefault.READ_PROTOCOL_VERSION;
+    }
+
+    @Override
+    public String[] getMandatoryParams() {
+        return null;
     }
 }
\ No newline at end of file
