Index: build/macosx/universal/mozconfig
===================================================================
RCS file: /cvsroot/mozilla/build/macosx/universal/mozconfig,v
retrieving revision 1.2.2.2
diff -u -6 -p -r1.2.2.2 mozconfig
--- build/macosx/universal/mozconfig	22 Feb 2006 17:32:37 -0000	1.2.2.2
+++ build/macosx/universal/mozconfig	22 Mar 2007 18:30:17 -0000
@@ -44,13 +44,13 @@ mk_add_options MOZ_POSTFLIGHT_ALL+=build
 
 DARWIN_VERSION=`uname -r`
 ac_add_app_options ppc  --target=powerpc-apple-darwin$DARWIN_VERSION
 ac_add_app_options i386 --target=i386-apple-darwin$DARWIN_VERSION
 
 # ppc builds run on older systems.  The minimum SDK for x86 is 10.4u.
-ac_add_app_options ppc  --with-macos-sdk=/Developer/SDKs/MacOSX10.2.8.sdk
+ac_add_app_options ppc  --with-macos-sdk=/Developer/SDKs/MacOSX10.3.9.sdk
 ac_add_app_options i386 --with-macos-sdk=/Developer/SDKs/MacOSX10.4u.sdk
 
 # $MOZ_BUILD_APP is only defined when sourced by configure.  That's not a
 # problem, because the variables it affects only need to be set for
 # configure.
 if test -n "$MOZ_BUILD_APP" ; then
Index: extensions/java/xpcom/nsJavaInterfaces.cpp
===================================================================
RCS file: /cvsroot/mozilla/extensions/java/xpcom/Attic/nsJavaInterfaces.cpp,v
retrieving revision 1.26.2.5
diff -u -6 -p -r1.26.2.5 nsJavaInterfaces.cpp
--- extensions/java/xpcom/nsJavaInterfaces.cpp	18 Jan 2007 19:36:12 -0000	1.26.2.5
+++ extensions/java/xpcom/nsJavaInterfaces.cpp	22 Mar 2007 18:30:24 -0000
@@ -427,6 +427,70 @@ MOZILLA_NATIVE(getNativeHandleFromAWT) (
 #else
   NS_WARNING("getNativeHandleFromAWT JNI method not implemented");
 #endif
 
   return handle;
 }
+
+extern "C" NS_EXPORT jlong JNICALL
+JXUTILS_NATIVE(wrapJavaObject) (JNIEnv* env, jobject, jobject aJavaObject,
+                                jstring aIID)
+{
+  nsresult rv;
+  nsISupports* xpcomObject = nsnull;
+
+  if (!aJavaObject || !aIID) {
+    rv = NS_ERROR_NULL_POINTER;
+  } else {
+    const char* str = env->GetStringUTFChars(aIID, nsnull);
+    if (!str) {
+      rv = NS_ERROR_OUT_OF_MEMORY;
+    } else {
+      nsID iid;
+      if (iid.Parse(str)) {
+        rv = GetNewOrUsedXPCOMObject(env, aJavaObject, iid, &xpcomObject);
+      } else {
+        rv = NS_ERROR_INVALID_ARG;
+      }
+
+      env->ReleaseStringUTFChars(aIID, str);
+    }
+  }
+
+  if (NS_FAILED(rv)) {
+    ThrowException(env, rv, "Failed to create XPCOM proxy for Java object");
+  }
+  return NS_REINTERPRET_CAST(jlong, xpcomObject);
+}
+
+extern "C" NS_EXPORT jobject JNICALL
+JXUTILS_NATIVE(wrapXPCOMObject) (JNIEnv* env, jobject, jlong aXPCOMObject,
+                                 jstring aIID)
+{
+  nsresult rv;
+  jobject javaObject = nsnull;
+  nsISupports* xpcomObject = NS_REINTERPRET_CAST(nsISupports*, aXPCOMObject);
+
+  if (!xpcomObject || !aIID) {
+    rv = NS_ERROR_NULL_POINTER;
+  } else {
+    const char* str = env->GetStringUTFChars(aIID, nsnull);
+    if (!str) {
+      rv = NS_ERROR_OUT_OF_MEMORY;
+    } else {
+      nsID iid;
+      if (iid.Parse(str)) {
+        // XXX Should we be passing something other than NULL for aObjectLoader?
+        rv = GetNewOrUsedJavaObject(env, xpcomObject, iid, nsnull, &javaObject);
+      } else {
+        rv = NS_ERROR_INVALID_ARG;
+      }
+
+      env->ReleaseStringUTFChars(aIID, str);
+    }
+  }
+
+  if (NS_FAILED(rv)) {
+    ThrowException(env, rv, "Failed to create XPCOM proxy for Java object");
+  }
+  return javaObject;
+}
Index: extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp
===================================================================
RCS file: /cvsroot/mozilla/extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp,v
retrieving revision 1.3.4.8
diff -u -6 -p -r1.3.4.8 nsJavaXPCOMGlue.cpp
--- extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp	1 Feb 2007 22:31:07 -0000	1.3.4.8
+++ extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp	22 Mar 2007 18:30:24 -0000
@@ -81,16 +81,18 @@ enum {
   kFunc_GetServiceManager,
   kFunc_NewLocalFile,
   kFunc_CallXPCOMMethod,
   kFunc_FinalizeProxy,
   kFunc_IsSameXPCOMObject,
   kFunc_ReleaseProfileLock,
-  kFunc_GetNativeHandleFromAWT
+  kFunc_GetNativeHandleFromAWT,
+  kFunc_WrapJavaObject,
+  kFunc_WrapXPCOMObject
 };
 
