Backed out changeset add33a95e3ef to fix talos crashes. b=489864
authorSteven Michaud <smichaud@pobox.com>
Mon, 11 May 2009 15:40:32 -0500
changeset 28212 aa3a28d8eb76653d061bb2d07ac6fe94c0e9f17b
parent 28210 d5cc0631c2bda4d7b9ece7b638dc2a0af91cc3a9 (current diff)
parent 28211 88df6943633f8f75d3df5460ae720d860f4307a1 (diff)
child 28213 9cbd47d7b0251d0e4d193789c3def2c6c062726a
push id6945
push usersmichaud@pobox.com
push dateMon, 11 May 2009 20:41:08 +0000
treeherdermozilla-central@aa3a28d8eb76 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs489864
milestone1.9.2a1pre
backs outadd33a95e3ef643243db7d287251cacbadecf515
Backed out changeset add33a95e3ef to fix talos crashes. b=489864
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -114,16 +114,21 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPr
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheUpdateService,
                                          nsOfflineCacheUpdateService::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsOfflineCacheUpdate)
 NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
 #ifdef MOZ_ENABLE_DBUS
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp)
 #endif 
 
+#if defined(XP_MAC) || defined(XP_MACOSX)
+#include "nsInternetConfigService.h"
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsInternetConfigService)
+#endif
+
 // session history
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHEntry)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHTransaction)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHistory)
 
 // download history
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadHistory)
 
@@ -224,16 +229,20 @@ static const nsModuleComponentInfo gDocS
   { NS_OFFLINECACHEUPDATE_CLASSNAME, NS_OFFLINECACHEUPDATE_CID, NS_OFFLINECACHEUPDATE_CONTRACTID,
     nsOfflineCacheUpdateConstructor, },
   { "Local Application Handler App", NS_LOCALHANDLERAPP_CID, 
     NS_LOCALHANDLERAPP_CONTRACTID, PlatformLocalHandlerApp_tConstructor, },
 #ifdef MOZ_ENABLE_DBUS
   { "DBus Handler App", NS_DBUSHANDLERAPP_CID,
       NS_DBUSHANDLERAPP_CONTRACTID, nsDBusHandlerAppConstructor},
 #endif
+#if defined(XP_MAC) || defined(XP_MACOSX)
+  { "Internet Config Service", NS_INTERNETCONFIGSERVICE_CID, NS_INTERNETCONFIGSERVICE_CONTRACTID,
+    nsInternetConfigServiceConstructor, },
+#endif
         
     // session history
    { "nsSHEntry", NS_SHENTRY_CID,
       NS_SHENTRY_CONTRACTID, nsSHEntryConstructor },
    { "nsSHEntry", NS_HISTORYENTRY_CID,
       NS_HISTORYENTRY_CONTRACTID, nsSHEntryConstructor },
    { "nsSHTransaction", NS_SHTRANSACTION_CID,
       NS_SHTRANSACTION_CONTRACTID, nsSHTransactionConstructor },
--- a/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -264,17 +264,35 @@ nsresult nsIconChannel::MakeInputStream(
     
     CFURLRef macURL;
     if (NS_SUCCEEDED(localFileMac->GetCFURL(&macURL))) {
       iconImage = [[NSWorkspace sharedWorkspace] iconForFile:[(NSURL*)macURL path]];
       ::CFRelease(macURL);
     }
   }
 
-  // if we don't have an icon yet try to get one by extension
+  // try by HFS type if we don't have an icon yet
+  if (!iconImage) {
+    nsCOMPtr<nsIMIMEService> mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // if we were given an explicit content type, use it....
+    nsCOMPtr<nsIMIMEInfo> mimeInfo;
+    if (mimeService && (!contentType.IsEmpty() || !fileExt.IsEmpty()))
+      mimeService->GetFromTypeAndExtension(contentType, fileExt, getter_AddRefs(mimeInfo));
+
+    if (mimeInfo) {
+      // get the icon by HFS type
+      PRUint32 macType;
+      if (NS_SUCCEEDED(mimeInfo->GetMacType(&macType)))
+        iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(macType)];
+    }
+  }
+  
+  // if we still don't have an icon, try to get one by extension
   if (!iconImage && !fileExt.IsEmpty()) {
     NSString* fileExtension = [NSString stringWithUTF8String:PromiseFlatCString(fileExt).get()];
     iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:fileExtension];
   }
   
   if (!iconImage)
     return NS_ERROR_FAILURE;
   
--- a/netwerk/mime/public/nsIMIMEInfo.idl
+++ b/netwerk/mime/public/nsIMIMEInfo.idl
@@ -48,17 +48,17 @@ interface nsIMutableArray;
 interface nsIInterfaceRequestor;
 
 typedef long nsHandlerInfoAction;
 
 /**
  * nsIHandlerInfo gives access to the information about how a given protocol
  * scheme or MIME-type is handled.
  */
