diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java
index c0806157ec4..2be9664e278 100644
--- a/app/src/processing/app/Base.java
+++ b/app/src/processing/app/Base.java
@@ -117,6 +117,10 @@ public class Base {
   // Location for untitled items
   static File untitledFolder;
 
+  // Current directory to use for relative paths specified on the
+  // commandline
+  static String currentDirectory = System.getProperty("user.dir");
+
   // p5 icon for the window
 //  static Image icon;
 
@@ -139,8 +143,28 @@ static public void main(String args[]) throws Exception {
     if (!portableFolder.exists())
       portableFolder = null;
 
+    String preferencesFile = null;
+
+    // Do a first pass over the commandline arguments, the rest of them
+    // will be processed by the Base constructor. Note that this loop
+    // does not look at the last element of args, to prevent crashing
+    // when no parameter was specified to an option. Later, Base() will
+    // then show an error for these.
+    for (int i = 0; i < args.length - 1; i++) {
+      if (args[i].equals("--preferences-file")) {
+        ++i;
+        preferencesFile = args[i];
+        continue;
+      }
+      if (args[i].equals("--curdir")) {
+        i++;
+        currentDirectory = args[i];
+        continue;
+      }
+    }
+
     // run static initialization that grabs all the prefs
-    Preferences.init(args);
+    Preferences.init(absoluteFile(preferencesFile));
 
     try {
       File versionFile = getContentFile("lib/version.txt");
@@ -267,7 +291,22 @@ static protected void initRequirements() {
     }
   }
 
+  // Returns a File object for the given pathname. If the pathname
+  // is not absolute, it is interpreted relative to the current
+  // directory when starting the IDE (which is not the same as the
+  // current working directory!).
+  static public File absoluteFile(String path) {
+    if (path == null) return null;
+
+    File file = new File(path);
+    if (!file.isAbsolute()) {
+      file = new File(currentDirectory, path);
+    }
+    return file;
+  }
+
 
+  protected static enum ACTION { GUI, VERIFY, UPLOAD, NOOP, GET_PREF };
   public Base(String[] args) throws Exception {
     platform.init(this);
 
@@ -283,7 +322,7 @@ public Base(String[] args) throws Exception {
       if (portableFolder != null)
         sketchbookFolder = new File(portableFolder, sketchbookPath);
       else
-        sketchbookFolder = new File(sketchbookPath);
+        sketchbookFolder = Base.absoluteFile(sketchbookPath);
       if (!sketchbookFolder.exists()) {
         Base.showWarning(_("Sketchbook folder disappeared"),
                 _("The sketchbook folder no longer exists.\n" +
@@ -318,23 +357,37 @@ public Base(String[] args) throws Exception {
     // Setup board-dependent variables.
     onBoardOrPortChange();
 
-    boolean doUpload = false;
-    boolean doVerify = false;
+    ACTION action = ACTION.GUI;
     boolean doVerboseBuild = false;
     boolean doVerboseUpload = false;;
+    String getPref = null;
     String selectBoard = null;
     String selectPort = null;
-    String currentDirectory = System.getProperty("user.dir");
     List<String> filenames = new LinkedList<String>();
 
+    // Map of possible actions and corresponding options
+    final Map<String, ACTION> actions = new HashMap<String, ACTION>();
+    actions.put("--verify", ACTION.VERIFY);
+    actions.put("--upload", ACTION.UPLOAD);
+    actions.put("--noop", ACTION.NOOP);
+    actions.put("--get-pref", ACTION.GET_PREF);
+
     // Check if any files were passed in on the command line
     for (int i = 0; i < args.length; i++) {
-      if (args[i].equals("--upload")) {
-        doUpload = true;
-        continue;
-      }
-      if (args[i].equals("--verify")) {
-        doVerify = true;
+      ACTION a = actions.get(args[i]);
+      if (a != null) {
+        if (action != ACTION.GUI) {
+          String[] valid = actions.keySet().toArray(new String[0]);
+          String mess = I18n.format(_("Can only pass one of: {0}"), PApplet.join(valid, ", "));
+          showError(null, mess, 3);
+        }
+        if (a == ACTION.GET_PREF) {
+          i++;
+          if (i >= args.length)
+            showError(null, _("Argument required for --get-pref"), 3);
+          getPref = args[i];
+        }
+        action = a;
         continue;
       }
       if (args[i].equals("--verbose") || args[i].equals("-v")) {
@@ -354,21 +407,21 @@ public Base(String[] args) throws Exception {
         i++;
         if (i >= args.length)
           showError(null, _("Argument required for --board"), 3);
-        selectBoard = args[i];
+        processBoardArgument(args[i]);
         continue;
       }
       if (args[i].equals("--port")) {
         i++;
         if (i >= args.length)
           showError(null, _("Argument required for --port"), 3);
-        selectPort = args[i];
+        Base.selectSerialPort(args[i]);
         continue;
       }
       if (args[i].equals("--curdir")) {
         i++;
         if (i >= args.length)
           showError(null, _("Argument required for --curdir"), 3);
-        currentDirectory = args[i];
+        // Argument should be already processed by Base.main(...)
         continue;
       }
       if (args[i].equals("--pref")) {
@@ -378,11 +431,15 @@ public Base(String[] args) throws Exception {
         processPrefArgument(args[i]);
         continue;
       }
+      if (args[i].equals("--no-save-prefs")) {
+        Preferences.setDoSave(false);
+        continue;
+      }
       if (args[i].equals("--preferences-file")) {
         i++;
         if (i >= args.length)
           showError(null, _("Argument required for --preferences-file"), 3);
-        // Argument should be already processed by Preferences.init(...) 
+        // Argument should be already processed by Base.main(...)
         continue;
       }
       if (args[i].startsWith("--"))
@@ -391,77 +448,103 @@ public Base(String[] args) throws Exception {
       filenames.add(args[i]);
     }
 
-    if ((doUpload || doVerify) && filenames.size() != 1)
+    if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1)
       showError(null, _("Must specify exactly one sketch file"), 3);
 
+    if ((action == ACTION.NOOP || action == ACTION.GET_PREF) && filenames.size() != 0)
+      showError(null, _("Cannot specify any sketch files"), 3);
+
+    if ((action != ACTION.UPLOAD && action != ACTION.VERIFY) && (doVerboseBuild || doVerboseUpload))
+      showError(null, _("--verbose, --verbose-upload and --verbose-build can only be used together with --verify or --upload"), 3);
+
     for (String path: filenames) {
+      // Correctly resolve relative paths
+      File file = absoluteFile(path);
+
       // Fix a problem with systems that use a non-ASCII languages. Paths are
       // being passed in with 8.3 syntax, which makes the sketch loader code
       // unhappy, since the sketch folder naming doesn't match up correctly.
       // http://dev.processing.org/bugs/show_bug.cgi?id=1089
       if (isWindows()) {
         try {
-          File file = new File(path);
-          path = file.getCanonicalPath();
+          file = file.getCanonicalFile();
         } catch (IOException e) {
           e.printStackTrace();
         }
       }
 
-      if (!new File(path).isAbsolute()) {
-        path = new File(currentDirectory, path).getAbsolutePath();
-      }
-
-      if (handleOpen(path, nextEditorLocation(), !(doUpload || doVerify)) == null) {
+      boolean showEditor = (action == ACTION.GUI);
+      if (handleOpen(file, nextEditorLocation(), showEditor) == null) {
         String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path);
         // Open failure is fatal in upload/verify mode
-        if (doUpload || doVerify)
+        if (action == ACTION.VERIFY || action == ACTION.UPLOAD)
           showError(null, mess, 2);
         else
           showWarning(null, mess, null);
       }
     }
 
-    if (doUpload || doVerify) {
-      // Set verbosity for command line build
-      Preferences.set("build.verbose", "" + doVerboseBuild);
-      Preferences.set("upload.verbose", "" + doVerboseUpload);
+    // Save the preferences. For GUI mode, this happens in the quit
+    // handler, but for other modes we should also make sure to save
+    // them.
+    Preferences.save();
 
-      Editor editor = editors.get(0);
+    switch (action) {
+      case VERIFY:
+      case UPLOAD:
+        // Set verbosity for command line build
+        Preferences.set("build.verbose", "" + doVerboseBuild);
+        Preferences.set("upload.verbose", "" + doVerboseUpload);
 
-      // Do board selection if requested
-      processBoardArgument(selectBoard);
-    
-      if (doUpload) {
-        // Build and upload
-        if (selectPort != null)
-          editor.selectSerialPort(selectPort);
-        editor.exportHandler.run();
-      } else {
-        // Build only
-        editor.runHandler.run();
-      }
+        // Make sure these verbosity preferences are only for the
+        // current session
+        Preferences.setDoSave(false);
 
-      // Error during build or upload
-      int res = editor.status.mode;
-      if (res == EditorStatus.ERR)
-        System.exit(1);
+        Editor editor = editors.get(0);
 
-      // No errors exit gracefully
-      System.exit(0);
-    }
+        if (action == ACTION.UPLOAD) {
+          // Build and upload
+          editor.exportHandler.run();
+        } else {
+          // Build only
+          editor.runHandler.run();
+        }
 
-    // Check if there were previously opened sketches to be restored
-    restoreSketches();
+        // Error during build or upload
+        int res = editor.status.mode;
+        if (res == EditorStatus.ERR)
+          System.exit(1);
 
-    // Create a new empty window (will be replaced with any files to be opened)
-    if (editors.isEmpty()) {
-      handleNew();
-    }
+        // No errors exit gracefully
+        System.exit(0);
+        break;
+      case GUI:
+        // Check if there were previously opened sketches to be restored
+        restoreSketches();
+
+        // Create a new empty window (will be replaced with any files to be opened)
+        if (editors.isEmpty()) {
+          handleNew();
+        }
 
-    // Check for updates
-    if (Preferences.getBoolean("update.check")) {
-      new UpdateCheck(this);
+        // Check for updates
+        if (Preferences.getBoolean("update.check")) {
+          new UpdateCheck(this);
+        }
+        break;
+      case NOOP:
+        // Do nothing (intended for only changing preferences)
+        System.exit(0);
+        break;
+      case GET_PREF:
+        String value = Preferences.get(getPref, null);
+        if (value != null) {
+          System.out.println(value);
+          System.exit(0);
+        } else {
+          System.exit(4);
+        }
+        break;
     }
   }
 
@@ -583,7 +666,7 @@ protected boolean restoreSketches() throws Exception {
         location = nextEditorLocation();
       }
       // If file did not exist, null will be returned for the Editor
-      if (handleOpen(path, location, true) != null) {
+      if (handleOpen(new File(path), location, true) != null) {
         opened++;
       }
     }
@@ -741,7 +824,7 @@ protected int[] nextEditorLocation() {
    * @param shift whether shift is pressed, which will invert prompt setting
    * @param noPrompt disable prompt, no matter the setting
    */
-  protected String createNewUntitled() throws IOException {
+  protected File createNewUntitled() throws IOException {
     File newbieDir = null;
     String newbieName = null;
 
@@ -788,7 +871,7 @@ protected String createNewUntitled() throws IOException {
       throw new IOException();
     }
     FileUtils.copyFile(new File(getContentFile("examples"), "01.Basics" + File.separator + "BareMinimum" + File.separator + "BareMinimum.ino"), newbieFile);
-    return newbieFile.getAbsolutePath();
+    return newbieFile;
   }
 
 
@@ -798,9 +881,9 @@ protected String createNewUntitled() throws IOException {
    */
   public void handleNew() throws Exception {
     try {
-      String path = createNewUntitled();
-      if (path != null) {
-        Editor editor = handleOpen(path);
+      File file = createNewUntitled();
+      if (file != null) {
+        Editor editor = handleOpen(file);
         editor.untitled = true;
       }
 
@@ -829,9 +912,9 @@ public void handleNewReplace() {
 
   protected void handleNewReplaceImpl() {
     try {
-      String path = createNewUntitled();
-      if (path != null) {
-        activeEditor.handleOpenInternal(path);
+      File file = createNewUntitled();
+      if (file != null) {
+        activeEditor.handleOpenInternal(file);
         activeEditor.untitled = true;
       }
 //      return true;
@@ -847,14 +930,14 @@ protected void handleNewReplaceImpl() {
    * Open a sketch, replacing the sketch in the current window.
    * @param path Location of the primary pde file for the sketch.
    */
-  public void handleOpenReplace(String path) {
+  public void handleOpenReplace(File file) {
     if (!activeEditor.checkModified()) {
       return;  // sketch was modified, and user canceled
     }
     // Close the running window, avoid window boogers with multiple sketches
     activeEditor.internalCloseRunner();
 
-    boolean loaded = activeEditor.handleOpenInternal(path);
+    boolean loaded = activeEditor.handleOpenInternal(file);
     if (!loaded) {
       // replace the document without checking if that's ok
       handleNewReplaceImpl();
@@ -885,30 +968,30 @@ public void handleOpenPrompt() throws Exception {
     File inputFile = fd.getSelectedFile();
 
     Preferences.set("last.folder", inputFile.getAbsolutePath());
-    handleOpen(inputFile.getAbsolutePath());
+    handleOpen(inputFile);
   }
 
 
   /**
    * Open a sketch in a new window.
-   * @param path Path to the pde file for the sketch in question
+   * @param file File to open
    * @return the Editor object, so that properties (like 'untitled')
    *         can be set by the caller
    * @throws Exception 
    */
-  public Editor handleOpen(String path) throws Exception {
-    return handleOpen(path, nextEditorLocation(), true);
+  public Editor handleOpen(File file) throws Exception {
+    return handleOpen(file, nextEditorLocation(), true);
   }
 
 
-  protected Editor handleOpen(String path, int[] location, boolean showEditor) throws Exception {
+  protected Editor handleOpen(File file, int[] location, boolean showEditor) throws Exception {
 //    System.err.println("entering handleOpen " + path);
 
-    File file = new File(path);
     if (!file.exists()) return null;
 
 //    System.err.println("  editors: " + editors);
     // Cycle through open windows to make sure that it's not already open.
+    String path = file.getAbsolutePath();
     for (Editor editor : editors) {
       if (editor.getSketch().getMainFilePath().equals(path)) {
         editor.toFront();
@@ -932,7 +1015,7 @@ protected Editor handleOpen(String path, int[] location, boolean showEditor) thr
 //    }
 
 //    System.err.println("  creating new editor");
-    Editor editor = new Editor(this, path, location);
+    Editor editor = new Editor(this, file, location);
 //    Editor editor = null;
 //    try {
 //      editor = new Editor(this, path, location);
@@ -1444,6 +1527,11 @@ private JRadioButtonMenuItem createBoardMenusAndCustomMenus(
     Action action = new AbstractAction(board.getName()) {
       public void actionPerformed(ActionEvent actionevent) {
         selectBoard((TargetBoard)getValue("b"));
+        filterVisibilityOfSubsequentBoardMenus((TargetBoard)getValue("b"), 1);
+
+        onBoardOrPortChange();
+        rebuildImportMenu(Editor.importMenu);
+        rebuildExamplesMenu(Editor.examplesMenu);
       }
     };
     action.putValue("b", board);
@@ -1580,14 +1668,15 @@ private void selectBoard(TargetBoard targetBoard) {
     File platformFolder = targetPlatform.getFolder();
     Preferences.set("runtime.platform.path", platformFolder.getAbsolutePath());
     Preferences.set("runtime.hardware.path", platformFolder.getParentFile().getAbsolutePath());
-    
-    filterVisibilityOfSubsequentBoardMenus(targetBoard, 1);
-
-    onBoardOrPortChange();
-    rebuildImportMenu(Editor.importMenu);
-    rebuildExamplesMenu(Editor.examplesMenu);
   }
 
+  public static void selectSerialPort(String port) {
+    Preferences.set("serial.port", port);
+    if (port.startsWith("/dev/"))
+      Preferences.set("serial.port.file", port.substring(5));
+    else
+      Preferences.set("serial.port.file", port);
+  }
 
   public void rebuildProgrammerMenu(JMenu menu) {
     menu.removeAll();
@@ -1669,16 +1758,17 @@ private boolean addSketchesSubmenu(JMenu menu, String name, File folder,
     ActionListener listener = new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         String path = e.getActionCommand();
-        if (new File(path).exists()) {
+        File file = new File(path);
+        if (file.exists()) {
           boolean replace = replaceExisting;
           if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0) {
             replace = !replace;
           }
           if (replace) {
-            handleOpenReplace(path);
+            handleOpenReplace(file);
           } else {
             try {
-              handleOpen(path);
+              handleOpen(file);
             } catch (Exception e1) {
               e1.printStackTrace();
             }
@@ -1959,7 +2049,7 @@ static public File getSettingsFolder() {
 
     String preferencesPath = Preferences.get("settings.path");
     if (preferencesPath != null) {
-      settingsFolder = new File(preferencesPath);
+      settingsFolder = absoluteFile(preferencesPath);
 
     } else {
       try {
@@ -1998,8 +2088,9 @@ static public File getBuildFolder() {
     if (buildFolder == null) {
       String buildPath = Preferences.get("build.path");
       if (buildPath != null) {
-        buildFolder = new File(buildPath);
-
+        buildFolder = Base.absoluteFile(buildPath);
+        if (!buildFolder.exists())
+          buildFolder.mkdirs();
       } else {
         //File folder = new File(getTempFolder(), "build");
         //if (!folder.exists()) folder.mkdirs();
@@ -2160,7 +2251,7 @@ static public String getPortableSketchbookFolder() {
   static public File getSketchbookFolder() {
     if (portableFolder != null)
       return new File(portableFolder, Preferences.get("sketchbook.path"));
-    return new File(Preferences.get("sketchbook.path"));
+    return absoluteFile(Preferences.get("sketchbook.path"));
   }
 
 
diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java
index 278b548409e..e8b3c170cc6 100644
--- a/app/src/processing/app/Editor.java
+++ b/app/src/processing/app/Editor.java
@@ -155,7 +155,7 @@ public class Editor extends JFrame implements RunnerListener {
   Runnable exportAppHandler;
 
 
-  public Editor(Base ibase, String path, int[] location) throws Exception {
+  public Editor(Base ibase, File file, int[] location) throws Exception {
     super("Arduino");
     this.base = ibase;
 
@@ -310,7 +310,7 @@ public void windowDeactivated(WindowEvent e) {
 //    System.out.println("t4");
 
     // Open the document that was passed in
-    boolean loaded = handleOpenInternal(path);
+    boolean loaded = handleOpenInternal(file);
     if (!loaded) sketch = null;
 
 //    System.out.println("t5");
@@ -965,11 +965,7 @@ protected void selectSerialPort(String name) {
     }
     if (selection != null) selection.setState(true);
     //System.out.println(item.getLabel());
-    Preferences.set("serial.port", name);
-    if (name.startsWith("/dev/"))
-      Preferences.set("serial.port.file", name.substring(5));
-    else
-      Preferences.set("serial.port.file", name);
+    Base.selectSerialPort(name);
     if (serialMonitor != null) {
       try {
         serialMonitor.close();
@@ -2096,10 +2092,10 @@ protected boolean checkModified() {
    * Open a sketch from a particular path, but don't check to save changes.
    * Used by Sketch.saveAs() to re-open a sketch after the "Save As"
    */
-  protected void handleOpenUnchecked(String path, int codeIndex,
+  protected void handleOpenUnchecked(File file, int codeIndex,
                                      int selStart, int selStop, int scrollPos) {
     internalCloseRunner();
-    handleOpenInternal(path);
+    handleOpenInternal(file);
     // Replacing a document that may be untitled. If this is an actual
     // untitled document, then editor.untitled will be set by Base.
     untitled = false;
@@ -2114,27 +2110,26 @@ protected void handleOpenUnchecked(String path, int codeIndex,
    * Second stage of open, occurs after having checked to see if the
    * modifications (if any) to the previous sketch need to be saved.
    */
-  protected boolean handleOpenInternal(String path) {
+  protected boolean handleOpenInternal(File file) {
     // check to make sure that this .pde file is
     // in a folder of the same name
-    File file = new File(path);
     String fileName = file.getName();
     File parent = file.getParentFile();
     String parentName = parent.getName();
     String pdeName = parentName + ".pde";
     File altPdeFile = new File(parent, pdeName);
     String inoName = parentName + ".ino";
-    File altInoFile = new File(parent, pdeName);
+    File altInoFile = new File(parent, inoName);
 
     if (pdeName.equals(fileName) || inoName.equals(fileName)) {
       // no beef with this guy
 
     } else if (altPdeFile.exists()) {
       // user selected a .java from the same sketch, but open the .pde instead
-      path = altPdeFile.getAbsolutePath();
+      file = altPdeFile;
     } else if (altInoFile.exists()) {
-      path = altInoFile.getAbsolutePath();
-    } else if (!path.endsWith(".ino") && !path.endsWith(".pde")) {
+      file = altInoFile;
+    } else if (!fileName.endsWith(".ino") && !fileName.endsWith(".pde")) {
       Base.showWarning(_("Bad file selected"),
                        _("Processing can only open its own sketches\n" +
                          "and other files ending in .ino or .pde"), null);
@@ -2183,19 +2178,18 @@ protected boolean handleOpenInternal(String path) {
         }
         // copy the sketch inside
         File properPdeFile = new File(properFolder, file.getName());
-        File origPdeFile = new File(path);
         try {
-          Base.copyFile(origPdeFile, properPdeFile);
+          Base.copyFile(file, properPdeFile);
         } catch (IOException e) {
           Base.showWarning(_("Error"), _("Could not copy to a proper location."), e);
           return false;
         }
 
         // remove the original file, so user doesn't get confused
-        origPdeFile.delete();
+        file.delete();
 
         // update with the new path
-        path = properPdeFile.getAbsolutePath();
+        file = properPdeFile;
 
       } else if (result == JOptionPane.NO_OPTION) {
         return false;
@@ -2203,7 +2197,7 @@ protected boolean handleOpenInternal(String path) {
     }
 
     try {
-      sketch = new Sketch(this, path);
+      sketch = new Sketch(this, file);
     } catch (IOException e) {
       Base.showWarning(_("Error"), _("Could not create the sketch."), e);
       return false;
@@ -2643,6 +2637,7 @@ public void handlePrint() {
    * Show an error int the status bar.
    */
   public void statusError(String what) {
+    System.err.println(what);
     status.error(what);
     //new Exception("deactivating RUN").printStackTrace();
     toolbar.deactivate(EditorToolbar.RUN);
diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java
index 73b980ef52b..dc2b04b99fa 100644
--- a/app/src/processing/app/Preferences.java
+++ b/app/src/processing/app/Preferences.java
@@ -220,9 +220,14 @@ public String toString() {
   static Hashtable<String, String> defaults;
   static Hashtable<String, String> table = new Hashtable<String, String>();
   static File preferencesFile;
+  static boolean doSave = true;
 
 
-  static protected void init(String args[]) {
+  static protected void init(File file) {
+    if (file != null)
+      preferencesFile = file;
+    else
+      preferencesFile = Base.getSettingsFile(Preferences.PREFS_FILE);
 
     // start by loading the defaults, in case something
     // important was deleted from the user prefs
@@ -254,22 +259,7 @@ static protected void init(String args[]) {
     // clone the hash table
     defaults = new Hashtable<String, String>(table);
 
-    // next load user preferences file
-    preferencesFile = Base.getSettingsFile(PREFS_FILE);
-
-    // load a preferences file if specified on the command line
-    if (args != null) {
-      for (int i = 0; i < args.length - 1; i++) {
-        if (args[i].equals("--preferences-file"))
-          preferencesFile = new File(args[i + 1]);
-      }
-    }
-
-    if (!preferencesFile.exists()) {
-      // create a new preferences file if none exists
-      // saves the defaults out to the file
-      save();
-    } else {
+    if (preferencesFile.exists()) {
       // load the previous preferences file
       try {
         load(new FileInputStream(preferencesFile));
@@ -502,7 +492,7 @@ public void actionPerformed(ActionEvent e) {
     final JLabel clickable = label;
     label.addMouseListener(new MouseAdapter() {
         public void mousePressed(MouseEvent e) {
-          Base.openFolder(Base.getSettingsFolder());
+          Base.openFolder(preferencesFile.getParentFile());
         }
 
         public void mouseEntered(MouseEvent e) {
@@ -789,6 +779,7 @@ static public String[] loadStrings(InputStream input) {
 
 
   static protected void save() {
+    if (!doSave) return;
 //    try {
     // on startup, don't worry about it
     // this is trying to update the prefs for who is open
@@ -989,4 +980,10 @@ static public PreferencesMap getMap()
     return new PreferencesMap(table);
   }
 
+  // Decide wether changed preferences will be saved. When value is
+  // false, Preferences.save becomes a no-op.
+  static public void setDoSave(boolean value)
+  {
+    doSave = value;
+  }
 }
diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java
index 9d7bbbbc2b1..253af52382d 100644
--- a/app/src/processing/app/Sketch.java
+++ b/app/src/processing/app/Sketch.java
@@ -106,10 +106,10 @@ public class Sketch {
    * path is location of the main .pde file, because this is also
    * simplest to use when opening the file from the finder/explorer.
    */
-  public Sketch(Editor editor, String path) throws IOException {
+  public Sketch(Editor editor, File file) throws IOException {
     this.editor = editor;
 
-    primaryFile = new File(path);
+    primaryFile = file;
 
     // get the name of the sketch by chopping .pde or .java
     // off of the main file name
@@ -136,7 +136,7 @@ public Sketch(Editor editor, String path) throws IOException {
     tempBuildFolder = Base.getBuildFolder();
     //Base.addBuildFolderToClassPath();
 
-    folder = new File(new File(path).getParent());
+    folder = new File(file.getParent());
     //System.out.println("sketch dir is " + folder);
 
     load();
@@ -516,12 +516,11 @@ protected void nameCode(String newName) {
         // if successful, set base properties for the sketch
 
         File newMainFile = new File(newFolder, newName + ".ino");
-        String newMainFilePath = newMainFile.getAbsolutePath();
 
         // having saved everything and renamed the folder and the main .pde,
         // use the editor to re-open the sketch to re-init state
         // (unfortunately this will kill positions for carets etc)
-        editor.handleOpenUnchecked(newMainFilePath,
+        editor.handleOpenUnchecked(newMainFile,
                                    currentIndex,
                                    editor.getSelectionStart(),
                                    editor.getSelectionStop(),
@@ -915,7 +914,7 @@ protected boolean saveAs() throws IOException {
     File newFile = new File(newFolder, newName + ".ino");
     code[0].saveAs(newFile);
 
-    editor.handleOpenUnchecked(newFile.getPath(),
+    editor.handleOpenUnchecked(newFile,
                                currentIndex,
                                editor.getSelectionStart(),
                                editor.getSelectionStop(),
diff --git a/app/src/processing/app/macosx/ThinkDifferent.java b/app/src/processing/app/macosx/ThinkDifferent.java
index 6448b1e9aab..0f226dd716a 100644
--- a/app/src/processing/app/macosx/ThinkDifferent.java
+++ b/app/src/processing/app/macosx/ThinkDifferent.java
@@ -26,6 +26,8 @@
 
 import com.apple.eawt.*;
 
+import java.io.File;
+
 
 /**
  * Deal with issues related to thinking different. This handles the basic
@@ -97,7 +99,7 @@ public void handleOpenFile(ApplicationEvent ae) {
 //    System.out.println("got open file event " + ae.getFilename());
     String filename = ae.getFilename();
     try {
-      base.handleOpen(filename);
+      base.handleOpen(new File(filename));
     } catch (Exception e) {
       e.printStackTrace();
     }
diff --git a/build/shared/manpage.adoc b/build/shared/manpage.adoc
index 30f5072cdce..7af5a8c7ccf 100644
--- a/build/shared/manpage.adoc
+++ b/build/shared/manpage.adoc
@@ -75,6 +75,9 @@ OPTIONS
 {empty}::
 	If this option is not passed, the value from the current
 	preferences is used (e.g., the last board selected in the IDE).
+	If this option is given, the value passed is written to the
+	preferences file and rememberd for subsequent runs (except when
+	*--no-save-prefs* is passed).
 
 *--port* __portname__::
 	Select the serial port to perform upload of the sketch.
@@ -85,21 +88,36 @@ OPTIONS
 {empty}::
 	If this option is not passed, the value from the current
 	preferences is used (e.g., the last port selected in the IDE).
+	If this option is given, the value passed is written to the
+	preferences file and rememberd for subsequent runs (except when
+	*--no-save-prefs* is passed).
 
 *--verbose-build*::
-    Enable verbose mode during build. If this option is not given,
-    verbose mode during build is disabled regardless of the current
-    preferences.
+	Enable verbose mode during build. If this option is not given,
+	verbose mode during build is disabled regardless of the current
+	preferences.
+
+{empty}::
+	This option is only valid together with *--verify* or
+	*--upload*.
 
 *--verbose-upload*::
-    Enable verbose mode during upload. If this option is not given,
-    verbose mode during upload is disabled regardless of the current
-    preferences.
+	Enable verbose mode during upload. If this option is not given,
+	verbose mode during upload is disabled regardless of the current
+	preferences.
+
+{empty}::
+	This option is only valid together with *--verify* or
+	*--upload*.
 
 *-v, --verbose*::
 	Enable verbose mode during build and upload.
-    This option has the same effect of using both *--verbose-build*
-    and *--verbose-upload*.
+	This option has the same effect of using both *--verbose-build*
+	and *--verbose-upload*.
+
+{empty}::
+	This option is only valid together with *--verify* or
+	*--upload*.
 
 *--preferences-file* __filename__::
 	Read and store preferences from the specified __filename__ instead
@@ -108,22 +126,34 @@ OPTIONS
 *--pref* __name__=__value__::
 	Sets the preference __name__ to the given __value__.
 
-{empty}::
-	Currently the preferences set are saved to 'preferences.txt', but
-	this might change in the future (making them only active during
-	the current invocation).
-
 {empty}::
 	Note that the preferences you set with this option are not
 	validated: Invalid names will be set but never used, invalid
 	values might lead to an error later on.
 
+{empty}::
+	If this option is given, the value passed is written to the
+	preferences file and rememberd for subsequent runs (except when
+	*--no-save-prefs* is passed).
+
+*--no-save-prefs*::
+	Do not save any (changed) preferences to *preferences.txt*.
+
 *--upload*::
 	Build and upload the sketch.
 
 *--verify*::
 	Build the sketch.
 
+*--noop*::
+	Immediately quit after processing the commandline. This can be
+	used to just set preferences with *--pref*.
+
+*--get-pref __preference__*::
+	Prints the value of the given preference to the standard output
+	stream. When the value does not exist, nothing is printed and
+	the exit status is set (see EXIT STATUS below).
+
 PREFERENCES
 -----------
 Arduino keeps a list of preferences, as simple name and value pairs.
@@ -160,6 +190,7 @@ EXIT STATUS
 *1*:: Build failed or upload failed
 *2*:: Sketch not found
 *3*:: Invalid (argument for) commandline option
+*4*:: Preference passed to *--get-pref* does not exist
 
 FILES
 -----
@@ -211,6 +242,51 @@ re-use any previous build results in that directory.
 
      arduino --pref build.path=/path/to/sketch/build --verify /path/to/sketch/sketch.ino
 
+Change the selected board and build path and do nothing else.
+
+     arduino --pref build.path=/path/to/sketch/build --board arduino:avr:uno --noop
+
+HISTORY
+-------
+1.5.2::
+	Added initial commandline support. This introduced *--verify*,
+	*--upload*, *--board*, *--port*, *--verbose* and *-v*.
+
+1.5.5::
+	Added support for board-specific parameters to *--board*.
+
+{empty}::
+	Sketch filenames are now interpreted relative to the current
+	directory instead of the location of the arduino command itself.
+
+1.5.6::
+	Introduced *--pref*, *--preferences-file*, *--verbose-build* and
+	*--verbose-upload*.
+
+{empty}::
+	Preferences set through --pref are remembered, preferences set
+	through *--board*, *--port* or the *--verbose* options are not.
+
+{empty}::
+	When running with *--verify* or *--upload*, the full GUI is no
+	longer shown. Error messages still use a graphical popup and on
+	Windows, the splash screen is still shown.
+
+1.5.7::
+	Introduced *--no-save-prefs* and *--noop*.
+
+{empty}::
+	*--board* and *--port* options are now saved to the preferences
+	file, just like *--pref*. The *--verbose* options still only
+	apply to the current run.
+
+{empty}::
+	A path passed to *--preferences-file*, or set in the
+	*build.path*, *preferences.path* or *settings.path* is now
+	interpreted relative to the current directory instead of the
+	location of the arduino command itself.
+
+
 RESOURCES
 ---------
 Web site: <http://arduino.cc/>