-#define JX_NUM_FUNCS 16
+#define JX_NUM_FUNCS 18
 
 
 // Get path string from java.io.File object.
 jstring
 GetJavaFilePath(JNIEnv* env, jobject aFile)
 {
@@ -163,12 +165,16 @@ LoadXULMethods(JNIEnv* env, jobject aXPC
     { "_Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_isSameXPCOMObject@16",
             (NSFuncPtr*) &aFunctions[kFunc_IsSameXPCOMObject] },
     { "_Java_org_mozilla_xpcom_ProfileLock_release@16",
             (NSFuncPtr*) &aFunctions[kFunc_ReleaseProfileLock] },
     { "_Java_org_mozilla_xpcom_internal_MozillaImpl_getNativeHandleFromAWT@12",
             (NSFuncPtr*) &aFunctions[kFunc_GetNativeHandleFromAWT] },
+    { "_Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapJavaObject@16",
+            (NSFuncPtr*) &aFunctions[kFunc_WrapJavaObject] },
+    { "_Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapXPCOMObject@16",
+            (NSFuncPtr*) &aFunctions[kFunc_WrapXPCOMObject] },
     { nsnull, nsnull }
   };
 #else
   nsDynamicFunctionLoad funcs[] = {
     { "Java_org_mozilla_xpcom_internal_MozillaImpl_initialize",
             (NSFuncPtr*) &aFunctions[kFunc_Initialize] },
@@ -199,12 +205,16 @@ LoadXULMethods(JNIEnv* env, jobject aXPC
     { "Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_isSameXPCOMObject",
             (NSFuncPtr*) &aFunctions[kFunc_IsSameXPCOMObject] },
     { "Java_org_mozilla_xpcom_ProfileLock_release",
             (NSFuncPtr*) &aFunctions[kFunc_ReleaseProfileLock] },
     { "Java_org_mozilla_xpcom_internal_MozillaImpl_getNativeHandleFromAWT",
             (NSFuncPtr*) &aFunctions[kFunc_GetNativeHandleFromAWT] },
+    { "Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapJavaObject",
+            (NSFuncPtr*) &aFunctions[kFunc_WrapJavaObject] },
+    { "Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapXPCOMObject",
+            (NSFuncPtr*) &aFunctions[kFunc_WrapXPCOMObject] },
     { nsnull, nsnull }
   };
 #endif
 
   rv = XPCOMGlueLoadXULFunctions(funcs);
   if (NS_FAILED(rv))
@@ -300,17 +310,24 @@ RegisterNativeMethods(JNIEnv* env, void*
     { "finalizeProxyNative", "(Ljava/lang/Object;)V",
       (void*) aFunctions[kFunc_FinalizeProxy] },
     { "isSameXPCOMObject", "(Ljava/lang/Object;Ljava/lang/Object;)Z",
       (void*) aFunctions[kFunc_IsSameXPCOMObject] }
   };
 
-   JNINativeMethod lockProxy_methods[] = {
+  JNINativeMethod lockProxy_methods[] = {
     { "releaseNative", "(J)V",
       (void*) aFunctions[kFunc_ReleaseProfileLock] }
   };
 
+  JNINativeMethod util_methods[] = {
+    { "wrapJavaObject", "(Ljava/lang/Object;Ljava/lang/String;)J",
+      (void*) aFunctions[kFunc_WrapJavaObject] },
+    { "wrapXPCOMObject", "(JLjava/lang/String;)Ljava/lang/Object;",
+      (void*) aFunctions[kFunc_WrapXPCOMObject] }
+  };
+
   jint rc = -1;
   jclass clazz = env->FindClass("org/mozilla/xpcom/internal/MozillaImpl");
   if (clazz) {
     rc = env->RegisterNatives(clazz, mozilla_methods,
                           sizeof(mozilla_methods) / sizeof(mozilla_methods[0]));
   }
@@ -345,12 +362,20 @@ RegisterNativeMethods(JNIEnv* env, void*
   if (clazz) {
     rc = env->RegisterNatives(clazz, lockProxy_methods,
                       sizeof(lockProxy_methods) / sizeof(lockProxy_methods[0]));
   }
   NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE);
 
+  rc = -1;
+  clazz = env->FindClass("org/mozilla/xpcom/internal/JavaXPCOMMethods");
+  if (clazz) {
+    rc = env->RegisterNatives(clazz, util_methods,
+                              sizeof(util_methods) / sizeof(util_methods[0]));
+  }
+  NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE);
+
   return NS_OK;
 }
 
 // Load the JavaXPCOM methods from the XUL shared library, and registers them
 // as Java native methods.
 extern "C" JX_EXPORT void JNICALL
Index: extensions/java/xpcom/interfaces/IJavaXPCOMUtils.java
===================================================================
RCS file: extensions/java/xpcom/interfaces/IJavaXPCOMUtils.java
diff -N extensions/java/xpcom/interfaces/IJavaXPCOMUtils.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ extensions/java/xpcom/interfaces/IJavaXPCOMUtils.java	6 Feb 2007 22:21:11 -0000
@@ -0,0 +1,59 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Java XPCOM Bindings.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Javier Pedemonte (jhpedemonte@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.xpcom;
+
+public interface IJavaXPCOMUtils {
+
+	/**
+	 * Returns a pointer to a C++ proxy object for the given Java object.
+	 * 
+	 * @param aJavaObject   Java object to encapsulate in C++ proxy
+	 * @param aIID          interface ID for requested proxy
+	 * @return  C pointer (as long) of new proxy
+	 */
+	long wrapJavaObject(Object aJavaObject, String aIID);
+
+	/**
+	 * Returns a Java proxy for the given C++ XPCOM object
+	 * 
+	 * @param aXPCOMObject  C++ XPCOM object to encapsulate in Java proxy
+	 * @param aIID          interface ID for requested proxy
+	 * @return  new Proxy
+	 */
+	Object wrapXPCOMObject(long aXPCOMObject, String aIID);
+
+}
Index: extensions/java/xpcom/interfaces/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/extensions/java/xpcom/interfaces/Makefile.in,v
retrieving revision 1.5.4.11
diff -u -6 -p -r1.5.4.11 Makefile.in
--- extensions/java/xpcom/interfaces/Makefile.in	18 Oct 2006 20:37:46 -0000	1.5.4.11
+++ extensions/java/xpcom/interfaces/Makefile.in	22 Mar 2007 18:30:24 -0000
@@ -47,12 +47,13 @@ JARFILE_SRC = $(patsubst %.jar,%-src.jar
 JAVA_SRCS = \
 		$(srcdir)/Mozilla.java \
 		$(srcdir)/GREVersionRange.java \
 		$(srcdir)/IMozilla.java \
 		$(srcdir)/IGRE.java \
 		$(srcdir)/IXPCOM.java \
+		$(srcdir)/IJavaXPCOMUtils.java \
 		$(srcdir)/IAppFileLocProvider.java \
 		$(srcdir)/INIParser.java \
 		$(srcdir)/VersionComparator.java \
 		$(srcdir)/ProfileLock.java \
 		$(srcdir)/../XPCOMException.java \
 		$(srcdir)/XPCOMInitializationException.java \
Index: extensions/java/xpcom/interfaces/Mozilla.java
===================================================================
RCS file: /cvsroot/mozilla/extensions/java/xpcom/interfaces/Attic/Mozilla.java,v
retrieving revision 1.3.4.7
diff -u -6 -p -r1.3.4.7 Mozilla.java
--- extensions/java/xpcom/interfaces/Mozilla.java	1 Feb 2007 22:31:08 -0000	1.3.4.7
+++ extensions/java/xpcom/interfaces/Mozilla.java	22 Mar 2007 18:30:24 -0000
@@ -82,23 +82,23 @@ import org.mozilla.interfaces.nsISupport
  *    // handle exception
  * }
  * </pre>
  * 
  * @see http://www.mozilla.org/projects/embedding/GRE.html
  */
-public class Mozilla implements IMozilla, IGRE, IXPCOM, IXPCOMError {
+public class Mozilla implements IMozilla, IGRE, IXPCOM, IJavaXPCOMUtils,
+IXPCOMError {
 
   private static Mozilla mozillaInstance = new Mozilla();
 
   private static final String JAVAXPCOM_JAR = "javaxpcom.jar";
 
   private IMozilla mozilla = null;
-
   private IGRE gre = null;
-
   private IXPCOM xpcom = null;
+  private IJavaXPCOMUtils jxutils = null;
 
   /**
    * @return
    */
   public static Mozilla getInstance() {
     return mozillaInstance;
@@ -652,12 +652,17 @@ public class Mozilla implements IMozilla
           true, loader);
       gre = (IGRE) greClass.newInstance();
 
       Class xpcomClass = Class.forName("org.mozilla.xpcom.internal.XPCOMImpl",
                                        true, loader);
       xpcom = (IXPCOM) xpcomClass.newInstance();
+
+      Class javaXPCOMClass =
+    	  Class.forName("org.mozilla.xpcom.internal.JavaXPCOMMethods",
+    			  true, loader);
+      jxutils  = (IJavaXPCOMUtils) javaXPCOMClass.newInstance();
     } catch (Exception e) {
       throw new XPCOMInitializationException("Could not load " +
           "org.mozilla.xpcom.internal.* classes", e);
     }
     
     mozilla.initialize(aLibXULDirectory);
@@ -1038,7 +1043,25 @@ public class Mozilla implements IMozilla
     } catch (NullPointerException e) {
       throw new XPCOMInitializationException("Must call " +
           "Mozilla.getInstance().initialize() before using this method", e);
     }
   }
 
+	public long wrapJavaObject(Object aJavaObject, String aIID) {
+		try {
+			return jxutils.wrapJavaObject(aJavaObject, aIID);
+		} catch (NullPointerException e) {
+			throw new XPCOMInitializationException("Must call " +
+				"Mozilla.getInstance().initialize() before using this method", e);
+		}
+	}
+	
+	public Object wrapXPCOMObject(long aXPCOMObject, String aIID) {
+		try {
+			return jxutils.wrapXPCOMObject(aXPCOMObject, aIID);
+		} catch (NullPointerException e) {
+			throw new XPCOMInitializationException("Must call " +
+				"Mozilla.getInstance().initialize() before using this method", e);
+		}
+	}
+
 }
