Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 998)
+++ src/org/openstreetmap/josm/Main.java	(working copy)
@@ -9,6 +9,7 @@
 import java.awt.Toolkit;
 import java.awt.event.KeyEvent;
 import java.io.File;
+import java.lang.reflect.*;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -59,7 +60,7 @@
 import org.openstreetmap.josm.plugins.PluginProxy;
 import org.openstreetmap.josm.tools.ImageProvider;
 
-abstract public class Main {
+abstract public class Main implements InvocationHandler {
 	/**
 	 * Global parent component for all dialogs and message boxes
 	 */
@@ -180,6 +181,7 @@
 
 	public Main() {
 		main = this;
+		setupOSX();
 		contentPane.add(panel, BorderLayout.CENTER);
 		panel.add(new GettingStarted(), BorderLayout.CENTER);
 		menu = new MainMenu();
@@ -470,4 +472,46 @@
 
 		main.menu.open.openFile(new File(s));
 	}
+
+	public static boolean withOSXIntegration = false;
+
+	public void setupOSX() {
+		if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) {
+			try {
+				Class Ccom_apple_eawt_Application = Class.forName("com.apple.eawt.Application");
+				Object Ocom_apple_eawt_Application = Ccom_apple_eawt_Application.getConstructor((Class[])null).newInstance((Object[])null);
+				Class Ccom_apple_eawt_ApplicationListener = Class.forName("com.apple.eawt.ApplicationListener");
+				Method MaddApplicationListener = Ccom_apple_eawt_Application.getDeclaredMethod("addApplicationListener", new Class[] { Ccom_apple_eawt_ApplicationListener });
+				Object Oproxy = Proxy.newProxyInstance(Main.class.getClassLoader(), new Class[] { Ccom_apple_eawt_ApplicationListener }, this);
+				MaddApplicationListener.invoke(Ocom_apple_eawt_Application, new Object[] { Oproxy });
+				Method MsetEnabledPreferencesMenu = Ccom_apple_eawt_Application.getDeclaredMethod("setEnabledPreferencesMenu", new Class[] { boolean.class });
+				MsetEnabledPreferencesMenu.invoke(Ocom_apple_eawt_Application, new Object[] { Boolean.TRUE });
+				withOSXIntegration = true;
+			} catch (Exception ex) {
+				System.out.println("Failed to report register with OSX: " + ex);
 }
+		}
+	}
+
+	public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
+		Boolean handled = Boolean.TRUE;
+		//System.out.println("Going to handle method "+method+" (short: "+method.getName()+") with event "+args[0]);
+		if (method.getName().equals("handleQuit")) {
+			handled = !breakBecauseUnsavedChanges();
+		} else if (method.getName().equals("handleAbout")) {
+			menu.about.actionPerformed(null);
+		} else if (method.getName().equals("handlePreferences")) {
+			menu.preferences.actionPerformed(null);
+		} else {
+			return null;
+		}
+		if (args[0] != null) {
+			try {
+				args[0].getClass().getDeclaredMethod("setHandled", new Class[] { boolean.class }).invoke(args[0], new Object[] { handled });
+			} catch (Exception ex) {
+				System.out.println("Failed to report handled event: " + ex);
+			}
+		}
+		return null;
+	}
+}