-[scriptable, uuid(8E726396-3E02-467C-855E-5900E562BA42)] 
+[scriptable, uuid(325e56a7-3762-4312-aec7-f1fcf84b4145)] 
 interface nsIHandlerInfo : nsISupports {
     /**
      * The type of this handler info.  For MIME handlers, this is the MIME type.
      * For protocol handlers, it's the scheme.
      * 
      * @return String representing the type.
      */
     readonly attribute ACString type;
@@ -198,16 +198,22 @@ interface nsIMIMEInfo : nsIHandlerInfo {
      * 
      * @return String representing the MIME type.
      * 
      * @deprecated  use nsIHandlerInfo::type instead.
      */
     readonly attribute ACString MIMEType;
 
     /**
+     * Mac Type and creator types
+     */
+    attribute PRUint32 macType;
+    attribute PRUint32 macCreator;
+
+    /**
      * Returns whether or not these two nsIMIMEInfos are logically
      * equivalent.
      *
      * @returns PR_TRUE if the two are considered equal
      */
     boolean equals(in nsIMIMEInfo aMIMEInfo);
 
     /** 
--- a/uriloader/exthandler/Makefile.in
+++ b/uriloader/exthandler/Makefile.in
@@ -92,16 +92,18 @@ ifdef MOZ_PHOENIX
 REQUIRES	+= toolkitcomps
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 REQUIRES		+= windowwatcher \
 	             $(NULL)
 
 CMMSRCS	= nsOSHelperAppService.mm \
+			nsInternetConfig.mm \
+			nsInternetConfigService.mm \
 			nsMIMEInfoMac.mm \
 			nsLocalHandlerAppMac.mm \
 			$(NULL)
 else
 OSHELPER	= nsOSHelperAppService.cpp
 endif
 
 LOCAL_INCLUDES = -I$(srcdir)
@@ -138,16 +140,20 @@ XPIDLSRCS = \
 	nsCExternalHandlerService.idl	\
 	nsIExternalProtocolService.idl \
 	nsIExternalHelperAppService.idl	\
 	nsIHelperAppLauncherDialog.idl \
 	nsIContentDispatchChooser.idl \
 	nsIHandlerService.idl	\
 	$(NULL)
 
+ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
+XPIDLSRCS		+= nsIInternetConfigService.idl
+endif
+
 CPPSRCS	= \
 	nsExternalHelperAppService.cpp	\
 	nsExternalProtocolHandler.cpp \
 	nsMIMEInfoImpl.cpp \
 	nsLocalHandlerApp.cpp \
 	$(OSHELPER) \
 	$(NULL)
 
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfig.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+ 
+#ifndef __NS_INTERNETCONFIG_H__
+#define __NS_INTERNETCONFIG_H__
+
+#include <Carbon/Carbon.h>
+#include "prtypes.h"
+#include "nsError.h"
+
+class nsInternetConfig
+{
+public:
+	nsInternetConfig();
+	~nsInternetConfig();
+
+	static ICInstance GetInstance();
+	static  PRBool		HasSeedChanged();
+private:
+	static	ICInstance sInstance;
+	static  long sSeed;
+	static  PRInt32 sRefCount;
+};
+
+#endif /* __NS_INTERNETCONFIG_H__ */
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfig.mm
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsInternetConfig.h"
+#include "nsObjCExceptions.h"
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "nsDebug.h"
+
+#include <Carbon/Carbon.h>
+
+ICInstance nsInternetConfig::sInstance = NULL;
+long nsInternetConfig::sSeed = 0;
+PRInt32  nsInternetConfig::sRefCount = 0;
+
+
+
+static OSType GetAppCreatorCode()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+  ProcessSerialNumber psn = { 0, kCurrentProcess } ;
+  ProcessInfoRec      procInfo;
+  
+  procInfo.processInfoLength = sizeof(ProcessInfoRec);
+  procInfo.processName = NULL;
+#ifndef __LP64__
+  procInfo.processAppSpec = NULL;
+#else
+  procInfo.processAppRef = NULL;
+#endif
+
+  GetProcessInformation(&psn, &procInfo);
+  return procInfo.processSignature;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0x0);
+}
+
+
+
+ICInstance nsInternetConfig::GetInstance()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+	if ( !sInstance )
+	{
+		OSType creator = GetAppCreatorCode();
+		OSStatus err = ::ICStart( &sInstance, creator  );
+		if ( err != noErr )
+		{
+			::ICStop( sInstance );
+		}
+		else
+		{
+			::ICGetSeed( sInstance, &sSeed );
+		}
+	}
+	return sInstance;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NULL);
+}
+
+PRBool nsInternetConfig::HasSeedChanged()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+	ICInstance instance = nsInternetConfig::GetInstance();
+	if ( instance )
+	{
+		long newSeed = 0;
+		::ICGetSeed( sInstance, &newSeed );
+		if ( newSeed != sSeed )
+		{
+			sSeed = newSeed;
+			return PR_TRUE;
+		}
+	}
+	return PR_FALSE;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
+}
+
+nsInternetConfig::nsInternetConfig()
+{
+	sRefCount++;
+}
+
+nsInternetConfig::~nsInternetConfig()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+	sRefCount--;
+	if ( sRefCount == 0 && sInstance)
+	{
+		::ICStop( sInstance );
+		sInstance = NULL;
+	}
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfigService.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+#ifndef __nsInternetConfigService_h
+#define __nsInternetConfigService_h
+
+#include "nsIInternetConfigService.h"
+#include "nsInternetConfig.h"
+
+#define NS_INTERNETCONFIGSERVICE_CID \
+  {0x9b8b9d81, 0x5f4f, 0x11d4, \
+    { 0x96, 0x96, 0x00, 0x60, 0x08, 0x3a, 0x0b, 0xcf }}
+
+class nsInternetConfigService : public nsIInternetConfigService
+{
+public:
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIINTERNETCONFIGSERVICE
+
+  nsresult GetMappingForMIMEType(const char *mimetype, const char *fileextension, ICMapEntry *entry);
+
+  nsInternetConfigService();
+  virtual ~nsInternetConfigService();
+protected:
+  // some private helper methods...
+  nsresult FillMIMEInfoForICEntry(ICMapEntry& entry, nsIMIMEInfo ** mimeinfo);
+  
+  nsresult GetICKeyPascalString(PRUint32 inIndex, const unsigned char*& outICKey);
+  nsresult GetICPreference(PRUint32 inKey, void *outData, long *ioSize);
+};
+
+#endif
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfigService.mm
@@ -0,0 +1,629 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Steve Dagley <sdagley@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsInternetConfigService.h"
+#include "nsObjCExceptions.h"
+#include "nsCOMPtr.h"
+#include "nsIMIMEInfo.h"
+#include "nsMIMEInfoMac.h"
+#include "nsAutoPtr.h"
+#include "nsIFactory.h"
+#include "nsIComponentManager.h"
+#include "nsIURL.h"
+#include "nsXPIDLString.h"
+#include "nsReadableUtils.h"
+#include "nsString.h"
+#include "nsCRT.h"
+#include "nsILocalFileMac.h"
+#include "nsMimeTypes.h"
+
+#import <Carbon/Carbon.h>
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+
+/* This is an undocumented interface that seems to exist at least in 10.4 and 10.5 */
+@class NSURLFileTypeMappingsInternal;
+
+@interface NSURLFileTypeMappings : NSObject
+{
+    NSURLFileTypeMappingsInternal *_internal;
+}
+
++ (NSURLFileTypeMappings*)sharedMappings;
+- (NSString*)MIMETypeForExtension:(NSString*)fp8;
+- (NSString*)preferredExtensionForMIMEType:(NSString*)fp8;
+- (NSArray*)extensionsForMIMEType:(NSString*)fp8;
+@end
+
+// helper converter function.....
+static void ConvertCharStringToStr255(const char* inString, Str255& outString)
+{
+  if (inString == NULL)
+    return;
+  
+  PRInt32 len = strlen(inString);
+  NS_ASSERTION(len <= 255 , " String is too big");
+  if (len> 255)
+  {
+    len = 255;
+  }
+  memcpy(&outString[1], inString, len);
+  outString[0] = len;
+}
+
+/* Define Class IDs */
+
+nsInternetConfigService::nsInternetConfigService()
+{
+}
+
+nsInternetConfigService::~nsInternetConfigService()
+{
+}
+
+
+/*
+ * Implement the nsISupports methods...
+ */
+NS_IMPL_ISUPPORTS1(nsInternetConfigService, nsIInternetConfigService)
+
+// void LaunchURL (in string url);
+// Given a url string, call ICLaunchURL using url
+// Under OS X use LaunchServices instead of IC
+NS_IMETHODIMP nsInternetConfigService::LaunchURL(const char *url)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  nsresult rv = NS_ERROR_FAILURE; 
+
+  CFURLRef myURLRef = ::CFURLCreateWithBytes(
+                                             kCFAllocatorDefault,
+                                             (const UInt8*)url,
+                                             strlen(url),
+                                             kCFStringEncodingUTF8, NULL);
+  if (myURLRef)
+  {
+    rv = ::LSOpenCFURLRef(myURLRef, NULL);
+    ::CFRelease(myURLRef);
+  }
+
+  return rv;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+// boolean HasMappingForMIMEType (in string mimetype);
+// given a mime type, search Internet Config database for a mapping for that mime type
+NS_IMETHODIMP nsInternetConfigService::HasMappingForMIMEType(const char *mimetype, PRBool *_retval)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  ICMapEntry entry;
+  nsresult rv = GetMappingForMIMEType(mimetype, nsnull, &entry);
+  if (rv == noErr)
+    *_retval = PR_TRUE;
+  else
+    *_retval = PR_FALSE;
+  return rv;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+/* boolean hasProtocolHandler (in string protocol); */
+// returns NS_ERROR_NOT_AVAILABLE if the current application is registered
+// as the protocol handler for the given protocol
+NS_IMETHODIMP nsInternetConfigService::HasProtocolHandler(const char *protocol, PRBool *_retval)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  *_retval = PR_FALSE;            // presume the OS doesn't have a handler
+  nsresult rv = NS_OK;
+
+  // Since protocol comes in with _just_ the protocol we have to add a ':' to
+  // the end of it or LaunchServices will be very unhappy with the CFURLRef
+  // created from it (crashes trying to look up a handler for it with
+  // LSGetApplicationForURL, at least under 10.2.1)
+  nsCAutoString scheme(protocol);
+  scheme += ":";
+  CFURLRef myURLRef = ::CFURLCreateWithBytes(
+                                              kCFAllocatorDefault,
+                                              (const UInt8 *)scheme.get(),
+                                              scheme.Length(),
+                                              kCFStringEncodingUTF8, NULL);
+  if (myURLRef)
+  {
+    FSRef appFSRef;
+  
+    if (::LSGetApplicationForURL(myURLRef, kLSRolesAll, &appFSRef, NULL) == noErr)
+    { // Now see if the FSRef for the found app == the running app
+      ProcessSerialNumber psn;
+      if (::GetCurrentProcess(&psn) == noErr)
+      {
+        FSRef runningAppFSRef;
+        if (::GetProcessBundleLocation(&psn, &runningAppFSRef) == noErr)
+        {
+          if (::FSCompareFSRefs(&appFSRef, &runningAppFSRef) == noErr)
+          { // Oops, the current app is the handler which would cause infinite recursion
+            rv = NS_ERROR_NOT_AVAILABLE;
+          }
+          else
+          {
+            *_retval = PR_TRUE;
+          }
+        }
+      }
+    }
+    ::CFRelease(myURLRef);
+  }
+
+  return rv;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+// This method does the dirty work of traipsing through IC mappings database
+// looking for a mapping for mimetype
+nsresult nsInternetConfigService::GetMappingForMIMEType(const char *mimetype, const char *fileextension, ICMapEntry *entry)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  ICInstance  inst = nsInternetConfig::GetInstance();
+  OSStatus    err = noErr;
+  ICAttr      attr;
+  Handle      prefH;
+  PRBool      domimecheck = PR_TRUE;
+  PRBool      gotmatch = PR_FALSE;
+  ICMapEntry  ent;
+  
+  // if mime type is "unknown" or "octet stream" *AND* we have a file extension,
+  // then disable match on mime type
+  if (((nsCRT::strcasecmp(mimetype, UNKNOWN_CONTENT_TYPE) == 0) ||
+       (nsCRT::strcasecmp(mimetype, APPLICATION_OCTET_STREAM) == 0)) &&
+       fileextension)
+    domimecheck = PR_FALSE;
+  
+  entry->totalLength = 0;
+  if (inst)
+  {
+    err = ::ICBegin(inst, icReadOnlyPerm);
+    if (err == noErr)
+    {
+      prefH = ::NewHandle(2048); // picked 2048 out of thin air
+      if (prefH)
+      {
+        err = ::ICFindPrefHandle(inst, kICMapping, &attr, prefH);
+        if (err == noErr)
+        {
+          long count;
+          err = ::ICCountMapEntries(inst, prefH, &count);
+          if (err == noErr)
+          {
+            long pos;
+            for (long i = 1; i <= count; ++i)
+            {
+              err = ::ICGetIndMapEntry(inst, prefH, i, &pos, &ent);
+              if (err == noErr)
+              {
+                // first, do mime type check
+                if (domimecheck)
+                {
+                  nsCAutoString temp((char *)&ent.MIMEType[1], (int)ent.MIMEType[0]);
+                  if (!temp.EqualsIgnoreCase(mimetype))
+                  {
+                    // we need to do mime check, and check failed
+                    // nothing here to see, move along
+                    continue;
+                  }
+                }
+                if (fileextension)
+                {
+                  // if fileextension was passed in, compare that also
+                  if (ent.extension[0]) // check for non-empty pascal string
+                  {
+                    nsCAutoString temp((char *)&ent.extension[1], (int)ent.extension[0]);
+                    if (temp.EqualsIgnoreCase(fileextension))
+                    {
+                      // mime type and file extension match, we're outta here
+                      gotmatch = PR_TRUE;
+                      // copy over ICMapEntry
+                      *entry = ent;
+                      break;
+                    }
+                  }
+                }
+                else if(domimecheck)
+                {
+                  // at this point, we've got our match because
+                  // domimecheck is true, the mime strings match, and fileextension isn't passed in
+                  // bad thing is we'll stop on first match, but what can you do?
+                  gotmatch = PR_TRUE;
+                  // copy over ICMapEntry
+                  *entry = ent;
+                  break;
+                }
+              }
+            }
+          }
+        }
+        ::DisposeHandle(prefH);
+      }
+      else
+      {
+        err = memFullErr;
+      }
+      err = ::ICEnd(inst);
+      if (err == noErr && gotmatch == PR_FALSE)
+      {
+        err = fnfErr; // return SOME kind of error
+      }
+    }
+  }
+  
+  if (err != noErr)
+    return NS_ERROR_FAILURE;
+  else
+    return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+nsresult nsInternetConfigService::FillMIMEInfoForICEntry(ICMapEntry& entry, nsIMIMEInfo ** mimeinfo)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  // create a mime info object and we'll fill it in based on the values from IC mapping entry
+  nsresult  rv = NS_OK;
+  nsRefPtr<nsMIMEInfoMac> info (new nsMIMEInfoMac());
+  if (info)
+  {
+    nsCAutoString mimetype ((char *)&entry.MIMEType[1], entry.MIMEType[0]);
+    // check if entry.MIMEType is empty, if so, set mime type to APPLICATION_OCTET_STREAM
+    if (entry.MIMEType[0])
+      info->SetMIMEType(mimetype);
+    else
+    { // The IC mappings seem to not be very agressive about determining the mime type if
+      // all we have is a type or creator code.  This is a bandaid approach for when we
+      // get a file of type 'TEXT' with no mime type mapping so that we'll display the
+      // file rather than trying to download it.
+      if (entry.fileType == 'TEXT')
+        info->SetMIMEType(NS_LITERAL_CSTRING(TEXT_PLAIN));
+      else
+        info->SetMIMEType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
+    }
+
+    nsCAutoString temp;
+
+    /* The internet config service seems to return the first extension
+     * from the map's list; however, that first extension is sometimes
+     * not the best one to use.  Specifically, for image/jpeg, the
+     * internet config service will return "jfif", whereas the
+     * preferred extension is really "jpg".  So, don't believe IC's
+     * lies, and ask NSURLFileTypeMappings instead (see bug 414201).
+     */
+    NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings];
+    NSString *mimeStr = [NSString stringWithCString:mimetype.get() encoding:NSASCIIStringEncoding];
+    NSString *realExtension = map ? [map preferredExtensionForMIMEType:mimeStr] : NULL;
+
+    if (realExtension) {
+      temp.Assign([realExtension cStringUsingEncoding:NSASCIIStringEncoding]);
+
+      info->AppendExtension(temp);
+    } else {
+      // convert entry.extension which is a Str255 
+      // don't forget to remove the '.' in front of the file extension....
+      temp.Assign((char *)&entry.extension[2], entry.extension[0] > 0 ? (int)entry.extension[0]-1 : 0);
+
+      info->AppendExtension(temp);
+    }
+
+    info->SetMacType(entry.fileType);
+    info->SetMacCreator(entry.fileCreator);
+    temp.Assign((char *) &entry.entryName[1], entry.entryName[0]);
+    info->SetDescription(NS_ConvertASCIItoUTF16(temp));
+    
+    temp.Assign((char *) &entry.postAppName[1], entry.postAppName[0]);
+    info->SetDefaultDescription(NS_ConvertASCIItoUTF16(temp));
+    
+    if (entry.flags & kICMapPostMask)
+    {
+      // there is a post processor app
+      info->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
+      nsCOMPtr<nsILocalFileMac> file (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+      if (file)
+      {
+        rv = file->InitToAppWithCreatorCode(entry.postCreator);
+        if (rv == NS_OK)
+        {
+          nsCOMPtr<nsIFile> nsfile = do_QueryInterface(file, &rv);
+          if (rv == NS_OK)
+            info->SetDefaultApplication(nsfile);
+        }
+      }
+    }
+    else
+    {
+      // there isn't a post processor app so set the preferred action to be save to disk.
+      info->SetPreferredAction(nsIMIMEInfo::saveToDisk);
+    }
+    
+    *mimeinfo = info;
+    NS_IF_ADDREF(*mimeinfo);
+  }
+  else // we failed to allocate the info object...
+    rv = NS_ERROR_FAILURE;
+   
+  return rv;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+/* void FillInMIMEInfo (in string mimetype, in string fileExtension, out nsIMIMEInfo mimeinfo); */
+NS_IMETHODIMP nsInternetConfigService::FillInMIMEInfo(const char *mimetype, const char * aFileExtension, nsIMIMEInfo **mimeinfo)
+{
+  nsresult    rv;
+  ICMapEntry  entry;
+  
+  NS_ENSURE_ARG_POINTER(mimeinfo);
+  *mimeinfo = nsnull;
+
+  if (aFileExtension && *aFileExtension)
+  {
+    nsCAutoString fileExtension;
+    fileExtension.Assign(".");  
+    fileExtension.Append(aFileExtension);
+    rv = GetMappingForMIMEType(mimetype, fileExtension.get(), &entry);
+  }
+  else
+  {
+    rv = GetMappingForMIMEType(mimetype, nsnull, &entry);
+  }
+  
+  if (rv == NS_OK)
+    rv = FillMIMEInfoForICEntry(entry, mimeinfo);
+  else
+    rv = NS_ERROR_FAILURE;
+
+  return rv;
+}
+
+NS_IMETHODIMP nsInternetConfigService::GetMIMEInfoFromExtension(const char *aFileExt, nsIMIMEInfo **_retval)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  nsresult    rv = NS_ERROR_FAILURE;
+  ICInstance  instance = nsInternetConfig::GetInstance();
+  if (instance)
+  {
+    nsCAutoString filename("foobar.");
+    filename += aFileExt;
+    Str255  pFileName;
+    ConvertCharStringToStr255(filename.get(), pFileName);
+    ICMapEntry  entry;
+    OSStatus  err = ::ICMapFilename(instance, pFileName, &entry);
+    if (err == noErr)
+    {
+      rv = FillMIMEInfoForICEntry(entry, _retval);
+    }
+  }   
+  return rv;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetMIMEInfoFromTypeCreator(PRUint32 aType, PRUint32 aCreator, const char *aFileExt, nsIMIMEInfo **_retval)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  nsresult    rv = NS_ERROR_FAILURE;
+  ICInstance  instance = nsInternetConfig::GetInstance();
+  if (instance)
+  {
+    nsCAutoString filename("foobar.");
+    filename += aFileExt;
+    Str255  pFileName;
+    ConvertCharStringToStr255(filename.get(), pFileName);
+    ICMapEntry  entry;
+    OSStatus  err = ::ICMapTypeCreator(instance, aType, aCreator, pFileName, &entry);
+    if (err == noErr)
+      rv = FillMIMEInfoForICEntry(entry,_retval);
+  }
+  return rv;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+nsresult nsInternetConfigService::GetICKeyPascalString(PRUint32 inIndex, const unsigned char*& outICKey)
+{
+  nsresult  rv = NS_OK;
+
+  switch (inIndex)
+  {
+    case eICColor_WebBackgroundColour: outICKey = kICWebBackgroundColour; break;
+    case eICColor_WebReadColor:        outICKey = kICWebReadColor;        break;
+    case eICColor_WebTextColor:        outICKey = kICWebTextColor;        break;
+    case eICColor_WebUnreadColor:      outICKey = kICWebUnreadColor;      break;
+
+    case eICBoolean_WebUnderlineLinks: outICKey = kICWebUnderlineLinks;  break;
+    case eICBoolean_UseFTPProxy:       outICKey = kICUseFTPProxy;        break;
+    case eICBoolean_UsePassiveFTP:     outICKey = kICUsePassiveFTP;      break;
+    case eICBoolean_UseHTTPProxy:      outICKey = kICUseHTTPProxy;       break;
+    case eICBoolean_NewMailDialog:     outICKey = kICNewMailDialog;      break;
+    case eICBoolean_NewMailFlashIcon:  outICKey = kICNewMailFlashIcon;   break;
+    case eICBoolean_NewMailPlaySound:  outICKey = kICNewMailPlaySound;   break;
+    case eICBoolean_UseGopherProxy:    outICKey = kICUseGopherProxy;     break;
+    case eICBoolean_UseSocks:          outICKey = kICUseSocks;           break;
+
+    case eICString_WWWHomePage:        outICKey = kICWWWHomePage;        break;
+    case eICString_WebSearchPagePrefs: outICKey = kICWebSearchPagePrefs; break;
+    case eICString_MacSearchHost:      outICKey = kICMacSearchHost;      break;
+    case eICString_FTPHost:            outICKey = kICFTPHost;            break;
+    case eICString_FTPProxyUser:       outICKey = kICFTPProxyUser;       break;
+    case eICString_FTPProxyAccount:    outICKey = kICFTPProxyAccount;    break;
+    case eICString_FTPProxyHost:       outICKey = kICFTPProxyHost;       break;
+    case eICString_FTPProxyPassword:   outICKey = kICFTPProxyPassword;   break;
+    case eICString_HTTPProxyHost:      outICKey = kICHTTPProxyHost;      break;
+    case eICString_LDAPSearchbase:     outICKey = kICLDAPSearchbase;     break;
+    case eICString_LDAPServer:         outICKey = kICLDAPServer;         break;
+    case eICString_SMTPHost:           outICKey = kICSMTPHost;           break;
+    case eICString_Email:              outICKey = kICEmail;              break;
+    case eICString_MailAccount:        outICKey = kICMailAccount;        break;
+    case eICString_MailPassword:       outICKey = kICMailPassword;       break;
+    case eICString_NewMailSoundName:   outICKey = kICNewMailSoundName;   break;
+    case eICString_NNTPHost:           outICKey = kICNNTPHost;           break;
+    case eICString_NewsAuthUsername:   outICKey = kICNewsAuthUsername;   break;
+    case eICString_NewsAuthPassword:   outICKey = kICNewsAuthPassword;   break;
+    case eICString_InfoMacPreferred:   outICKey = kICInfoMacPreferred;   break;
+    case eICString_Organization:       outICKey = kICOrganization;       break;
+    case eICString_QuotingString:      outICKey = kICQuotingString;      break;
+    case eICString_RealName:           outICKey = kICRealName;           break;
+    case eICString_FingerHost:         outICKey = kICFingerHost;         break;
+    case eICString_GopherHost:         outICKey = kICGopherHost;         break;
+    case eICString_GopherProxy:        outICKey = kICGopherProxy;        break;
+    case eICString_SocksHost:          outICKey = kICSocksHost;          break;
+    case eICString_TelnetHost:         outICKey = kICTelnetHost;         break;
+    case eICString_IRCHost:            outICKey = kICIRCHost;            break;
+    case eICString_UMichPreferred:     outICKey = kICUMichPreferred;     break;
+    case eICString_WAISGateway:        outICKey = kICWAISGateway;        break;
+    case eICString_WhoisHost:          outICKey = kICWhoisHost;          break;
+    case eICString_PhHost:             outICKey = kICPhHost;             break;
+    case eICString_NTPHost:            outICKey = kICNTPHost;            break;
+    case eICString_ArchiePreferred:    outICKey = kICArchiePreferred;    break;
+    
+    case eICText_MailHeaders:          outICKey = kICMailHeaders;        break;
+    case eICText_Signature:            outICKey = kICSignature;          break;
+    case eICText_NewsHeaders:          outICKey = kICNewsHeaders;        break;
+    case eICText_SnailMailAddress:     outICKey = kICSnailMailAddress;   break;
+    case eICText_Plan:                 outICKey = kICPlan;               break;
+
+    default:
+      rv = NS_ERROR_INVALID_ARG;
+  }
+  return rv;
+}
+
+
+nsresult nsInternetConfigService::GetICPreference(PRUint32 inKey, 
+                                                  void *outData, long *ioSize)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  const unsigned char *icKey;
+  nsresult  rv = GetICKeyPascalString(inKey, icKey);
+  if (rv == NS_OK)
+  {
+    ICInstance  instance = nsInternetConfig::GetInstance();
+    if (instance)
+    {
+      OSStatus  err;
+      ICAttr    junk;
+      err = ::ICGetPref(instance, icKey, &junk, outData, ioSize);
+      if (err != noErr)
+        rv = NS_ERROR_UNEXPECTED;
+    }
+    else
+      rv = NS_ERROR_FAILURE;
+  }
+  return rv;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetString(PRUint32 inKey, nsACString& value)
+{
+  long      size = 256;
+  char      buffer[256];
+  nsresult  rv = GetICPreference(inKey, (void *)&buffer, &size);
+  if (rv == NS_OK)
+  {
+    if (size == 0)
+    {
+      value = "";
+      rv = NS_ERROR_UNEXPECTED;
+    }
+    else
+    { // Buffer is a Pascal string so adjust for length byte when assigning
+      value.Assign(&buffer[1], (unsigned char)buffer[0]);
+    }
+  }
+  return rv;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetColor(PRUint32 inKey, PRUint32 *outColor)
+{
+// We're 'borrowing' this macro from nscolor.h so that uriloader doesn't depend on gfx.
+// Make a color out of r,g,b values. This assumes that the r,g,b values are
+// properly constrained to 0-255. This also assumes that a is 255.
+
+  #define MAKE_NS_RGB(_r,_g,_b) \
+    ((PRUint32) ((255 << 24) | ((_b)<<16) | ((_g)<<8) | (_r)))
+
+  RGBColor  buffer;
+  long      size = sizeof(RGBColor);
+  nsresult  rv = GetICPreference(inKey, &buffer, &size);
+  if (rv == NS_OK)
+  {
+    if (size != sizeof(RGBColor))
+    { // default to white if we didn't get the right size
+      *outColor = MAKE_NS_RGB(0xff, 0xff, 0xff);
+    }
+    else
+    { // convert to a web color
+      *outColor = MAKE_NS_RGB(buffer.red >> 8, buffer.green >> 8, buffer.blue >> 8);
+    }
+  }
+  return rv;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetBoolean(PRUint32 inKey, PRBool *outFlag)
+{
+  Boolean   buffer;
+  long      size = sizeof(Boolean);
+  nsresult  rv = GetICPreference(inKey, (void *)&buffer, &size);
+  if (rv == NS_OK)
+  {
+    if ((size_t)size < sizeof(Boolean))
+      *outFlag = PR_FALSE;  // default to false if we didn't get the right amount of data
+    else
+      *outFlag = buffer;
+  }
+  return rv;
+}
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.mm
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.mm
@@ -41,16 +41,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #import <Carbon/Carbon.h>
 
 #include "nsObjCExceptions.h"
 #include "nsMIMEInfoMac.h"
 #include "nsILocalFileMac.h"
 #include "nsIFileURL.h"
+#include "nsIInternetConfigService.h"
 
 // We override this to make sure app bundles display their pretty name (without .app suffix)
 NS_IMETHODIMP nsMIMEInfoMac::GetDefaultDescription(nsAString& aDefaultDescription)
 {
   if (mDefaultApplication) {
     nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(mDefaultApplication);
     if (macFile) {
       PRBool isPackage;
@@ -118,34 +119,21 @@ nsMIMEInfoMac::LaunchWithFile(nsIFile *a
   return app->LaunchWithDoc(localFile, PR_FALSE);
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsresult 
 nsMIMEInfoMac::LoadUriInternal(nsIURI *aURI)
 {
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
-
   NS_ENSURE_ARG_POINTER(aURI);
-
   nsresult rv = NS_ERROR_FAILURE;
-
+  
   nsCAutoString uri;
-  aURI->GetSpec(uri);
+  aURI->GetAsciiSpec(uri);
   if (!uri.IsEmpty()) {
-    CFURLRef myURLRef = ::CFURLCreateWithBytes(kCFAllocatorDefault,
-                                               (const UInt8*)uri.get(),
-                                               strlen(uri.get()),
-                                               kCFStringEncodingUTF8,
-                                               NULL);
-    if (myURLRef) {
-      OSStatus status = ::LSOpenCFURLRef(myURLRef, NULL);
-      if (status == noErr)
-        rv = NS_OK;
-      ::CFRelease(myURLRef);
-    }
+    nsCOMPtr<nsIInternetConfigService> icService = 
+      do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID);
+    if (icService)
+      rv = icService->LaunchURL(uri.get());
   }
-
   return rv;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
--- a/uriloader/exthandler/mac/nsOSHelperAppService.h
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.h
@@ -69,11 +69,15 @@ public:
   // GetFileTokenForPath must be implemented by each platform. 
   // platformAppPath --> a platform specific path to an application that we got out of the 
   //                     rdf data source. This can be a mac file spec, a unix path or a windows path depending on the platform
   // aFile --> an nsIFile representation of that platform application path.
   virtual nsresult GetFileTokenForPath(const PRUnichar * platformAppPath, nsIFile ** aFile);
 
   nsresult OSProtocolHandlerExists(const char * aScheme,
                                    PRBool * aHandlerExists);
+
+protected:
+  // add any mac specific service state here
+  void UpdateCreatorInfo(nsIMIMEInfo * aMIMEInfo);
 };
 
 #endif // nsOSHelperAppService_h__
--- a/uriloader/exthandler/mac/nsOSHelperAppService.mm
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.mm
@@ -49,71 +49,64 @@
 #include "nsILocalFile.h"
 #include "nsILocalFileMac.h"
 #include "nsMimeTypes.h"
 #include "nsIStringBundle.h"
 #include "nsIPromptService.h"
 #include "nsMemory.h"
 #include "nsCRT.h"
 #include "nsMIMEInfoMac.h"
+#include "nsIInternetConfigService.h"
 #include "nsEmbedCID.h"
 
 #import <Carbon/Carbon.h>
 
 // chrome URL's
 #define HELPERAPPLAUNCHER_BUNDLE_URL "chrome://global/locale/helperAppLauncher.properties"
 #define BRAND_BUNDLE_URL "chrome://branding/locale/brand.properties"
 
 extern "C" {
   // Returns the CFURL for application currently set as the default opener for
   // the given URL scheme. appURL must be released by the caller.
   extern OSStatus _LSCopyDefaultSchemeHandlerURL(CFStringRef scheme,
                                                  CFURLRef *appURL);
 }
 
-/* This is an undocumented interface (in the Foundation framework) that has
- * been stable since at least 10.2.8 and is still present on SnowLeopard.
- * Furthermore WebKit has three public methods (in WebKitSystemInterface.h)
- * that are thin wrappers around this interface's last three methods.  So
- * it's unlikely to change anytime soon.  Now that we're no longer using
- * Internet Config Services, this is the only way to look up a MIME type
- * from an extension, or vice versa.
- */
-@class NSURLFileTypeMappingsInternal;
-
-@interface NSURLFileTypeMappings : NSObject
-{
-    NSURLFileTypeMappingsInternal *_internal;
-}
-
-+ (NSURLFileTypeMappings*)sharedMappings;
-- (NSString*)MIMETypeForExtension:(NSString*)aString;
-- (NSString*)preferredExtensionForMIMEType:(NSString*)aString;
-- (NSArray*)extensionsForMIMEType:(NSString*)aString;
-@end
-
 nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService()
 {
 }
 
 nsOSHelperAppService::~nsOSHelperAppService()
 {}
 
 nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists)
 {
-  CFStringRef schemeString = ::CFStringCreateWithBytes(kCFAllocatorDefault,
-                                                       (const UInt8*)aProtocolScheme,
-                                                       strlen(aProtocolScheme),
-                                                       kCFStringEncodingUTF8,
-                                                       false);
-  CFStringRef handlerString = ::LSCopyDefaultHandlerForURLScheme(schemeString);
-  *aHandlerExists = !!handlerString;
-  ::CFRelease(handlerString);
-  ::CFRelease(schemeString);
-  return NS_OK;
+  // look up the protocol scheme in Internet Config....if we find a match then we have a handler for it...
+  *aHandlerExists = PR_FALSE;
+  // ask the internet config service to look it up for us...
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+  if (icService)
+  {
+    rv = icService->HasProtocolHandler(aProtocolScheme, aHandlerExists);
+    if (rv == NS_ERROR_NOT_AVAILABLE)
+    {
+      // There is a protocol handler, but it's the current app!  We can't let
+      // the current app handle the protocol, as that'll get us into an infinite
+      // loop, so we just pretend there's no protocol handler available.
+      *aHandlerExists = PR_FALSE;
+      rv = NS_OK;
+
+      // FIXME: instead of pretending there's no protocol handler available,
+      // let the caller know about the loop so it can deal with the problem
+      // (i.e. either fix it automatically, if there's some way to do that,
+      // or just provide the user with options for fixing it manually).
+    }
+  }
+  return rv;
 }
 
 NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsresult rv = NS_ERROR_NOT_AVAILABLE;
 
@@ -212,180 +205,133 @@ nsresult nsOSHelperAppService::GetFileTo
     return rv;
   *aFile = localFile;
   NS_IF_ADDREF(*aFile);
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
+///////////////////////////
+// method overrides --> use internet config information for mime type lookup.
+///////////////////////////
 
 NS_IMETHODIMP nsOSHelperAppService::GetFromTypeAndExtension(const nsACString& aType, const nsACString& aFileExt, nsIMIMEInfo ** aMIMEInfo)
 {
-  return nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo);
+  // first, ask our base class....
+  nsresult rv = nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo);
+  if (NS_SUCCEEDED(rv) && *aMIMEInfo) 
+  {
+    UpdateCreatorInfo(*aMIMEInfo);
+  }
+  return rv;
 }
 
-// aMIMEType and aFileExt might not match,  This method's documentation (in
-// nsExternalHelperAppService.h) says that the MIME type is given preference.
 already_AddRefed<nsIMIMEInfo>
 nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
                                         const nsACString& aFileExt,
                                         PRBool * aFound)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSNULL;
 
-  *aFound = PR_FALSE;
+  nsIMIMEInfo* mimeInfo = nsnull;
+  *aFound = PR_TRUE;
 
   const nsCString& flatType = PromiseFlatCString(aMIMEType);
   const nsCString& flatExt = PromiseFlatCString(aFileExt);
 
-  PR_LOG(mLog, PR_LOG_DEBUG, ("Mac: HelperAppService lookup for type '%s' ext '%s'\n",
-                              flatType.get(), flatExt.get()));
-
-  // Create a Mac-specific MIME info so we can use Mac-specific members.
-  nsMIMEInfoMac* mimeInfoMac = new nsMIMEInfoMac(aMIMEType);
-  if (!mimeInfoMac)
-    return nsnull;
-  NS_ADDREF(mimeInfoMac);
+  // ask the internet config service to look it up for us...
+  nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+  PR_LOG(mLog, PR_LOG_DEBUG, ("Mac: HelperAppService lookup for type '%s' ext '%s' (IC: 0x%p)\n",
+                              flatType.get(), flatExt.get(), icService.get()));
+  if (icService)
+  {
+    nsCOMPtr<nsIMIMEInfo> miByType, miByExt;
+    if (!aMIMEType.IsEmpty())
+      icService->FillInMIMEInfo(flatType.get(), flatExt.get(), getter_AddRefs(miByType));
 
-  OSStatus err;
-  PRBool haveAppForType = PR_FALSE;
-  PRBool haveAppForExt = PR_FALSE;
-  PRBool typeAppIsDefault = PR_FALSE;
-  PRBool extAppIsDefault = PR_FALSE;
-  FSRef typeAppFSRef;
-  FSRef extAppFSRef;
+    PRBool hasDefault = PR_FALSE;
+    if (miByType)
+      miByType->GetHasDefaultHandler(&hasDefault);
 
-  if (!aMIMEType.IsEmpty()) {
-    CFURLRef appURL = NULL;
-    CFStringRef CFType = ::CFStringCreateWithCString(NULL, flatType.get(), kCFStringEncodingUTF8);
-    err = ::LSCopyApplicationForMIMEType(CFType, kLSRolesAll, &appURL);
-    if ((err == noErr) && appURL && ::CFURLGetFSRef(appURL, &typeAppFSRef)) {
-      haveAppForType = PR_TRUE;
-      PR_LOG(mLog, PR_LOG_DEBUG, ("LSCopyApplicationForMIMEType found a default application\n"));
+    if (!aFileExt.IsEmpty() && (!hasDefault || !miByType)) {
+      icService->GetMIMEInfoFromExtension(flatExt.get(), getter_AddRefs(miByExt));
+      if (miByExt && !aMIMEType.IsEmpty()) {
+        // XXX see XXX comment below
+        nsIMIMEInfo* pByExt = miByExt.get();
+        nsMIMEInfoBase* byExt = static_cast<nsMIMEInfoBase*>(pByExt);
+        byExt->SetMIMEType(aMIMEType);
+      }
     }
-    if (appURL)
-      ::CFRelease(appURL);
-    ::CFRelease(CFType);
-  }
-  if (!aFileExt.IsEmpty()) {
-    CFStringRef CFExt = ::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8);
-    err = ::LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFExt,
-                                    kLSRolesAll, &extAppFSRef, nsnull);
-    if (err == noErr) {
-      haveAppForExt = PR_TRUE;
-      PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo found a default application\n"));
-    }
-  }
+    PR_LOG(mLog, PR_LOG_DEBUG, ("OS gave us: By Type: 0x%p By Ext: 0x%p type has default: %s\n",
+                                miByType.get(), miByExt.get(), hasDefault ? "true" : "false"));
 
-  if (haveAppForType && haveAppForExt) {
-    typeAppIsDefault = PR_TRUE;
-    // Only add the extension if aMIMEType and aFileExt match.
-    if (::FSCompareFSRefs((const FSRef *) &typeAppFSRef, (const FSRef *) &extAppFSRef) == noErr)
-      mimeInfoMac->AppendExtension(aFileExt);
-    *aFound = PR_TRUE;
-  } else if (haveAppForType) {
-    typeAppIsDefault = PR_TRUE;
-    *aFound = PR_TRUE;
-  } else if (haveAppForExt) {
-    extAppIsDefault = PR_TRUE;
-    mimeInfoMac->AppendExtension(aFileExt);
-    *aFound = PR_TRUE;
+    // If we got two matches, and the type has no default app, copy default app
+    if (!hasDefault && miByType && miByExt) {
+      // IC currently always uses nsMIMEInfoBase-derived classes.
+      // When it stops doing that, this code will need changing.
+      // XXX This assumes that IC will give os an nsMIMEInfoBase. I'd use
+      // dynamic_cast but that crashes.
+      // XXX these pBy* variables are needed because .get() returns an
+      // nsDerivedSafe thingy that can't be cast to nsMIMEInfoBase*
+      nsIMIMEInfo* pByType = miByType.get();
+      nsIMIMEInfo* pByExt = miByExt.get();
+      nsMIMEInfoBase* byType = static_cast<nsMIMEInfoBase*>(pByType);
+      nsMIMEInfoBase* byExt = static_cast<nsMIMEInfoBase*>(pByExt);
+      if (!byType || !byExt) {
+        NS_ERROR("IC gave us an nsIMIMEInfo that's no nsMIMEInfoBase! Fix nsOSHelperAppService.");
+        return nsnull;
+      }
+      // Copy the attributes of miByType onto miByExt
+      byType->CopyBasicDataTo(byExt);
+      miByType = miByExt;
+    }
+    if (miByType)
+      miByType.swap(mimeInfo);
+    else if (miByExt)
+      miByExt.swap(mimeInfo);
   }
 
-  if (aMIMEType.IsEmpty()) {
-    if (haveAppForExt) {
-      // If aMIMEType is empty and we've found a default app for aFileExt, try
-      // to get the MIME type from aFileExt.  (It might also be worth doing
-      // this when aMIMEType isn't empty but haveAppForType is false -- but
-      // the doc for this method says that if we have a MIME type (in
-      // aMIMEType), we need to give it preference.)
-      NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings];
-      NSString *extStr = [NSString stringWithCString:flatExt.get() encoding:NSASCIIStringEncoding];
-      NSString *typeStr = map ? [map MIMETypeForExtension:extStr] : NULL;
-      if (typeStr) {
-        nsCAutoString mimeType;
-        mimeType.Assign((char *)[typeStr cStringUsingEncoding:NSASCIIStringEncoding]);
-        mimeInfoMac->SetMIMEType(mimeType);
+  if (!mimeInfo) {
+    *aFound = PR_FALSE;
+    PR_LOG(mLog, PR_LOG_DEBUG, ("Creating new mimeinfo\n"));
+    // Create a Mac-specific MIME info so we can use Mac-specific members.
+    nsMIMEInfoMac* mimeInfoMac = new nsMIMEInfoMac(aMIMEType);
+    if (!mimeInfoMac)
+      return nsnull;
+    NS_ADDREF(mimeInfoMac);
+
+    if (!aFileExt.IsEmpty())
+      mimeInfoMac->AppendExtension(aFileExt);
+
+    // Now see if Launch Services knows of an application that should be run for this type.
+    OSStatus err;
+    FSRef appFSRef;
+    CFStringRef CFExt = ::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8);
+    err = ::LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFExt,
+                                    kLSRolesAll, &appFSRef, nsnull);
+    if (err == noErr) {
+      nsCOMPtr<nsILocalFileMac> app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+      if (!app) {
+        ::CFRelease(CFExt);
+        NS_RELEASE(mimeInfoMac);
+        return nsnull;
       }
+      app->InitWithFSRef(&appFSRef);
+      mimeInfoMac->SetDefaultApplication(app);
+      PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo found a default application\n"));
     } else {
-      // Otherwise set the MIME type to a reasonable fallback.
-      mimeInfoMac->SetMIMEType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
-    }
-  }
-
-  if (typeAppIsDefault || extAppIsDefault) {
-    nsCOMPtr<nsILocalFileMac> app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
-    if (!app) {
-      NS_RELEASE(mimeInfoMac);
-      return nsnull;
-    }
-
-    CFStringRef CFAppName = NULL;
-    if (typeAppIsDefault) {
-      app->InitWithFSRef(&typeAppFSRef);
-      ::LSCopyItemAttribute((const FSRef *) &typeAppFSRef, kLSRolesAll,
-                            kLSItemDisplayName, (CFTypeRef *) &CFAppName);
-    } else {
-      app->InitWithFSRef(&extAppFSRef);
-      ::LSCopyItemAttribute((const FSRef *) &extAppFSRef, kLSRolesAll,
-                            kLSItemDisplayName, (CFTypeRef *) &CFAppName);
+      // Just leave the default application unset.
+      PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo returned error code %d; default application was not set\n", err));
     }
-    if (CFAppName) {
-      nsAutoTArray<UniChar, 255> buffer;
-      CFIndex appNameLength = ::CFStringGetLength(CFAppName);
-      buffer.SetLength(appNameLength);
-      ::CFStringGetCharacters(CFAppName, CFRangeMake(0, appNameLength),
-                              buffer.Elements());
-      nsAutoString appName;
-      appName.Assign(buffer.Elements(), appNameLength);
-      mimeInfoMac->SetDefaultDescription(appName);
-      ::CFRelease(CFAppName);
-    }
-
-    mimeInfoMac->SetDefaultApplication(app);
-    mimeInfoMac->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
-  } else {
-    mimeInfoMac->SetPreferredAction(nsIMIMEInfo::saveToDisk);
+    mimeInfo = mimeInfoMac;
+    ::CFRelease(CFExt);
   }
-
-  nsCAutoString mimeType;
-  mimeInfoMac->GetMIMEType(mimeType);
-  if (!mimeType.IsEmpty()) {
-    // If we have a MIME type, make sure its preferred extension is included
-    // in our list.
-    NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings];
-    NSString *typeStr = [NSString stringWithCString:mimeType.get() encoding:NSASCIIStringEncoding];
-    NSString *extStr = map ? [map preferredExtensionForMIMEType:typeStr] : NULL;
-    if (extStr) {
-      nsCAutoString preferredExt;
-      preferredExt.Assign((char *)[extStr cStringUsingEncoding:NSASCIIStringEncoding]);
-      mimeInfoMac->AppendExtension(preferredExt);
-    }
-
-    CFStringRef CFType = ::CFStringCreateWithCString(NULL, mimeType.get(), kCFStringEncodingUTF8);
-    CFStringRef CFTypeDesc = NULL;
-    if (::LSCopyKindStringForMIMEType(CFType, &CFTypeDesc) == noErr) {
-      nsAutoTArray<UniChar, 255> buffer;
-      CFIndex typeDescLength = ::CFStringGetLength(CFTypeDesc);
-      buffer.SetLength(typeDescLength);
-      ::CFStringGetCharacters(CFTypeDesc, CFRangeMake(0, typeDescLength),
-                              buffer.Elements());
-      nsAutoString typeDesc;
-      typeDesc.Assign(buffer.Elements(), typeDescLength);
-      mimeInfoMac->SetDescription(typeDesc);
-    }
-    if (CFTypeDesc)
-      ::CFRelease(CFTypeDesc);
-    ::CFRelease(CFType);
-  }
-
-  PR_LOG(mLog, PR_LOG_DEBUG, ("OS gave us: type '%s' found '%i'\n", mimeType.get(), *aFound));
-
-  return mimeInfoMac;
+  
+  return mimeInfo;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL;
 }
 
 NS_IMETHODIMP
 nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aScheme,
                                                    PRBool *found,
                                                    nsIHandlerInfo **_retval)