Index: extensions/java/xpcom/src/JavaXPCOMMethods.java
===================================================================
RCS file: /cvsroot/mozilla/extensions/java/xpcom/src/Attic/JavaXPCOMMethods.java,v
retrieving revision 1.1.2.4
diff -u -6 -p -r1.1.2.4 JavaXPCOMMethods.java
--- extensions/java/xpcom/src/JavaXPCOMMethods.java	3 Oct 2006 20:02:15 -0000	1.1.2.4
+++ extensions/java/xpcom/src/JavaXPCOMMethods.java	22 Mar 2007 18:30:24 -0000
@@ -35,14 +35,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 package org.mozilla.xpcom.internal;
 
 import java.io.File;
 
+import org.mozilla.xpcom.IJavaXPCOMUtils;
 
-public class JavaXPCOMMethods {
+
+public class JavaXPCOMMethods implements IJavaXPCOMUtils {
 
   public static void registerJavaXPCOMMethods(File aLibXULDirectory) {
     // load JNI library
     String path = "";
     if (aLibXULDirectory != null) {
       path = aLibXULDirectory + File.separator;
@@ -82,8 +84,12 @@ public class JavaXPCOMMethods {
       }
     } catch (ClassNotFoundException e) {
       return null;
     }
   }
 
+  public native long wrapJavaObject(Object aJavaObject, String aIID);
+
+  public native Object wrapXPCOMObject(long aXPCOMObject, String aIID);
+
 }
 
Index: extensions/java/xpcom/src/dlldeps-javaxpcom.cpp
===================================================================
RCS file: /cvsroot/mozilla/extensions/java/xpcom/src/dlldeps-javaxpcom.cpp,v
retrieving revision 1.2.4.4
diff -u -6 -p -r1.2.4.4 dlldeps-javaxpcom.cpp
--- extensions/java/xpcom/src/dlldeps-javaxpcom.cpp	18 Jan 2007 19:36:13 -0000	1.2.4.4
+++ extensions/java/xpcom/src/dlldeps-javaxpcom.cpp	22 Mar 2007 18:30:24 -0000
@@ -67,8 +67,12 @@ void XXXNeverCalled_javaxpcom()
 
   JAVAPROXY_NATIVE(isSameXPCOMObject) (nsnull, nsnull, nsnull, nsnull);
 
   LOCKPROXY_NATIVE(release) (nsnull, nsnull, nsnull);
 
   MOZILLA_NATIVE(getNativeHandleFromAWT) (nsnull, nsnull, nsnull);
+
+  JXUTILS_NATIVE(wrapJavaObject) (nsnull, nsnull, nsnull, nsnull);
+
+  JXUTILS_NATIVE(wrapXPCOMObject) (nsnull, nsnull, nsnull, nsnull);
 }
 
Index: extensions/java/xpcom/src/nsJavaInterfaces.h
===================================================================
RCS file: /cvsroot/mozilla/extensions/java/xpcom/src/nsJavaInterfaces.h,v
retrieving revision 1.2.4.4
diff -u -6 -p -r1.2.4.4 nsJavaInterfaces.h
--- extensions/java/xpcom/src/nsJavaInterfaces.h	18 Jan 2007 19:36:13 -0000	1.2.4.4
+++ extensions/java/xpcom/src/nsJavaInterfaces.h	22 Mar 2007 18:30:24 -0000
@@ -43,12 +43,14 @@
 #define MOZILLA_NATIVE(func) Java_org_mozilla_xpcom_internal_MozillaImpl_##func
 #define GRE_NATIVE(func) Java_org_mozilla_xpcom_internal_GREImpl_##func
 #define XPCOM_NATIVE(func) Java_org_mozilla_xpcom_internal_XPCOMImpl_##func
 #define JAVAPROXY_NATIVE(func) \
           Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_##func
 #define LOCKPROXY_NATIVE(func) Java_org_mozilla_xpcom_ProfileLock_##func
+#define JXUTILS_NATIVE(func) \
+          Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_##func
 
 
 extern "C" NS_EXPORT void JNICALL
 MOZILLA_NATIVE(initialize) (JNIEnv* env, jobject);
 
 extern "C" NS_EXPORT void JNICALL
@@ -98,7 +100,15 @@ JAVAPROXY_NATIVE(isSameXPCOMObject) (JNI
 extern "C" NS_EXPORT void JNICALL
 LOCKPROXY_NATIVE(release) (JNIEnv *env, jclass that, jlong aLockObject);
 
 extern "C" NS_EXPORT jlong JNICALL
 MOZILLA_NATIVE(getNativeHandleFromAWT) (JNIEnv* env, jobject, jobject widget);
 
+extern "C" NS_EXPORT jlong JNICALL
+JXUTILS_NATIVE(wrapJavaObject) (JNIEnv* env, jobject, jobject aJavaObject,
+                                jstring aIID);
+
+extern "C" NS_EXPORT jobject JNICALL
+JXUTILS_NATIVE(wrapXPCOMObject) (JNIEnv* env, jobject, jlong aXPCOMObject,
+                                 jstring aIID);
+
 #endif // _nsJavaInterfaces_h_
Index: toolkit/mozapps/installer/packager.mk
===================================================================
RCS file: /cvsroot/mozilla/toolkit/mozapps/installer/packager.mk,v
retrieving revision 1.16.2.16
diff -u -6 -p -r1.16.2.16 packager.mk
--- toolkit/mozapps/installer/packager.mk	28 Dec 2006 20:23:47 -0000	1.16.2.16
+++ toolkit/mozapps/installer/packager.mk	22 Mar 2007 18:30:46 -0000
@@ -122,14 +122,17 @@ ifneq (,$(MOZ_PKG_MAC_EXTRA))
 PKG_DMG_FLAGS += $(MOZ_PKG_MAC_EXTRA)
 endif
 _ABS_TOPSRCDIR = $(shell cd $(topsrcdir) && pwd)
 ifdef UNIVERSAL_BINARY
 STAGEPATH = universal/
 endif
+ifndef PKG_DMG_SOURCE
+PKG_DMG_SOURCE = $(STAGEPATH)$(MOZ_PKG_APPNAME)
+endif
 MAKE_PACKAGE	= $(_ABS_TOPSRCDIR)/build/package/mac_osx/pkg-dmg \
-  --source "$(STAGEPATH)$(MOZ_PKG_APPNAME)" --target "$(PACKAGE)" \
+  --source "$(PKG_DMG_SOURCE)" --target "$(PACKAGE)" \
   --volname "$(MOZ_APP_DISPLAYNAME)" $(PKG_DMG_FLAGS)
 UNMAKE_PACKAGE	= \
   set -ex; \
   function cleanup() { \
     hdiutil detach $${DEV_NAME} || \
      { sleep 5 && hdiutil detach $${DEV_NAME} -force; }; \
Index: widget/src/cocoa/nsChildView.h
===================================================================
RCS file: /cvsroot/mozilla/widget/src/cocoa/nsChildView.h,v
retrieving revision 1.31.4.7
diff -u -6 -p -r1.31.4.7 nsChildView.h
--- widget/src/cocoa/nsChildView.h	20 Nov 2006 23:39:12 -0000	1.31.4.7
+++ widget/src/cocoa/nsChildView.h	22 Mar 2007 18:30:51 -0000
@@ -103,12 +103,14 @@ class nsChildView;
   NSPoint mHandScrollStartMouseLoc;
   nscoord mHandScrollStartScrollX, mHandScrollStartScrollY;
 
   // rects that were invalidated during a draw, so have pending drawing
   NSMutableArray* mPendingDirtyRects;
   BOOL mPendingFullDisplay;
+  
+  PRUint32 mLastModifierState;
 }
 
 // these are sent to the first responder when the window key status
 // changes
 - (void)viewsWindowDidBecomeKey;
 - (void)viewsWindowDidResignKey;
Index: widget/src/cocoa/nsChildView.mm
===================================================================
RCS file: /cvsroot/mozilla/widget/src/cocoa/nsChildView.mm,v
retrieving revision 1.120.2.14
diff -u -6 -p -r1.120.2.14 nsChildView.mm
--- widget/src/cocoa/nsChildView.mm	20 Nov 2006 23:39:12 -0000	1.120.2.14
+++ widget/src/cocoa/nsChildView.mm	22 Mar 2007 18:30:52 -0000
@@ -74,12 +74,19 @@
 - (BOOL)needsToDrawRect:(NSRect)aRect;
 - (BOOL)wantsDefaultClipping;
 #endif
 
 @end
 
+// This mask is only defined on 10.4 and up.
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
+enum {
+  NSDeviceIndependentModifierFlagsMask	= 0xffff0000U
+};
+#endif
+
 //#define DEBUG_IME 1
 
 @interface ChildView(Private)
 
   // sets up our view, attaching it to its owning gecko view
 - (id)initWithFrame:(NSRect)inFrame geckoChild:(nsChildView*)inChild eventSink:(nsIEventSink*)inSink;
@@ -1806,12 +1813,18 @@ NS_IMETHODIMP nsChildView::WidgetToScree
     // "global" coords are relative to the upper left of the main screen,
     // which is the first screen in the array (not [NSScreen mainScreen]).
     NSRect mainScreenFrame = [[[NSScreen screens] objectAtIndex:0] frame];
     temp.origin.y = NSMaxY(mainScreenFrame) - temp.origin.y;
   }
   
+  // If this is rect has a size (and is not simply a point), it is important to account 
+  // for the fact that convertRect:toView:nil thought our passed-in point was in bottom-left 
+  // coords. Thus, we subtract the rect's height, to get the top-left rect's origin 
+  // where we want it.
+  temp.origin.y -= temp.size.height;
+
   ConvertCocoaToGeckoRect(temp, aGlobalRect);
   
   return NS_OK;
 }
 
 
@@ -2259,29 +2272,52 @@ nsChildView::Idle()
     NSIntPixelsToTwips(deltaX, mPixelsToTwips);
   nscoord newY = mHandScrollStartScrollY +
     NSIntPixelsToTwips(deltaY, mPixelsToTwips);
   aScrollableView->ScrollTo(newX, newY, NS_VMREFRESH_IMMEDIATE);
 }
 
-// reset the scroll flag and cursor
-- (void) stopHandScroll:(NSEvent*)theEvent
+// Return true if the correct modifiers are pressed to perform hand scrolling.
++ (BOOL) areHandScrollModifiers:(unsigned int)modifiers
 {
-  mInHandScroll = FALSE;
+  // The command and option key should be held down.  Ignore capsLock by
+  // setting it explicitly to match.
+  modifiers |= NSAlphaShiftKeyMask;
+  return (modifiers & NSDeviceIndependentModifierFlagsMask) ==
+      (NSAlphaShiftKeyMask | NSCommandKeyMask | NSAlternateKeyMask);
+}
 
-  // calling flagsChanged will set the cursor appropriately
-  [self flagsChanged:theEvent];
+// If the user is pressing the hand scroll modifiers, then set
+// the hand scroll cursor.
+- (void) setHandScrollCursor:(NSEvent*)theEvent
+{
+  BOOL inMouseView = NO;
+
+  // check to see if the user has hand scroll modifiers held down; if so, 
+  // find out if the cursor is in an ChildView
+  if ([ChildView areHandScrollModifiers:[theEvent modifierFlags]]) {
+    NSPoint pointInWindow = [[self window] mouseLocationOutsideOfEventStream];
+
+    NSView* mouseView = [[[self window] contentView] hitTest:pointInWindow];
+    inMouseView = (mouseView != nil && [mouseView isMemberOfClass:[ChildView class]]);   
+  }
+  if (inMouseView) {
+      mGeckoChild->SetCursor(eCursor_grab);
+  } else {
+    nsCursor cursor = mGeckoChild->GetCursor();
+    if (!mInHandScroll) {
+      if (cursor == eCursor_grab || cursor == eCursor_grabbing)
+        mGeckoChild->SetCursor(eCursor_standard);
+    }
+  }
 }
 
-// Return true if the correct modifiers are pressed to perform hand scrolling.
-+ (BOOL) areHandScrollModifiers:(unsigned int)modifiers
+// reset the scroll flag and cursor
+- (void) stopHandScroll:(NSEvent*)theEvent
 {
-  // The command and option key should be held down; ignore caps lock. We only
-  // check the low word because Apple started using it in panther for other purposes
-  // (no idea what).
-  modifiers |= NSAlphaShiftKeyMask;          // ignore capsLock by setting it explicitly to match
-  return modifiers >> 16 == (NSAlphaShiftKeyMask | NSCommandKeyMask | NSAlternateKeyMask) >> 16;
+  mInHandScroll = FALSE;
+  [self setHandScrollCursor:theEvent];
 }
 
 //
 // -setFrame
 //
 // Override in order to keep our mouse enter/exit tracking rect in sync with
@@ -2657,13 +2693,13 @@ nsChildView::Idle()
   // XXX maybe call markedTextSelectionChanged:client: here?
 }
 
 - (void)mouseEntered:(NSEvent*)theEvent
 {
   // checks to see if we should change to the hand cursor
-  [self flagsChanged:theEvent];
+  [self setHandScrollCursor:theEvent];
   
   // we need to forward mouse move events to gecko when the mouse
   // is over a gecko view
   if (mToggleMouseMoveEventWatching)
     [[self window] setAcceptsMouseMovedEvents: YES];
 }
@@ -2935,20 +2971,25 @@ static PRBool ConvertUnicodeToCharCode(P
 
   *outChar = convertedString[1];
   ::DisposeUnicodeToTextInfo(&converterInfo);
   return PR_TRUE;
 }
 
-static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& macEvent)
+static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& macEvent, PRUint32 keyType = 0)
 {
-    if ([cocoaEvent type] == NSKeyDown)
-      macEvent.what = [cocoaEvent isARepeat] ? autoKey : keyDown;
-    else
-      macEvent.what = keyUp;
+    UInt32 charCode = 0;
+    if ([cocoaEvent type] == NSFlagsChanged) {
+      macEvent.what = keyType == NS_KEY_DOWN ? keyDown : keyUp;
+    } else {
+      charCode = [[cocoaEvent characters] characterAtIndex:0];
+      if ([cocoaEvent type] == NSKeyDown)
+        macEvent.what = [cocoaEvent isARepeat] ? autoKey : keyDown;
+      else
+        macEvent.what = keyUp;
+    }
 
-    UInt32 charCode = [[cocoaEvent characters] characterAtIndex: 0];
     if (charCode >= 0x0080)
     {
         switch (charCode) {
         case NSUpArrowFunctionKey:
             charCode = kUpArrowCharCode;
             break;
@@ -3360,36 +3401,54 @@ static void ConvertCocoaKeyEventToMacEve
   ConvertCocoaKeyEventToMacEvent(theEvent, macEvent);
   geckoEvent.nativeMsg = &macEvent;
 
   mGeckoChild->DispatchWindowEvent(geckoEvent);
 }
 
-// look for the user's pressing of command and alt so that we can display
-// the hand scroll cursor
+// Fire key up/down events for the modifier keys (shift, alt, ctrl, command).
 - (void)flagsChanged:(NSEvent*)theEvent
 {
-  BOOL inMouseView = NO;
-  // check to see if the user has hand scroll modifiers held down; if so, 
-  // find out if the cursor is in an ChildView
-  if ([ChildView areHandScrollModifiers:[theEvent modifierFlags]]) {
-    NSPoint pointInWindow = [[self window] mouseLocationOutsideOfEventStream];
-
-    NSView* mouseView = [[[self window] contentView] hitTest:pointInWindow];
-    inMouseView = (mouseView != nil && [mouseView isMemberOfClass:[ChildView class]]);   
-  }
-  if (inMouseView) {
-      mGeckoChild->SetCursor(eCursor_grab);
-  } else {
-    nsCursor cursor = mGeckoChild->GetCursor();
-    if (!mInHandScroll) {
-      if (cursor == eCursor_grab || cursor == eCursor_grabbing)
-        mGeckoChild->SetCursor(eCursor_standard);
-      // pass on the event since we are not using it
-      [super flagsChanged:theEvent];
+  if ([theEvent type] == NSFlagsChanged) {
+    unsigned int modifiers =
+      [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
+    const PRUint32 kModifierMaskTable[] =
+      {NSShiftKeyMask, NSControlKeyMask, NSAlternateKeyMask, NSCommandKeyMask};
+    const PRUint32 kModifierCount = sizeof(kModifierMaskTable) /
+                                    sizeof(kModifierMaskTable[0]);
+
+    for(PRUint32 i = 0 ; i < kModifierCount ; i++) {
+      PRUint32 modifierBit = kModifierMaskTable[i];
+      if ((modifiers & modifierBit) != (mLastModifierState & modifierBit)) {
+        PRUint32 message = ((modifiers & modifierBit) != 0 ? NS_KEY_DOWN :
+                                                             NS_KEY_UP);
+
+        // Fire a key event.
+        nsKeyEvent geckoEvent(PR_TRUE, 0, nsnull);
+        geckoEvent.point.x = geckoEvent.point.y = 0;
+        [self convertKeyEvent:theEvent
+                      message:message
+                 toGeckoEvent:&geckoEvent];
+
+        EventRecord macEvent;
+        ConvertCocoaKeyEventToMacEvent(theEvent, macEvent, message);
+        geckoEvent.nativeMsg = &macEvent;
+        mGeckoChild->DispatchWindowEvent(geckoEvent);
+
+        // Stop if focus has changed.
+        // Check to see if we are still the first responder.
+        NSResponder* resp = [[self window] firstResponder];
+        if (resp != (NSResponder*)self)
+          break;
+      }
     }
+
+    mLastModifierState = modifiers;
   }
+
+  // check if the hand scroll cursor needs to be set/unset
+  [self setHandScrollCursor:theEvent];
 }
 
 // This method is called when we are about to be focused.
 - (BOOL)becomeFirstResponder
 {
   if (!mGeckoChild) return NO;   // we've been destroyed
@@ -3535,13 +3594,13 @@ static PRUint32 ConvertMacToRaptorKeyCod
   {
 //  case ??             :       raptorKeyCode = NS_VK_CANCEL;   break;      // don't know what this key means. Nor does joki
 
 // modifiers. We don't get separate events for these
     case kEscapeKeyCode:        raptorKeyCode = NS_VK_ESCAPE;         break;
     case kShiftKeyCode:         raptorKeyCode = NS_VK_SHIFT;          break;
-//    case kCommandKeyCode:       raptorKeyCode = NS_VK_META;           break;
+    case kCommandKeyCode:       raptorKeyCode = NS_VK_META;           break;
     case kCapsLockKeyCode:      raptorKeyCode = NS_VK_CAPS_LOCK;      break;
     case kControlKeyCode:       raptorKeyCode = NS_VK_CONTROL;        break;
     case kOptionkeyCode:        raptorKeyCode = NS_VK_ALT;            break;
     case kClearKeyCode:         raptorKeyCode = NS_VK_CLEAR;          break;
 
 // function keys
@@ -3735,13 +3794,17 @@ static PRBool IsSpecialRaptorKey(UInt32 
     // gecko also wants charCode to be in the appropriate case
     if (outGeckoEvent->isShift && (outGeckoEvent->charCode >= 'a' && outGeckoEvent->charCode <= 'z'))
       outGeckoEvent->charCode -= 32;    // convert to uppercase
   }
   else
   {
-    outGeckoEvent->keyCode = ConvertMacToRaptorKeyCode([aKeyEvent keyCode], outGeckoEvent, [aKeyEvent characters]);
+    NSString* characters = nil;
+    if ([aKeyEvent type] != NSFlagsChanged)
+      characters = [aKeyEvent characters];
+  
+    outGeckoEvent->keyCode = ConvertMacToRaptorKeyCode([aKeyEvent keyCode], outGeckoEvent, characters);
     outGeckoEvent->charCode = 0;
   } 
   
   if (aMessage == NS_KEY_PRESS && !outGeckoEvent->isMeta && outGeckoEvent->keyCode != NS_VK_PAGE_UP && 
       outGeckoEvent->keyCode != NS_VK_PAGE_DOWN)
     ::ObscureCursor();
Index: xulrunner/installer/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/xulrunner/installer/Makefile.in,v
retrieving revision 1.1.4.5
diff -u -6 -p -r1.1.4.5 Makefile.in
--- xulrunner/installer/Makefile.in	30 Nov 2006 21:36:24 -0000	1.1.4.5
+++ xulrunner/installer/Makefile.in	22 Mar 2007 18:30:55 -0000
@@ -59,12 +59,13 @@ NO_PKG_FILES = \
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 DIRS += mac
 _APPNAME = $(PKG_BASENAME).pkg
 PKG_SKIP_STRIP = 1
 MOZ_PKG_SPECIAL = pkg
+PKG_DMG_SOURCE = $(STAGEPATH)xulrunner-pkg
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
 