@@ -409,8 +355,38 @@ nsOSHelperAppService::GetProtocolHandler
   }
 
   nsAutoString desc;
   GetApplicationDescription(aScheme, desc);
   handlerInfo->SetDefaultDescription(desc);
 
   return NS_OK;
 }
+
+// we never want to use a hard coded value for the creator and file type for the mac. always look these values up
+// from internet config.
+void nsOSHelperAppService::UpdateCreatorInfo(nsIMIMEInfo * aMIMEInfo)
+{
+  PRUint32 macCreatorType;
+  PRUint32 macFileType;
+  aMIMEInfo->GetMacType(&macFileType);
+  aMIMEInfo->GetMacCreator(&macCreatorType);
+  
+  if (macFileType == 0 || macCreatorType == 0)
+  {
+    // okay these values haven't been initialized yet so fetch a mime object from internet config.
+    nsCAutoString mimeType;
+    aMIMEInfo->GetMIMEType(mimeType);
+    nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+    if (icService)
+    {
+      nsCOMPtr<nsIMIMEInfo> osMimeObject;
+      icService->FillInMIMEInfo(mimeType.get(), nsnull, getter_AddRefs(osMimeObject));
+      if (osMimeObject)
+      {
+        osMimeObject->GetMacType(&macFileType);
+        osMimeObject->GetMacCreator(&macCreatorType);
+        aMIMEInfo->SetMacCreator(macCreatorType);
+        aMIMEInfo->SetMacType(macFileType);
+      } // if we got an os object
+    } // if we got the ic service
+  } // if the creator or file type hasn't been initialized yet
+} 
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -87,16 +87,17 @@
 #include "nsIEncodedChannel.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIFileChannel.h"
 #include "nsIObserverService.h" // so we can be a profile change observer
 #include "nsIPropertyBag2.h" // for the 64-bit content length
 
 #ifdef XP_MACOSX
 #include "nsILocalFileMac.h"
+#include "nsIInternetConfigService.h"
 #ifndef __LP64__
 #include "nsIAppleFileDecoder.h"
 #endif
 #elif defined(XP_OS2)
 #include "nsILocalFileOS2.h"
 #endif
 
 #include "nsIPluginHost.h" // XXX needed for ext->type mapping (bug 233289)
@@ -486,16 +487,18 @@ static nsDefaultMimeTypeEntry defaultMim
 /**
  * This is a small private struct used to help us initialize some
  * default mime types.
  */
 struct nsExtraMimeTypeEntry {
   const char* mMimeType; 
   const char* mFileExtensions;
   const char* mDescription;
+  PRUint32 mMactype;
+  PRUint32 mMacCreator;
 };
 
 #ifdef XP_MACOSX
 #define MAC_TYPE(x) x
 #else
 #define MAC_TYPE(x) 0
 #endif
 
@@ -504,49 +507,49 @@ struct nsExtraMimeTypeEntry {
  * file extensions.  These entries also ensure that we provide a good descriptive name
  * when we encounter files with these content types and/or extensions.  These can be
  * overridden by user helper app prefs.
  * If you add types here, make sure they are lowercase, or you'll regret it.
  */
 static nsExtraMimeTypeEntry extraMimeEntries [] =
 {
 #if defined(VMS)
-  { APPLICATION_OCTET_STREAM, "exe,com,bin,sav,bck,pcsi,dcx_axpexe,dcx_vaxexe,sfx_axpexe,sfx_vaxexe", "Binary File" },
+  { APPLICATION_OCTET_STREAM, "exe,com,bin,sav,bck,pcsi,dcx_axpexe,dcx_vaxexe,sfx_axpexe,sfx_vaxexe", "Binary File", 0, 0 },
 #elif defined(XP_MACOSX) // don't define .bin on the mac...use internet config to look that up...
-  { APPLICATION_OCTET_STREAM, "exe,com", "Binary File" },
+  { APPLICATION_OCTET_STREAM, "exe,com", "Binary File", 0, 0 },
 #else
-  { APPLICATION_OCTET_STREAM, "exe,com,bin", "Binary File" },
+  { APPLICATION_OCTET_STREAM, "exe,com,bin", "Binary File", 0, 0 },
 #endif
-  { APPLICATION_GZIP2, "gz", "gzip" },
-  { "application/x-arj", "arj", "ARJ file" },
-  { APPLICATION_XPINSTALL, "xpi", "XPInstall Install" },
-  { APPLICATION_POSTSCRIPT, "ps,eps,ai", "Postscript File" },
-  { APPLICATION_JAVASCRIPT, "js", "Javascript Source File" },
-  { IMAGE_ART, "art", "ART Image" },
-  { IMAGE_BMP, "bmp", "BMP Image" },
-  { IMAGE_GIF, "gif", "GIF Image" },
-  { IMAGE_ICO, "ico,cur", "ICO Image" },
-  { IMAGE_JPG, "jpeg,jpg,jfif,pjpeg,pjp", "JPEG Image" },
-  { IMAGE_PNG, "png", "PNG Image" },
-  { IMAGE_TIFF, "tiff,tif", "TIFF Image" },
-  { IMAGE_XBM, "xbm", "XBM Image" },
-  { "image/svg+xml", "svg", "Scalable Vector Graphics" },
-  { MESSAGE_RFC822, "eml", "RFC-822 data" },
-  { TEXT_PLAIN, "txt,text", "Text File" },
-  { TEXT_HTML, "html,htm,shtml,ehtml", "HyperText Markup Language" },
-  { "application/xhtml+xml", "xhtml,xht", "Extensible HyperText Markup Language" },
-  { APPLICATION_RDF, "rdf", "Resource Description Framework" },
-  { TEXT_XUL, "xul", "XML-Based User Interface Language" },
-  { TEXT_XML, "xml,xsl,xbl", "Extensible Markup Language" },
-  { TEXT_CSS, "css", "Style Sheet" },
-  { VIDEO_OGG, "ogv", "Ogg Video" },
-  { VIDEO_OGG, "ogg", "Ogg Video" },
-  { APPLICATION_OGG, "ogg", "Ogg Video"},
-  { AUDIO_OGG, "oga", "Ogg Audio" },
-  { AUDIO_WAV, "wav", "Waveform Audio" }
+  { APPLICATION_GZIP2, "gz", "gzip", 0, 0 },
+  { "application/x-arj", "arj", "ARJ file", 0,0 },
+  { APPLICATION_XPINSTALL, "xpi", "XPInstall Install", MAC_TYPE('xpi*'), MAC_TYPE('MOSS') },
+  { APPLICATION_POSTSCRIPT, "ps,eps,ai", "Postscript File", 0, 0 },
+  { APPLICATION_JAVASCRIPT, "js", "Javascript Source File", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+  { IMAGE_ART, "art", "ART Image", 0, 0 },
+  { IMAGE_BMP, "bmp", "BMP Image", 0, 0 },
+  { IMAGE_GIF, "gif", "GIF Image", 0,0 },
+  { IMAGE_ICO, "ico,cur", "ICO Image", 0, 0 },
+  { IMAGE_JPG, "jpeg,jpg,jfif,pjpeg,pjp", "JPEG Image", 0, 0 },
+  { IMAGE_PNG, "png", "PNG Image", 0, 0 },
+  { IMAGE_TIFF, "tiff,tif", "TIFF Image", 0, 0 },
+  { IMAGE_XBM, "xbm", "XBM Image", 0, 0 },
+  { "image/svg+xml", "svg", "Scalable Vector Graphics", MAC_TYPE('svg '), MAC_TYPE('ttxt') },
+  { MESSAGE_RFC822, "eml", "RFC-822 data", MAC_TYPE('TEXT'), MAC_TYPE('MOSS') },
+  { TEXT_PLAIN, "txt,text", "Text File", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+  { TEXT_HTML, "html,htm,shtml,ehtml", "HyperText Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('MOSS') },
+  { "application/xhtml+xml", "xhtml,xht", "Extensible HyperText Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+  { APPLICATION_RDF, "rdf", "Resource Description Framework", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+  { TEXT_XUL, "xul", "XML-Based User Interface Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+  { TEXT_XML, "xml,xsl,xbl", "Extensible Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+  { TEXT_CSS, "css", "Style Sheet", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+  { VIDEO_OGG, "ogv", "Ogg Video", 0, 0 },
+  { VIDEO_OGG, "ogg", "Ogg Video", 0, 0 },
+  { APPLICATION_OGG, "ogg", "Ogg Video", 0, 0},
+  { AUDIO_OGG, "oga", "Ogg Audio", 0, 0 },
+  { AUDIO_WAV, "wav", "Waveform Audio", 0, 0 }
 };
 
 #undef MAC_TYPE
 
 /**
  * File extensions for which decoding should be disabled.
  * NOTE: These MUST be lower-case and ASCII.
  */
@@ -1354,16 +1357,29 @@ nsresult nsExternalAppHandler::SetUpTemp
   NS_ENSURE_SUCCESS(rv, rv);
 
 #ifndef XP_WIN
   // On other platforms, the file permission bits are used, so we can just call
   // IsExecutable
   mTempFile->IsExecutable(&mTempFileIsExecutable);
 #endif
 
+#ifdef XP_MACOSX
+  // Now that the file exists set Mac type if the file has no extension
+  // and we can determine a type.
+  if (ext.IsEmpty() && mMimeInfo) {
+    nsCOMPtr<nsILocalFileMac> macfile = do_QueryInterface(mTempFile);
+    if (macfile) {
+      PRUint32 type;
+      mMimeInfo->GetMacType(&type);
+      macfile->SetFileType(type);
+    }
+  }
+#endif
+
   nsCOMPtr<nsIOutputStream> outputStream;
   rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTempFile,
                                    PR_WRONLY | PR_CREATE_FILE, 0600);
   if (NS_FAILED(rv)) {
     mTempFile->Remove(PR_FALSE);
     return rv;
   }
 
@@ -2674,20 +2690,38 @@ NS_IMETHODIMP nsExternalHelperAppService
     {
       if (fileName[i] == PRUnichar('.'))
       {
         CopyUTF16toUTF8(fileName.get() + i + 1, fileExt);
         break;
       }
     }
   }
+  
+#ifdef XP_MACOSX
+  nsCOMPtr<nsILocalFileMac> macFile;
+  macFile = do_QueryInterface( aFile, &rv );
+  if (NS_SUCCEEDED( rv ) && fileExt.IsEmpty())
+  {
+    PRUint32 type, creator;
+    macFile->GetFileType( (OSType*)&type );
+    macFile->GetFileCreator( (OSType*)&creator );   
+    nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+    if (icService)
+    {
+      rv = icService->GetMIMEInfoFromTypeCreator(type, creator, fileExt.get(), getter_AddRefs(info));
+      if (NS_SUCCEEDED(rv))
+        return info->GetMIMEType(aContentType);
+    }
+  }
+#endif
 
+  // Windows, unix and mac when no type match occured.   
   if (fileExt.IsEmpty())
-    return NS_ERROR_FAILURE;
-
+    return NS_ERROR_FAILURE;    
   return GetTypeFromExtension(fileExt, aContentType);
 }
 
 nsresult nsExternalHelperAppService::FillMIMEInfoForMimeTypeFromExtras(
   const nsACString& aContentType, nsIMIMEInfo * aMIMEInfo)
 {
   NS_ENSURE_ARG( aMIMEInfo );
 
@@ -2699,16 +2733,19 @@ nsresult nsExternalHelperAppService::Fil
   PRInt32 numEntries = NS_ARRAY_LENGTH(extraMimeEntries);
   for (PRInt32 index = 0; index < numEntries; index++)
   {
       if ( MIMEType.Equals(extraMimeEntries[index].mMimeType) )
       {
           // This is the one. Set attributes appropriately.
           aMIMEInfo->SetFileExtensions(nsDependentCString(extraMimeEntries[index].mFileExtensions));
           aMIMEInfo->SetDescription(NS_ConvertASCIItoUTF16(extraMimeEntries[index].mDescription));
+          aMIMEInfo->SetMacType(extraMimeEntries[index].mMactype);
+          aMIMEInfo->SetMacCreator(extraMimeEntries[index].mMacCreator);
+
           return NS_OK;
       }
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 nsresult nsExternalHelperAppService::FillMIMEInfoForExtensionFromExtras(
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsIInternetConfigService.idl
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsISupports.idl"
+
+interface nsIMIMEInfo;
+interface nsIURL;
+
+%{C++
+
+#include <Carbon/Carbon.h>
+
+#define NS_INTERNETCONFIGSERVICE_CONTRACTID \
+"@mozilla.org/mac/internet-config-service;1"
+
+%}
+
+native FSSpec(FSSpec);
+[ptr] native FSSpecPtr(FSSpec);
+
+[scriptable, uuid(38C37AA2-9F74-4B24-A70C-AC3AE4308210)]
+interface nsIInternetConfigService : nsISupports
+{
+  const unsigned long eICColor_WebBackgroundColour = 1;
+  const unsigned long eICColor_WebReadColor = 2;
+  const unsigned long eICColor_WebTextColor = 3;
+  const unsigned long eICColor_WebUnreadColor = 4;
+  const unsigned long eICBoolean_WebUnderlineLinks = 11;
+  const unsigned long eICString_WWWHomePage = 101;
+  const unsigned long eICString_WebSearchPagePrefs = 102;
+  const unsigned long eICString_MacSearchHost = 103;
+  const unsigned long eICString_FTPHost = 121;
+  const unsigned long eICBoolean_UsePassiveFTP = 122;
+  const unsigned long eICBoolean_UseFTPProxy = 123;      const unsigned long eICString_FTPProxyUser = 124; 
+  const unsigned long eICString_FTPProxyAccount = 125;   const unsigned long eICString_FTPProxyHost = 126;
+  const unsigned long eICString_FTPProxyPassword = 127;
+  const unsigned long eICBoolean_UseHTTPProxy = 130;     const unsigned long eICString_HTTPProxyHost = 131;
+  const unsigned long eICString_LDAPSearchbase = 201;    const unsigned long eICString_LDAPServer = 202;
+  const unsigned long eICString_SMTPHost = 221;
+  const unsigned long eICString_Email = 222;
+  const unsigned long eICString_MailAccount = 223;       const unsigned long eICString_MailPassword = 224;
+  const unsigned long eICText_MailHeaders = 225;         const unsigned long eICText_Signature = 226;
+  const unsigned long eICBoolean_NewMailDialog = 231;
+  const unsigned long eICBoolean_NewMailFlashIcon = 232;
+  const unsigned long eICBoolean_NewMailPlaySound = 233; const unsigned long eICString_NewMailSoundName = 234;
+  const unsigned long eICString_NNTPHost = 241;
+  const unsigned long eICString_NewsAuthUsername = 242;  const unsigned long eICString_NewsAuthPassword = 243;
+  const unsigned long eICText_NewsHeaders = 244;
+  const unsigned long eICString_InfoMacPreferred = 245;
+  const unsigned long eICString_Organization = 251;      const unsigned long eICString_RealName = 252;
+  const unsigned long eICText_SnailMailAddress = 253;
+  const unsigned long eICString_QuotingString = 254;
+  const unsigned long eICString_GopherHost = 301;
+  const unsigned long eICBoolean_UseGopherProxy = 302;   const unsigned long eICString_GopherProxy = 303;
+  const unsigned long eICBoolean_UseSocks = 321;         const unsigned long eICString_SocksHost = 322;
+  const unsigned long eICString_TelnetHost = 331;
+  const unsigned long eICString_IRCHost = 341;
+  const unsigned long eICString_NTPHost = 351;
+  const unsigned long eICString_WAISGateway = 381;
+  const unsigned long eICString_FingerHost = 382;        const unsigned long eICText_Plan = 383;
+  const unsigned long eICString_WhoisHost = 384;
+  const unsigned long eICString_PhHost = 385;
+  const unsigned long eICString_ArchiePreferred = 386;
+  const unsigned long eICString_UMichPreferred = 391;
+
+  const unsigned long eIICMapFlag_BinaryMask            = 1;  /* file should be transfered in binary as opposed to text mode*/
+  const unsigned long eIICMapFlag_ResourceForkMask      = 2;  /* the resource fork of the file is significant*/
+  const unsigned long eIICMapFlag_DataForkMask          = 4;  /* the data fork of the file is significant*/
+  const unsigned long eIICMapFlag_PostMask              = 8;  /* post process using post fields*/
+  const unsigned long eIICMapFlag_NotIncomingMask       = 16; /* ignore this mapping for incoming files*/
+  const unsigned long eIICMapFlag_NotOutgoingMask       = 32; /* ignore this mapping for outgoing files*/
+
+
+  void launchURL(in string url);
+  
+  boolean hasMappingForMIMEType(in string mimetype);
+  
+  boolean hasProtocolHandler(in string protocol);
+  
+  // pass in a mime type or a file extension.....
+  void fillInMIMEInfo(in string mimetype, in string aFileExtension, out nsIMIMEInfo mimeinfo);
+  
+  void getMIMEInfoFromExtension(in string aFileExt, out nsIMIMEInfo mimeinfo);
+  
+  void getMIMEInfoFromTypeCreator(in PRUint32 aType, in PRUint32 aCreator, in string aFileExt, out nsIMIMEInfo mimeInfo);
+
+  ACString getString(in unsigned long keyenum);
+
+  unsigned long getColor(in unsigned long keyenum);
+
+  boolean getBoolean(in unsigned long keyenum);
+};
--- a/uriloader/exthandler/nsMIMEInfoImpl.cpp
+++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp
@@ -58,37 +58,43 @@ NS_INTERFACE_MAP_BEGIN(nsMIMEInfoBase)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMIMEInfo, mClass == eMIMEInfo)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHandlerInfo)
 NS_INTERFACE_MAP_END_THREADSAFE
 
 // nsMIMEInfoImpl methods
 
 // Constructors for a MIME handler.
 nsMIMEInfoBase::nsMIMEInfoBase(const char *aMIMEType) :
+    mMacType(0),
+    mMacCreator(0),
     mType(aMIMEType),
     mClass(eMIMEInfo),
     mPreferredAction(nsIMIMEInfo::saveToDisk),
     mAlwaysAskBeforeHandling(PR_TRUE)
 {
 }
 
 nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aMIMEType) :
+    mMacType(0),
+    mMacCreator(0),
     mType(aMIMEType),
     mClass(eMIMEInfo),
     mPreferredAction(nsIMIMEInfo::saveToDisk),
     mAlwaysAskBeforeHandling(PR_TRUE)
 {
 }
 
 // Constructor for a handler that lets the caller specify whether this is a
 // MIME handler or a protocol handler.  In the long run, these will be distinct
 // classes (f.e. nsMIMEInfo and nsProtocolInfo), but for now we reuse this class
 // for both and distinguish between the two kinds of handlers via the aClass
 // argument to this method, which can be either eMIMEInfo or eProtocolInfo.
 nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aType, HandlerClass aClass) :
+    mMacType(0),
+    mMacCreator(0),
     mType(aType),
     mClass(aClass),
     mPreferredAction(nsIMIMEInfo::saveToDisk),
     mAlwaysAskBeforeHandling(PR_TRUE)
 {
 }
 
 nsMIMEInfoBase::~nsMIMEInfoBase()
@@ -205,16 +211,52 @@ nsMIMEInfoBase::Equals(nsIMIMEInfo *aMIM
     if (NS_FAILED(rv)) return rv;
 
     *_retval = mType.Equals(type);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsMIMEInfoBase::GetMacType(PRUint32 *aMacType)
+{
+    *aMacType = mMacType;
+
+    if (!mMacType)
+        return NS_ERROR_NOT_INITIALIZED;
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoBase::SetMacType(PRUint32 aMacType)
+{
+    mMacType = aMacType;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoBase::GetMacCreator(PRUint32 *aMacCreator)
+{
+    *aMacCreator = mMacCreator;
+
+    if (!mMacCreator)
+        return NS_ERROR_NOT_INITIALIZED;
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoBase::SetMacCreator(PRUint32 aMacCreator)
+{
+    mMacCreator = aMacCreator;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 nsMIMEInfoBase::SetFileExtensions(const nsACString& aExtensions)
 {
     mExtensions.Clear();
     nsCString extList( aExtensions );
     
     PRInt32 breakLocation = -1;
     while ( (breakLocation= extList.FindChar(',') )!= -1)
     {
@@ -366,16 +408,19 @@ nsMIMEInfoBase::LaunchWithURI(nsIURI* aU
 }
 
 void
 nsMIMEInfoBase::CopyBasicDataTo(nsMIMEInfoBase* aOther)
 {
   aOther->mType = mType;
   aOther->mDefaultAppDescription = mDefaultAppDescription;
   aOther->mExtensions = mExtensions;
+
+  aOther->mMacType = mMacType;
+  aOther->mMacCreator = mMacCreator;
 }
 
 /* static */
 nsresult
 nsMIMEInfoBase::LaunchWithIProcess(nsIFile* aApp, const nsCString& aArg)
 {
   NS_ASSERTION(aApp, "Unexpected null pointer, fix caller");
 
--- a/uriloader/exthandler/nsMIMEInfoImpl.h
+++ b/uriloader/exthandler/nsMIMEInfoImpl.h
@@ -74,16 +74,20 @@ class nsMIMEInfoBase : public nsIMIMEInf
     NS_IMETHOD ExtensionExists(const nsACString & aExtension, PRBool *_retval);
     NS_IMETHOD AppendExtension(const nsACString & aExtension);
     NS_IMETHOD GetPrimaryExtension(nsACString & aPrimaryExtension);
     NS_IMETHOD SetPrimaryExtension(const nsACString & aPrimaryExtension);
     NS_IMETHOD GetType(nsACString & aType);
     NS_IMETHOD GetMIMEType(nsACString & aMIMEType);
     NS_IMETHOD GetDescription(nsAString & aDescription);
     NS_IMETHOD SetDescription(const nsAString & aDescription);
+    NS_IMETHOD GetMacType(PRUint32 *aMacType);
+    NS_IMETHOD SetMacType(PRUint32 aMacType);
+    NS_IMETHOD GetMacCreator(PRUint32 *aMacCreator);
+    NS_IMETHOD SetMacCreator(PRUint32 aMacCreator);
     NS_IMETHOD Equals(nsIMIMEInfo *aMIMEInfo, PRBool *_retval);
     NS_IMETHOD GetPreferredApplicationHandler(nsIHandlerApp * *aPreferredAppHandler);
     NS_IMETHOD SetPreferredApplicationHandler(nsIHandlerApp * aPreferredAppHandler);
     NS_IMETHOD GetPossibleApplicationHandlers(nsIMutableArray * *aPossibleAppHandlers);
     NS_IMETHOD GetDefaultDescription(nsAString & aDefaultDescription);
     NS_IMETHOD LaunchWithFile(nsIFile *aFile);
     NS_IMETHOD LaunchWithURI(nsIURI *aURI,
                              nsIInterfaceRequestor *aWindowContext);
@@ -159,16 +163,17 @@ class nsMIMEInfoBase : public nsIMIMEInf
      * @param  aFile     the associated nsILocalFile (out param)
      */
     static NS_HIDDEN_(nsresult) GetLocalFileFromURI(nsIURI *aURI,
                                                     nsILocalFile **aFile);
 
     // member variables
     nsTArray<nsCString>    mExtensions; ///< array of file extensions associated w/ this MIME obj
     nsString               mDescription; ///< human readable description
+    PRUint32               mMacType, mMacCreator; ///< Mac file type and creator
     nsCString              mType;
     HandlerClass           mClass;
     nsCOMPtr<nsIHandlerApp> mPreferredApplication;
     nsCOMPtr<nsIMutableArray> mPossibleApplications;
     nsHandlerInfoAction    mPreferredAction; ///< preferred action to associate with this type
     nsString               mPreferredAppDescription;
     nsString               mDefaultAppDescription;
     PRBool                 mAlwaysAskBeforeHandling;
--- a/widget/src/cocoa/nsLookAndFeel.mm
+++ b/widget/src/cocoa/nsLookAndFeel.mm
@@ -33,16 +33,17 @@
  * 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 ***** */
 
 #include "nsLookAndFeel.h"
 #include "nsObjCExceptions.h"
+#include "nsIInternetConfigService.h"
 #include "nsIServiceManager.h"
 #include "nsNativeThemeColors.h"
 
 #import <Carbon/Carbon.h>
 #import <Cocoa/Cocoa.h>
 
 nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
 {
@@ -61,17 +62,27 @@ static nscolor GetColorFromNSColor(NSCol
 }
 
 nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor)
 {
   nsresult res = NS_OK;
   
   switch (aID) {
     case eColor_WindowBackground:
-      aColor = NS_RGB(0xff,0xff,0xff);
+    {
+      nsCOMPtr<nsIInternetConfigService> icService_wb (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+      if (icService_wb) {
+        res = icService_wb->GetColor(nsIInternetConfigService::eICColor_WebBackgroundColour, &aColor);
+        if (NS_SUCCEEDED(res))
+          return res;
+      }
+      
+      aColor = NS_RGB(0xff,0xff,0xff); // default to white if we didn't find it in internet config
+      res = NS_OK;
+    }
       break;
     case eColor_WindowForeground:
       aColor = NS_RGB(0x00,0x00,0x00);        
       break;
     case eColor_WidgetBackground:
       aColor = NS_RGB(0xdd,0xdd,0xdd);
       break;
     case eColor_WidgetForeground:
@@ -87,18 +98,27 @@ nsresult nsLookAndFeel::NativeGetColor(c
       aColor = NS_RGB(0xa0,0xa0,0xa0);
       break;
     case eColor_Widget3DShadow:
       aColor = NS_RGB(0x40,0x40,0x40);
       break;
     case eColor_TextBackground:
       aColor = NS_RGB(0xff,0xff,0xff);
       break;
-    case eColor_TextForeground:
+    case eColor_TextForeground: 
+    {
+      nsCOMPtr<nsIInternetConfigService> icService_tf (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+      if (icService_tf) {
+        res = icService_tf->GetColor(nsIInternetConfigService::eICColor_WebTextColor, &aColor);
+        if (NS_SUCCEEDED(res))
+          return res;
+      }
       aColor = NS_RGB(0x00,0x00,0x00);
+      res = NS_OK;
+    }
       break;
     case eColor_TextSelectBackground:
       res = GetMacBrushColor(kThemeBrushPrimaryHighlightColor, aColor, NS_RGB(0x00,0x00,0x00));
       break;
     case eColor_highlight: // CSS2 color
       res = GetMacBrushColor(kThemeBrushAlternatePrimaryHighlightColor, aColor, NS_RGB(0x33,0x6F,0xCB));
       break;
     case eColor__moz_menuhover: