Bug 570488 - Stop reading/writing xpti.dat and incrementally loading XPT files [1/2] r=Mossop
authorBenjamin Smedberg <benjamin@smedbergs.us>
Mon, 14 Jun 2010 16:05:48 -0700
changeset 43619 894850aef55c
parent 43618 eb0883ccdb63
child 43620 0def0bbb620d
push id13811
push usermwu@mozilla.com
push date2010-06-15 00:56 +0000
treeherdermozilla-central@91851c94fb73 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs570488
milestone1.9.3a6pre
Bug 570488 - Stop reading/writing xpti.dat and incrementally loading XPT files [1/2] r=Mossop
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsXREDirProvider.cpp
xpcom/Makefile.in
xpcom/build/nsXPComInit.cpp
xpcom/glue/nsBaseHashtable.h
xpcom/io/nsDirectoryService.cpp
xpcom/io/nsDirectoryServiceAtomList.h
xpcom/io/nsDirectoryServiceDefs.h
xpcom/proxy/src/nsProxyObjectManager.cpp
xpcom/reflect/xptcall/src/xptcall.cpp
xpcom/reflect/xptinfo/src/Makefile.in
xpcom/reflect/xptinfo/src/xptiFile.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiManifest.cpp
xpcom/reflect/xptinfo/src/xptiMisc.cpp
xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
xpcom/reflect/xptinfo/src/xptiZipItem.cpp
xpcom/reflect/xptinfo/src/xptiZipLoader.cpp
xpcom/reflect/xptinfo/src/xptiprivate.h
xpcom/tools/Makefile.in
xpcom/tools/registry/Makefile.in
xpcom/tools/registry/regxpcom.cpp
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -2474,19 +2474,16 @@ static void RemoveComponentRegistries(ns
   nsCOMPtr<nsIFile> file;
   aProfileDir->Clone(getter_AddRefs(file));
   if (!file)
     return;
 
   file->AppendNative(NS_LITERAL_CSTRING("compreg.dat"));
   file->Remove(PR_FALSE);
 
-  file->SetNativeLeafName(NS_LITERAL_CSTRING("xpti.dat"));
-  file->Remove(PR_FALSE);
-
   if (aRemoveEMFiles) {
     file->SetNativeLeafName(NS_LITERAL_CSTRING("extensions.ini"));
     file->Remove(PR_FALSE);
   }
 
   aLocalProfileDir->Clone(getter_AddRefs(file));
   if (!file)
     return;
@@ -3322,29 +3319,29 @@ XRE_main(int argc, char* argv[], const n
     //
     if (gSafeMode) {
       RemoveComponentRegistries(profD, profLD, PR_FALSE);
       WriteVersion(profD, NS_LITERAL_CSTRING("Safe Mode"), osABI,
                    dirProvider.GetGREDir(), gAppData->directory);
     }
     else if (versionOK) {
       if (!cachesOK) {
-        // Remove compreg.dat and xpti.dat, forcing component re-registration.
+        // Remove compreg.dat, forcing component re-registration.
         // The new list of additional components directories is derived from
         // information in "extensions.ini".
         RemoveComponentRegistries(profD, profLD, PR_FALSE);
         
         // Rewrite compatibility.ini to remove the flag
         WriteVersion(profD, version, osABI,
                      dirProvider.GetGREDir(), gAppData->directory);
       }
       // Nothing need be done for the normal startup case.
     }
     else {
-      // Remove compreg.dat and xpti.dat, forcing component re-registration
+      // Remove compreg.dat, forcing component re-registration
       // with the default set of components (this disables any potentially
       // troublesome incompatible XPCOM components). 
       RemoveComponentRegistries(profD, profLD, PR_TRUE);
 
       // Tell the Extension Manager it should check for incompatible 
       // Extensions and re-write the "extensions.ini" file with a list of 
       // directories for compatible extensions
       upgraded = PR_TRUE;
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -332,19 +332,16 @@ nsXREDirProvider::GetFile(const char* aP
     return GetSysUserExtensionsDirectory((nsILocalFile**)(nsIFile**) aFile);
   }
   else if (NS_SUCCEEDED(GetProfileStartupDir(getter_AddRefs(file)))) {
     // We need to allow component, xpt, and chrome registration to
     // occur prior to the profile-after-change notification.
     if (!strcmp(aProperty, NS_XPCOM_COMPONENT_REGISTRY_FILE)) {
       rv = file->AppendNative(NS_LITERAL_CSTRING("compreg.dat"));
     }
-    else if (!strcmp(aProperty, NS_XPCOM_XPTI_REGISTRY_FILE)) {
-      rv = file->AppendNative(NS_LITERAL_CSTRING("xpti.dat"));
-    }
     else if (!strcmp(aProperty, NS_APP_USER_CHROME_DIR)) {
       rv = file->AppendNative(NS_LITERAL_CSTRING("chrome"));
     }
   }
 
   if (NS_SUCCEEDED(rv) && file) {
     NS_ADDREF(*aFile = file);
     return NS_OK;
--- a/xpcom/Makefile.in
+++ b/xpcom/Makefile.in
@@ -59,20 +59,16 @@ DIRS		= \
                 system \
 		build \
 		$(NULL)
 
 ifndef MOZ_ENABLE_LIBXUL
 DIRS += stub
 endif
 
-TOOL_DIRS = \
-	tools \
-	$(NULL)
-
 ifeq ($(OS_ARCH),WINNT)
 ifdef MOZ_DEBUG
 DIRS		+= windbgdlg
 endif
 endif
 
 ifdef ENABLE_TESTS
 TOOL_DIRS += \
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -276,17 +276,17 @@ static NS_METHOD
 nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
                                        const nsIID& aIID,
                                        void* *aInstancePtr)
 {
     NS_ASSERTION(aInstancePtr, "null outptr");
     NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
 
     nsCOMPtr<nsIInterfaceInfoManager> iim
-        (xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef());
+        (xptiInterfaceInfoManager::GetSingleton());
     if (!iim)
         return NS_ERROR_FAILURE;
 
     return iim->QueryInterface(aIID, aInstancePtr);
 }
 
 
 static nsresult
@@ -693,28 +693,31 @@ NS_InitXPCOM3(nsIServiceManager* *result
                           NS_SIMPLE_UNICHAR_STREAM_FACTORY_CONTRACTID,
                           nsSimpleUnicharStreamFactory::GetInstance());
     }
 
     NS_TIME_FUNCTION_MARK("Next: interface info manager init");
 
     // Pay the cost at startup time of starting this singleton.
     nsIInterfaceInfoManager* iim =
-        xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
+        xptiInterfaceInfoManager::GetSingleton();
 
     NS_TIME_FUNCTION_MARK("Next: try to load compreg.dat");
 
+#if 0 // The constructor does this, don't do it twice!
+    // If the component registry is out of date, malformed, or incomplete,
+    // autoregister the default component directories.
+    (void) iim->AutoRegisterInterfaces();
+#endif,
+
     // "Re-register the world" if compreg.dat doesn't exist
     rv = nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry();
     if (NS_FAILED(rv)) {
         NS_TIME_FUNCTION_MARK("Next: try to register all components (compreg.dat not found)");
 
-        // If the component registry is out of date, malformed, or incomplete,
-        // autoregister the default component directories.
-        (void) iim->AutoRegisterInterfaces();
         nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);
     }
 
     NS_TIME_FUNCTION_MARK("Next: register category providers");
 
     // After autoreg, but before we actually instantiate any components,
     // add any services listed in the "xpcom-directory-providers" category
     // to the directory service.
--- a/xpcom/glue/nsBaseHashtable.h
+++ b/xpcom/glue/nsBaseHashtable.h
@@ -130,16 +130,34 @@ public:
 
     if (pData)
       *pData = ent->mData;
 
     return PR_TRUE;
   }
 
   /**
+   * For pointer types, get the value, returning NULL if the entry is not
+   * present in the table.
+   *
+   * @param aKey the key to retrieve
+   * @return The found value, or NULL if no entry was found with the given key.
+   * @note If NULL values are stored in the table, it is not possible to
+   *       distinguish between a NULL value and a missing entry.
+   */
+  UserDataType Get(KeyType aKey) const
+  {
+    EntryType* ent = GetEntry(aKey);
+    if (!ent)
+      return NULL;
+
+    return ent->mData;
+  }
+
+  /**
    * put a new value for the associated key
    * @param aKey the key to put
    * @param aData the new data
    * @return always PR_TRUE, unless memory allocation failed
    */
   PRBool Put(KeyType aKey, UserDataType aData)
   {
     EntryType* ent = PutEntry(aKey);
--- a/xpcom/io/nsDirectoryService.cpp
+++ b/xpcom/io/nsDirectoryService.cpp
@@ -79,18 +79,16 @@
 #endif
 
 #include "SpecialSystemDirectory.h"
 #include "nsAppFileLocationProvider.h"
 
 #define COMPONENT_REGISTRY_NAME NS_LITERAL_CSTRING("compreg.dat")
 #define COMPONENT_DIRECTORY     NS_LITERAL_CSTRING("components")
 
-#define XPTI_REGISTRY_NAME      NS_LITERAL_CSTRING("xpti.dat")
-
 // define home directory
 // For Windows platform, We are choosing Appdata folder as HOME
 #if defined (XP_WIN)
 #define HOME_DIR NS_WIN_APPDATA_DIR
 #elif defined (XP_MACOSX)
 #define HOME_DIR NS_OSX_HOME_DIR
 #elif defined (XP_UNIX)
 #define HOME_DIR NS_UNIX_HOME_DIR
@@ -628,25 +626,16 @@ nsDirectoryService::GetFile(const char *
     {
         rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
         if (!localFile)
             return NS_ERROR_FAILURE;
 
         localFile->AppendNative(COMPONENT_DIRECTORY);           
         localFile->AppendNative(COMPONENT_REGISTRY_NAME);           
     }
-    else if (inAtom == nsDirectoryService::sXPTIRegistry)
-    {
-        rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
-        if (!localFile)
-            return NS_ERROR_FAILURE;
-
-        localFile->AppendNative(COMPONENT_DIRECTORY);           
-        localFile->AppendNative(XPTI_REGISTRY_NAME);           
-    }
     
     // Unless otherwise set, the core pieces of the GRE exist
     // in the current process directory.
     else if (inAtom == nsDirectoryService::sGRE_Directory)
     {
         rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
     }
     // the GRE components directory is relative to the GRE directory
--- a/xpcom/io/nsDirectoryServiceAtomList.h
+++ b/xpcom/io/nsDirectoryServiceAtomList.h
@@ -34,17 +34,16 @@
  * 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 ***** */
 
 DIR_ATOM(sCurrentProcess, NS_XPCOM_CURRENT_PROCESS_DIR)
 DIR_ATOM(sComponentRegistry, NS_XPCOM_COMPONENT_REGISTRY_FILE)
 DIR_ATOM(sComponentDirectory, NS_XPCOM_COMPONENT_DIR)
-DIR_ATOM(sXPTIRegistry, NS_XPCOM_XPTI_REGISTRY_FILE)
 DIR_ATOM(sGRE_Directory, NS_GRE_DIR)
 DIR_ATOM(sGRE_ComponentDirectory, NS_GRE_COMPONENT_DIR)
 DIR_ATOM(sOS_DriveDirectory, NS_OS_DRIVE_DIR)
 DIR_ATOM(sOS_TemporaryDirectory, NS_OS_TEMP_DIR)
 DIR_ATOM(sOS_CurrentProcessDirectory, NS_OS_CURRENT_PROCESS_DIR)
 DIR_ATOM(sOS_CurrentWorkingDirectory, NS_OS_CURRENT_WORKING_DIR)
 DIR_ATOM(sOS_HomeDirectory, NS_OS_HOME_DIR)
 DIR_ATOM(sOS_DesktopDirectory, NS_OS_DESKTOP_DIR)
--- a/xpcom/io/nsDirectoryServiceDefs.h
+++ b/xpcom/io/nsDirectoryServiceDefs.h
@@ -85,21 +85,16 @@
  */
 #define NS_XPCOM_COMPONENT_DIR_LIST             "ComsDL"
 
 /* Property will return the location of the application components
  * registry file.
  */
 #define NS_XPCOM_COMPONENT_REGISTRY_FILE        "ComRegF"
 
-/* Property will return the location of the application XPTI
- * registry file.
- */
-#define NS_XPCOM_XPTI_REGISTRY_FILE             "XptiRegF"
-
 /* Property will return the location of the the XPCOM Shared Library.
  */
 #define NS_XPCOM_LIBRARY_FILE                   "XpcomLib"
 
 /* Property will return the current location of the the GRE directory.  
  * If no GRE is used, this propery will behave like 
  * NS_XPCOM_CURRENT_PROCESS_DIR.
  */
--- a/xpcom/proxy/src/nsProxyObjectManager.cpp
+++ b/xpcom/proxy/src/nsProxyObjectManager.cpp
@@ -285,17 +285,17 @@ nsProxyObjectManager::GetClass(REFNSIID 
         nsAutoLock lock(mProxyCreationLock);
         if (mProxyClassMap.Get(aIID, aResult)) {
             NS_ASSERTION(*aResult, "Null data in mProxyClassMap");
             return NS_OK;
         }
     }
 
     nsIInterfaceInfoManager *iim =
-        xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
+        xptiInterfaceInfoManager::GetSingleton();
     if (!iim)
         return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIInterfaceInfo> ii;
     nsresult rv = iim->GetInfoForIID(&aIID, getter_AddRefs(ii));
     if (NS_FAILED(rv))
         return rv;
 
--- a/xpcom/reflect/xptcall/src/xptcall.cpp
+++ b/xpcom/reflect/xptcall/src/xptcall.cpp
@@ -39,17 +39,17 @@
 
 #include "xptcprivate.h"
 #include "xptiprivate.h"
 
 NS_IMETHODIMP
 nsXPTCStubBase::QueryInterface(REFNSIID aIID,
                                void **aInstancePtr)
 {
-    if (aIID.Equals(mEntry->mIID)) {
+    if (aIID.Equals(mEntry->IID())) {
         NS_ADDREF_THIS();
         *aInstancePtr = static_cast<nsISupports*>(this);
         return NS_OK;
     }
 
     return mOuter->QueryInterface(aIID, aInstancePtr);
 }
 
@@ -67,17 +67,17 @@ nsXPTCStubBase::Release()
 
 EXPORT_XPCOM_API(nsresult)
 NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
                   nsISomeInterface* *aResult)
 {
     NS_ENSURE_ARG(aOuter && aResult);
 
     xptiInterfaceInfoManager *iim =
-        xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
+        xptiInterfaceInfoManager::GetSingleton();
     NS_ENSURE_TRUE(iim, NS_ERROR_NOT_INITIALIZED);
 
     xptiInterfaceEntry *iie = iim->GetInterfaceEntryForIID(&aIID);
     if (!iie || !iie->EnsureResolved())
         return NS_ERROR_FAILURE;
 
     nsXPTCStubBase* newbase = new nsXPTCStubBase(aOuter, iie);
     if (!newbase)
--- a/xpcom/reflect/xptinfo/src/Makefile.in
+++ b/xpcom/reflect/xptinfo/src/Makefile.in
@@ -43,25 +43,21 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= xpcom
 LIBRARY_NAME	= xptinfo
 MOZILLA_INTERNAL_API = 1
 
 
 CPPSRCS		= \
-		xptiFile.cpp	\
 		xptiInterfaceInfo.cpp	\
 		xptiInterfaceInfoManager.cpp	\
-		xptiManifest.cpp	\
 		xptiMisc.cpp	\
 		xptiTypelibGuts.cpp	\
 		xptiWorkingSet.cpp	\
-		xptiZipItem.cpp	\
-		xptiZipLoader.cpp	\
 		$(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 # Force use of PIC
 FORCE_USE_PIC	= 1
 
deleted file mode 100644
--- a/xpcom/reflect/xptinfo/src/xptiFile.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** 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.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Mike McCabe <mccabe@netscape.com>
- *   John Bandhauer <jband@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 ***** */
-
-/* Implementation of xptiFile. */
-
-#include "xptiprivate.h"
-
-xptiFile::xptiFile()
-    :   
-#ifdef DEBUG
-        mDEBUG_WorkingSet(nsnull),
-#endif
-        mSize(),
-        mDate(),
-        mName(nsnull),
-        mGuts(nsnull),
-        mDirectory(0)
-{
-    // empty
-    MOZ_COUNT_CTOR(xptiFile);
-}
-
-xptiFile::xptiFile(const nsInt64&  aSize,
-         const nsInt64&  aDate,
-         PRUint32        aDirectory,
-         const char*     aName,
-         xptiWorkingSet* aWorkingSet)
-    :   
-#ifdef DEBUG
-        mDEBUG_WorkingSet(aWorkingSet),
-#endif
-        mSize(aSize),
-        mDate(aDate),
-        mName(aName),
-        mGuts(nsnull),
-        mDirectory(aDirectory)
-{
-    NS_ASSERTION(aWorkingSet,"bad param");
-    mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName);
-
-    MOZ_COUNT_CTOR(xptiFile);
-}
-
-xptiFile::xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet)
-    :   
-#ifdef DEBUG
-        mDEBUG_WorkingSet(aWorkingSet),
-#endif
-        mSize(r.mSize),
-        mDate(r.mDate),
-        mName(nsnull),
-        mGuts(nsnull),
-        mDirectory(r.mDirectory)
-{
-    NS_ASSERTION(aWorkingSet,"bad param");
-    mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName);
-
-    MOZ_COUNT_CTOR(xptiFile);
-}
-
-xptiFile::~xptiFile()
-{
-    MOZ_COUNT_DTOR(xptiFile);
-}
-
-PRBool 
-xptiFile::SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet)
-{
-    NS_ASSERTION(!mGuts,"bad state");
-    NS_ASSERTION(aHeader,"bad param");
-    NS_ASSERTION(aWorkingSet,"bad param");
-
-    mGuts = xptiTypelibGuts::NewGuts(aHeader, aWorkingSet);
-    return mGuts != nsnull;
-}
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
@@ -64,198 +64,100 @@ static int DEBUG_MonitorEntryCount = 0;
 
 #else /* SHOW_INFO_COUNT_STATS */
 
 #define LOG_INFO_CREATE(t)     ((void)0)
 #define LOG_INFO_DESTROY(t)    ((void)0)
 #define LOG_INFO_MONITOR_ENTRY ((void)0)
 #endif /* SHOW_INFO_COUNT_STATS */
 
-#ifdef DEBUG
-// static 
-void xptiInterfaceInfo::DEBUG_ShutdownNotification()
+/* static */ xptiInterfaceEntry*
+xptiInterfaceEntry::Create(const char* name, const nsID& iid,
+                           XPTInterfaceDescriptor* aDescriptor,
+                           xptiTypelibGuts* aTypelib)
 {
-#ifdef SHOW_INFO_COUNT_STATS
-    printf("iiii %d total xptiInterfaceInfos created\n", DEBUG_TotalInfos);      
-    printf("iiii %d max xptiInterfaceInfos alive at one time\n", DEBUG_MaxInfos);       
-    printf("iiii %d xptiInterfaceInfos still alive\n", DEBUG_CurrentInfos);       
-    printf("iiii %d times locked\n", DEBUG_MonitorEntryCount);       
-#endif
+    int namelen = strlen(name);
+    return new (XPT_MALLOC(gXPTIStructArena,
+                           sizeof(xptiInterfaceEntry) + namelen))
+        xptiInterfaceEntry(name, namelen, iid, aDescriptor, aTypelib);
 }
-#endif /* DEBUG */
-
-/***************************************************************************/
-
-// static 
-xptiInterfaceEntry* 
-xptiInterfaceEntry::NewEntry(const char* name,
-                             int nameLength,
-                             const nsID& iid,
-                             const xptiTypelib& typelib,
-                             xptiWorkingSet* aWorkingSet)
-{
-    void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
-                             sizeof(xptiInterfaceEntry) + nameLength);
-    if(!place)
-        return nsnull;
-    return new(place) xptiInterfaceEntry(name, nameLength, iid, typelib);
-}
-
-// static 
-xptiInterfaceEntry* 
-xptiInterfaceEntry::NewEntry(const xptiInterfaceEntry& r,
-                             const xptiTypelib& typelib,
-                             xptiWorkingSet* aWorkingSet)
-{
-    size_t nameLength = PL_strlen(r.mName);
-    void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
-                             sizeof(xptiInterfaceEntry) + nameLength);
-    if(!place)
-        return nsnull;
-    return new(place) xptiInterfaceEntry(r, nameLength, typelib);
-}
-
 
 xptiInterfaceEntry::xptiInterfaceEntry(const char* name,
                                        size_t nameLength,
                                        const nsID& iid,
-                                       const xptiTypelib& typelib)
-    :   mIID(iid),
-        mTypelib(typelib),
-        mInfo(nsnull),
-        mFlags(uint8(0))
+                                       XPTInterfaceDescriptor* aDescriptor,
+                                       xptiTypelibGuts* aTypelib)
+    : mIID(iid)
+    , mDescriptor(aDescriptor)
+    , mMethodBaseIndex(0)
+    , mConstantBaseIndex(0)
+    , mTypelib(aTypelib)
+    , mParent(NULL)
+    , mInfo(NULL)
+    , mFlags(0)
 {
     memcpy(mName, name, nameLength);
-}
-
-xptiInterfaceEntry::xptiInterfaceEntry(const xptiInterfaceEntry& r,
-                                       size_t nameLength,
-                                       const xptiTypelib& typelib)
-    :   mIID(r.mIID),
-        mTypelib(typelib),
-        mInfo(nsnull),
-        mFlags(r.mFlags)
-{
-    SetResolvedState(NOT_RESOLVED);
-    memcpy(mName, r.mName, nameLength);
+    SetResolvedState(PARTIALLY_RESOLVED);
 }
 
 PRBool 
-xptiInterfaceEntry::Resolve(xptiWorkingSet* aWorkingSet /* = nsnull */)
+xptiInterfaceEntry::Resolve()
 {
     nsAutoLock lock(xptiInterfaceInfoManager::GetResolveLock());
-    return ResolveLocked(aWorkingSet);
+    return ResolveLocked();
 }
 
 PRBool 
-xptiInterfaceEntry::ResolveLocked(xptiWorkingSet* aWorkingSet /* = nsnull */)
+xptiInterfaceEntry::ResolveLocked()
 {
     int resolvedState = GetResolveState();
 
     if(resolvedState == FULLY_RESOLVED)
         return PR_TRUE;
     if(resolvedState == RESOLVE_FAILED)
         return PR_FALSE;
 
-    xptiInterfaceInfoManager* mgr = 
-        xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
-
-    if(!mgr)
-        return PR_FALSE;
-
-    if(!aWorkingSet)
-    {
-        aWorkingSet = mgr->GetWorkingSet();
-    }
-
-    if(resolvedState == NOT_RESOLVED)
-    {
-        LOG_RESOLVE(("! begin    resolve of %s\n", mName));
-        // Make a copy of mTypelib because the underlying memory will change!
-        xptiTypelib typelib = mTypelib;
-        
-        // We expect our PartiallyResolveLocked() to get called before 
-        // this returns. 
-        if(!mgr->LoadFile(typelib, aWorkingSet))
-        {
-            SetResolvedState(RESOLVE_FAILED);
-            return PR_FALSE;    
-        }
-        // The state was changed by LoadFile to PARTIALLY_RESOLVED, so this 
-        // ...falls through...
-    }
+    xptiInterfaceInfoManager* mgr = xptiInterfaceInfoManager::GetSingleton();
+    
 
     NS_ASSERTION(GetResolveState() == PARTIALLY_RESOLVED, "bad state!");    
 
     // Finish out resolution by finding parent and Resolving it so
     // we can set the info we get from it.
 
-    PRUint16 parent_index = mInterface->mDescriptor->parent_interface;
+    PRUint16 parent_index = mDescriptor->parent_interface;
 
     if(parent_index)
     {
         xptiInterfaceEntry* parent = 
-            aWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
-                                GetEntryAt(parent_index - 1);
+            mTypelib->GetEntryAt(parent_index - 1);
         
         if(!parent || !parent->EnsureResolvedLocked())
         {
-            xptiTypelib aTypelib = mInterface->mTypelib;
-            mInterface = nsnull;
-            mTypelib = aTypelib;
             SetResolvedState(RESOLVE_FAILED);
             return PR_FALSE;
         }
 
-        mInterface->mParent = parent;
+        mParent = parent;
 
-        mInterface->mMethodBaseIndex =
-            parent->mInterface->mMethodBaseIndex + 
-            parent->mInterface->mDescriptor->num_methods;
+        mMethodBaseIndex =
+            parent->mMethodBaseIndex + 
+            parent->mDescriptor->num_methods;
         
-        mInterface->mConstantBaseIndex =
-            parent->mInterface->mConstantBaseIndex + 
-            parent->mInterface->mDescriptor->num_constants;
+        mConstantBaseIndex =
+            parent->mConstantBaseIndex + 
+            parent->mDescriptor->num_constants;
 
     }
     LOG_RESOLVE(("+ complete resolve of %s\n", mName));
 
     SetResolvedState(FULLY_RESOLVED);
     return PR_TRUE;
 }        
 
-// This *only* gets called by xptiInterfaceInfoManager::LoadFile (while locked).
-PRBool 
-xptiInterfaceEntry::PartiallyResolveLocked(XPTInterfaceDescriptor*  aDescriptor,
-                                           xptiWorkingSet*          aWorkingSet)
-{
-    NS_ASSERTION(GetResolveState() == NOT_RESOLVED, "bad state");
-
-    LOG_RESOLVE(("~ partial  resolve of %s\n", mName));
-
-    xptiInterfaceGuts* iface = 
-        xptiInterfaceGuts::NewGuts(aDescriptor, mTypelib, aWorkingSet);
-
-    if(!iface)
-        return PR_FALSE;
-
-    mInterface = iface;
-
-#ifdef DEBUG
-    if(!DEBUG_ScriptableFlagIsValid())
-    {
-        NS_ERROR("unexpected scriptable flag!");
-        SetScriptableFlag(XPT_ID_IS_SCRIPTABLE(mInterface->mDescriptor->flags));
-    }
-#endif
-
-    SetResolvedState(PARTIALLY_RESOLVED);
-    return PR_TRUE;
-}        
-
 /**************************************************/
 // These non-virtual methods handle the delegated nsIInterfaceInfo methods.
 
 nsresult
 xptiInterfaceEntry::GetName(char **name)
 {
     // It is not necessary to Resolve because this info is read from manifest.
     *name = (char*) nsMemory::Clone(mName, PL_strlen(mName)+1);
@@ -269,169 +171,165 @@ xptiInterfaceEntry::GetIID(nsIID **iid)
     *iid = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID));
     return *iid ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 nsresult
 xptiInterfaceEntry::IsScriptable(PRBool* result)
 {
     // It is not necessary to Resolve because this info is read from manifest.
-    NS_ASSERTION(DEBUG_ScriptableFlagIsValid(), "scriptable flag out of sync!");   
     *result = GetScriptableFlag();
     return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::IsFunction(PRBool* result)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    *result = XPT_ID_IS_FUNCTION(GetInterfaceGuts()->mDescriptor->flags);
+    *result = XPT_ID_IS_FUNCTION(mDescriptor->flags);
     return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::GetMethodCount(uint16* count)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
     
-    *count = mInterface->mMethodBaseIndex + 
-             mInterface->mDescriptor->num_methods;
+    *count = mMethodBaseIndex + 
+             mDescriptor->num_methods;
     return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::GetConstantCount(uint16* count)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    *count = mInterface->mConstantBaseIndex + 
-             mInterface->mDescriptor->num_constants;
+    *count = mConstantBaseIndex + 
+             mDescriptor->num_constants;
     return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::GetMethodInfo(uint16 index, const nsXPTMethodInfo** info)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    if(index < mInterface->mMethodBaseIndex)
-        return mInterface->mParent->GetMethodInfo(index, info);
+    if(index < mMethodBaseIndex)
+        return mParent->GetMethodInfo(index, info);
 
-    if(index >= mInterface->mMethodBaseIndex + 
-                mInterface->mDescriptor->num_methods)
+    if(index >= mMethodBaseIndex + 
+                mDescriptor->num_methods)
     {
         NS_ERROR("bad param");
         *info = NULL;
         return NS_ERROR_INVALID_ARG;
     }
 
     // else...
     *info = reinterpret_cast<nsXPTMethodInfo*>
-                            (&mInterface->mDescriptor->
-                                    method_descriptors[index - 
-                                        mInterface->mMethodBaseIndex]);
+       (&mDescriptor->method_descriptors[index - mMethodBaseIndex]);
     return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::GetMethodInfoForName(const char* methodName, uint16 *index,
                                          const nsXPTMethodInfo** result)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
     // This is a slow algorithm, but this is not expected to be called much.
-    for(uint16 i = 0; i < mInterface->mDescriptor->num_methods; ++i)
+    for(uint16 i = 0; i < mDescriptor->num_methods; ++i)
     {
         const nsXPTMethodInfo* info;
         info = reinterpret_cast<nsXPTMethodInfo*>
-                               (&mInterface->mDescriptor->
+                               (&mDescriptor->
                                         method_descriptors[i]);
         if (PL_strcmp(methodName, info->GetName()) == 0) {
-            *index = i + mInterface->mMethodBaseIndex;
+            *index = i + mMethodBaseIndex;
             *result = info;
             return NS_OK;
         }
     }
     
-    if(mInterface->mParent)
-        return mInterface->mParent->GetMethodInfoForName(methodName, index, result);
+    if(mParent)
+        return mParent->GetMethodInfoForName(methodName, index, result);
     else
     {
         *index = 0;
         *result = 0;
         return NS_ERROR_INVALID_ARG;
     }
 }
 
 nsresult
 xptiInterfaceEntry::GetConstant(uint16 index, const nsXPTConstant** constant)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    if(index < mInterface->mConstantBaseIndex)
-        return mInterface->mParent->GetConstant(index, constant);
+    if(index < mConstantBaseIndex)
+        return mParent->GetConstant(index, constant);
 
-    if(index >= mInterface->mConstantBaseIndex + 
-                mInterface->mDescriptor->num_constants)
+    if(index >= mConstantBaseIndex + 
+                mDescriptor->num_constants)
     {
         NS_PRECONDITION(0, "bad param");
         *constant = NULL;
         return NS_ERROR_INVALID_ARG;
     }
 
     // else...
     *constant =
         reinterpret_cast<nsXPTConstant*>
-                        (&mInterface->mDescriptor->
+                        (&mDescriptor->
                                 const_descriptors[index -
-                                    mInterface->mConstantBaseIndex]);
+                                    mConstantBaseIndex]);
     return NS_OK;
 }
 
 // this is a private helper
 
 nsresult 
 xptiInterfaceEntry::GetEntryForParam(PRUint16 methodIndex, 
                                      const nsXPTParamInfo * param,
                                      xptiInterfaceEntry** entry)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    if(methodIndex < mInterface->mMethodBaseIndex)
-        return mInterface->mParent->GetEntryForParam(methodIndex, param, entry);
+    if(methodIndex < mMethodBaseIndex)
+        return mParent->GetEntryForParam(methodIndex, param, entry);
 
-    if(methodIndex >= mInterface->mMethodBaseIndex + 
-                      mInterface->mDescriptor->num_methods)
+    if(methodIndex >= mMethodBaseIndex + 
+                      mDescriptor->num_methods)
     {
         NS_ERROR("bad param");
         return NS_ERROR_INVALID_ARG;
     }
 
     const XPTTypeDescriptor *td = &param->type;
 
     while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
-        td = &mInterface->mDescriptor->additional_types[td->type.additional_type];
+        td = &mDescriptor->additional_types[td->type.additional_type];
     }
 
     if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_TYPE) {
         NS_ERROR("not an interface");
         return NS_ERROR_INVALID_ARG;
     }
 
-    xptiInterfaceEntry* theEntry = 
-            mInterface->mWorkingSet->GetTypelibGuts(mInterface->mTypelib)->
-                GetEntryAt(td->type.iface - 1);
+    xptiInterfaceEntry* theEntry = mTypelib->
+        GetEntryAt(td->type.iface - 1);
     
     // This can happen if a declared interface is not available at runtime.
     if(!theEntry)
     {
         NS_WARNING("Declared InterfaceInfo not found");
         *entry = nsnull;
         return NS_ERROR_FAILURE;
     }
@@ -488,17 +386,17 @@ nsresult
 xptiInterfaceEntry::GetTypeInArray(const nsXPTParamInfo* param,
                                   uint16 dimension,
                                   const XPTTypeDescriptor** type)
 {
     NS_ASSERTION(IsFullyResolved(), "bad state");
 
     const XPTTypeDescriptor *td = &param->type;
     const XPTTypeDescriptor *additional_types =
-                mInterface->mDescriptor->additional_types;
+                mDescriptor->additional_types;
 
     for (uint16 i = 0; i < dimension; i++) {
         if(XPT_TDP_TAG(td->prefix) != TD_ARRAY) {
             NS_ERROR("bad dimension");
             return NS_ERROR_INVALID_ARG;
         }
         td = &additional_types[td->type.additional_type];
     }
@@ -511,22 +409,22 @@ nsresult
 xptiInterfaceEntry::GetTypeForParam(uint16 methodIndex,
                                     const nsXPTParamInfo* param,
                                     uint16 dimension,
                                     nsXPTType* type)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    if(methodIndex < mInterface->mMethodBaseIndex)
-        return mInterface->mParent->
+    if(methodIndex < mMethodBaseIndex)
+        return mParent->
             GetTypeForParam(methodIndex, param, dimension, type);
 
-    if(methodIndex >= mInterface->mMethodBaseIndex + 
-                      mInterface->mDescriptor->num_methods)
+    if(methodIndex >= mMethodBaseIndex + 
+                      mDescriptor->num_methods)
     {
         NS_ERROR("bad index");
         return NS_ERROR_INVALID_ARG;
     }
 
     const XPTTypeDescriptor *td;
 
     if(dimension) {
@@ -545,22 +443,22 @@ nsresult
 xptiInterfaceEntry::GetSizeIsArgNumberForParam(uint16 methodIndex,
                                                const nsXPTParamInfo* param,
                                                uint16 dimension,
                                                uint8* argnum)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    if(methodIndex < mInterface->mMethodBaseIndex)
-        return mInterface->mParent->
+    if(methodIndex < mMethodBaseIndex)
+        return mParent->
             GetSizeIsArgNumberForParam(methodIndex, param, dimension, argnum);
 
-    if(methodIndex >= mInterface->mMethodBaseIndex + 
-                      mInterface->mDescriptor->num_methods)
+    if(methodIndex >= mMethodBaseIndex + 
+                      mDescriptor->num_methods)
     {
         NS_ERROR("bad index");
         return NS_ERROR_INVALID_ARG;
     }
 
     const XPTTypeDescriptor *td;
 
     if(dimension) {
@@ -590,22 +488,22 @@ nsresult
 xptiInterfaceEntry::GetLengthIsArgNumberForParam(uint16 methodIndex,
                                                  const nsXPTParamInfo* param,
                                                  uint16 dimension,
                                                  uint8* argnum)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    if(methodIndex < mInterface->mMethodBaseIndex)
-        return mInterface->mParent->
+    if(methodIndex < mMethodBaseIndex)
+        return mParent->
             GetLengthIsArgNumberForParam(methodIndex, param, dimension, argnum);
 
-    if(methodIndex >= mInterface->mMethodBaseIndex + 
-                      mInterface->mDescriptor->num_methods)
+    if(methodIndex >= mMethodBaseIndex + 
+                      mDescriptor->num_methods)
     {
         NS_ERROR("bad index");
         return NS_ERROR_INVALID_ARG;
     }
 
     const XPTTypeDescriptor *td;
 
     if(dimension) {
@@ -635,31 +533,31 @@ xptiInterfaceEntry::GetLengthIsArgNumber
 nsresult
 xptiInterfaceEntry::GetInterfaceIsArgNumberForParam(uint16 methodIndex,
                                                     const nsXPTParamInfo* param,
                                                     uint8* argnum)
 {
     if(!EnsureResolved())
         return NS_ERROR_UNEXPECTED;
 
-    if(methodIndex < mInterface->mMethodBaseIndex)
-        return mInterface->mParent->
+    if(methodIndex < mMethodBaseIndex)
+        return mParent->
             GetInterfaceIsArgNumberForParam(methodIndex, param, argnum);
 
-    if(methodIndex >= mInterface->mMethodBaseIndex + 
-                      mInterface->mDescriptor->num_methods)
+    if(methodIndex >= mMethodBaseIndex + 
+                      mDescriptor->num_methods)
     {
         NS_ERROR("bad index");
         return NS_ERROR_INVALID_ARG;
     }
 
     const XPTTypeDescriptor *td = &param->type;
 
     while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
-        td = &mInterface->mDescriptor->
+        td = &mDescriptor->
                                 additional_types[td->type.additional_type];
     }
 
     if(XPT_TDP_TAG(td->prefix) != TD_INTERFACE_IS_TYPE) {
         NS_ERROR("not an iid_is");
         return NS_ERROR_INVALID_ARG;
     }
 
@@ -697,17 +595,17 @@ xptiInterfaceEntry::GetIIDShared(const n
 /* PRBool hasAncestor (in nsIIDPtr iid); */
 nsresult 
 xptiInterfaceEntry::HasAncestor(const nsIID * iid, PRBool *_retval)
 {
     *_retval = PR_FALSE;
 
     for(xptiInterfaceEntry* current = this; 
         current;
-        current = current->mInterface->mParent)
+        current = current->mParent)
     {
         if(current->mIID.Equals(*iid))
         {
             *_retval = PR_TRUE;
             break;
         }
         if(!current->EnsureResolved())
             return NS_ERROR_UNEXPECTED;
@@ -719,22 +617,16 @@ xptiInterfaceEntry::HasAncestor(const ns
 /***************************************************/
 
 nsresult 
 xptiInterfaceEntry::GetInterfaceInfo(xptiInterfaceInfo** info)
 {
     nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor());
     LOG_INFO_MONITOR_ENTRY;
 
-#ifdef SHOW_INFO_COUNT_STATS
-    static int callCount = 0;
-    if(!(++callCount%100))
-        printf("iiii %d xptiInterfaceInfos currently alive\n", DEBUG_CurrentInfos);       
-#endif
-
     if(!mInfo)
     {
         mInfo = new xptiInterfaceInfo(this);
         if(!mInfo)
         {
             *info = nsnull;    
             return NS_ERROR_OUT_OF_MEMORY;
         }
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
@@ -37,163 +37,78 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Implementation of xptiInterfaceInfoManager. */
 
 #include "xptiprivate.h"
 #include "nsDependentString.h"
 #include "nsString.h"
+#include "nsISupportsArray.h"
 #include "nsArrayEnumerator.h"
 #include "mozilla/FunctionTimer.h"
 
 #define NS_ZIPLOADER_CONTRACTID NS_XPTLOADER_CONTRACTID_PREFIX "zip"
 
 NS_IMPL_THREADSAFE_ISUPPORTS2(xptiInterfaceInfoManager, 
                               nsIInterfaceInfoManager,
                               nsIInterfaceInfoSuperManager)
 
 static xptiInterfaceInfoManager* gInterfaceInfoManager = nsnull;
 #ifdef DEBUG
 static int gCallCount = 0;
 #endif
 
 // static
 xptiInterfaceInfoManager*
-xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef()
+xptiInterfaceInfoManager::GetSingleton()
 {
-    if(!gInterfaceInfoManager)
-    {
+    if (!gInterfaceInfoManager) {
         NS_TIME_FUNCTION;
 
-        NS_TIME_FUNCTION_MARK("Next: build file search path");
-        nsCOMPtr<nsISupportsArray> searchPath;
-        BuildFileSearchPath(getter_AddRefs(searchPath));
-        if(!searchPath)
-        {
-            NS_ERROR("can't get xpt search path!");    
-            return nsnull;
-        }
-
-        gInterfaceInfoManager = new xptiInterfaceInfoManager(searchPath);
-        if(!gInterfaceInfoManager)
-        {
-            NS_ERROR("can't instantiate xptiInterfaceInfoManager");
-            return nsnull;
-        }
-
+        gInterfaceInfoManager = new xptiInterfaceInfoManager();
         NS_ADDREF(gInterfaceInfoManager);
 
-        if(!gInterfaceInfoManager->IsValid())
-        {
-            NS_RELEASE(gInterfaceInfoManager);
-        }
-        else
-        {
-            NS_TIME_FUNCTION_MARK("Next: read xpti manifest");
-            PRBool mustAutoReg = 
-                    !xptiManifest::Read(gInterfaceInfoManager, 
-                                        &gInterfaceInfoManager->mWorkingSet);
-#ifdef DEBUG
-            {
-            // This sets what will be returned by GetOpenLogFile().
-            xptiAutoLog autoLog(gInterfaceInfoManager, 
-                                gInterfaceInfoManager->mAutoRegLogFile, PR_TRUE);
-            LOG_AUTOREG(("debug build forced autoreg after %s load of manifest\n", mustAutoReg ? "FAILED" : "successful"));
-        
-            mustAutoReg = PR_TRUE;
-            }
-#endif // DEBUG
-            if(mustAutoReg) {
-                NS_TIME_FUNCTION_MARK("Next: auto register interfaces");
-                gInterfaceInfoManager->AutoRegisterInterfaces();
-            }
-        }
+        NS_TIME_FUNCTION_MARK("Next: auto register interfaces");
+        gInterfaceInfoManager->AutoRegisterInterfaces();
     }
     return gInterfaceInfoManager;
 }
 
 void
 xptiInterfaceInfoManager::FreeInterfaceInfoManager()
 {
-    if(gInterfaceInfoManager)
-        gInterfaceInfoManager->LogStats();
-
     NS_IF_RELEASE(gInterfaceInfoManager);
 }
 
-PRBool 
-xptiInterfaceInfoManager::IsValid()
-{
-    return mWorkingSet.IsValid() &&
-           mResolveLock &&
-           mAutoRegLock &&
-           mInfoMonitor &&
-           mAdditionalManagersLock;
-}        
-
-xptiInterfaceInfoManager::xptiInterfaceInfoManager(nsISupportsArray* aSearchPath)
-    :   mWorkingSet(aSearchPath),
-        mOpenLogFile(nsnull),
+xptiInterfaceInfoManager::xptiInterfaceInfoManager()
+    :   mWorkingSet(),
         mResolveLock(PR_NewLock()),
         mAutoRegLock(PR_NewLock()),
         mInfoMonitor(nsAutoMonitor::NewMonitor("xptiInfoMonitor")),
-        mAdditionalManagersLock(PR_NewLock()),
-        mSearchPath(aSearchPath)
+        mAdditionalManagersLock(PR_NewLock())
 {
-    const char* statsFilename = PR_GetEnv("MOZILLA_XPTI_STATS");
-    if(statsFilename && *statsFilename)
-    {
-        mStatsLogFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);         
-        if(mStatsLogFile && 
-           NS_SUCCEEDED(mStatsLogFile->InitWithNativePath(nsDependentCString(statsFilename))))
-        {
-            printf("* Logging xptinfo stats to: %s\n", statsFilename);
-        }
-        else
-        {
-            printf("* Failed to create xptinfo stats file: %s\n", statsFilename);
-            mStatsLogFile = nsnull;
-        }
-    }
-
-    const char* autoRegFilename = PR_GetEnv("MOZILLA_XPTI_REGLOG");
-    if(autoRegFilename && *autoRegFilename)
-    {
-        mAutoRegLogFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);         
-        if(mAutoRegLogFile && 
-           NS_SUCCEEDED(mAutoRegLogFile->InitWithNativePath(nsDependentCString(autoRegFilename))))
-        {
-            printf("* Logging xptinfo autoreg to: %s\n", autoRegFilename);
-        }
-        else
-        {
-            printf("* Failed to create xptinfo autoreg file: %s\n", autoRegFilename);
-            mAutoRegLogFile = nsnull;
-        }
-    }
 }
 
 xptiInterfaceInfoManager::~xptiInterfaceInfoManager()
 {
     // We only do this on shutdown of the service.
     mWorkingSet.InvalidateInterfaceInfos();
 
-    if(mResolveLock)
+    if (mResolveLock)
         PR_DestroyLock(mResolveLock);
-    if(mAutoRegLock)
+    if (mAutoRegLock)
         PR_DestroyLock(mAutoRegLock);
-    if(mInfoMonitor)
+    if (mInfoMonitor)
         nsAutoMonitor::DestroyMonitor(mInfoMonitor);
-    if(mAdditionalManagersLock)
+    if (mAdditionalManagersLock)
         PR_DestroyLock(mAdditionalManagersLock);
 
     gInterfaceInfoManager = nsnull;
 #ifdef DEBUG
-    xptiInterfaceInfo::DEBUG_ShutdownNotification();
     gCallCount = 0;
 #endif
 }
 
 static nsresult
 GetDirectoryFromDirService(const char* codename, nsILocalFile** aDir)
 {
     NS_ASSERTION(codename,"loser!");
@@ -202,1559 +117,289 @@ GetDirectoryFromDirService(const char* c
     nsresult rv;
     nsCOMPtr<nsIProperties> dirService =
         do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
     if (NS_FAILED(rv)) return rv;
 
     return dirService->Get(codename, NS_GET_IID(nsILocalFile), (void**) aDir);
 }
 
-static PRBool
-AppendFromDirServiceList(const char* codename, nsISupportsArray* aPath)
-{
-    NS_ASSERTION(codename,"loser!");
-    NS_ASSERTION(aPath,"loser!");
-    
-    nsCOMPtr<nsIProperties> dirService = 
-        do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
-    if(!dirService)
-        return PR_FALSE;
-
-    nsCOMPtr<nsISimpleEnumerator> fileList;
-    dirService->Get(codename, NS_GET_IID(nsISimpleEnumerator), 
-                    getter_AddRefs(fileList));
-    if(!fileList)
-        return PR_FALSE;
-    
-    PRBool more;
-    while(NS_SUCCEEDED(fileList->HasMoreElements(&more)) && more)
-    {
-        nsCOMPtr<nsILocalFile> dir;
-        fileList->GetNext(getter_AddRefs(dir));
-        if(!dir || !aPath->AppendElement(dir))
-            return PR_FALSE;
-    }
-
-    return PR_TRUE;
-}        
-
-// static 
-PRBool xptiInterfaceInfoManager::BuildFileSearchPath(nsISupportsArray** aPath)
-{
-#ifdef DEBUG
-    NS_ASSERTION(!gCallCount++, "Expected only one call!");
-#endif
-
-    nsCOMPtr<nsISupportsArray> searchPath;
-    NS_NewISupportsArray(getter_AddRefs(searchPath));
-    if(!searchPath)
-        return PR_FALSE;
-    
-    nsCOMPtr<nsILocalFile> compDir;
-
-    // Always put components directory first
-
-    if(NS_FAILED(GetDirectoryFromDirService(NS_XPCOM_COMPONENT_DIR, 
-                                            getter_AddRefs(compDir))) ||
-       !searchPath->AppendElement(compDir))
-    {
-        return PR_FALSE;
-    }
-
-    // No error checking here since this is optional in some embeddings
-    
-    // Add the GRE's component directory to searchPath if the 
-    // application is using an GRE.
-    // An application indicates that it's using an GRE by returning
-    // a valid nsIFile via its directory service provider interface.
-    //
-    // Please see http://www.mozilla.org/projects/embedding/MRE.html
-    // for more info. on GREs
-    //
-    nsCOMPtr<nsILocalFile> greComponentDirectory;
-    nsresult rv = GetDirectoryFromDirService(NS_GRE_COMPONENT_DIR, 
-                                    getter_AddRefs(greComponentDirectory));
-    if(NS_SUCCEEDED(rv) && greComponentDirectory)
-    {
-        // make sure we only append a directory if its a different one
-        PRBool equalsCompDir = PR_FALSE;
-        greComponentDirectory->Equals(compDir, &equalsCompDir);
-
-        if(!equalsCompDir)
-            searchPath->AppendElement(greComponentDirectory);
-    }
-
-    (void)AppendFromDirServiceList(NS_XPCOM_COMPONENT_DIR_LIST, searchPath);
-
-    NS_ADDREF(*aPath = searchPath);
-    return PR_TRUE;
-}
-
-PRBool 
-xptiInterfaceInfoManager::GetCloneOfManifestLocation(nsILocalFile** aFile)
-{
-    // We *trust* that this will not change!
-    nsCOMPtr<nsILocalFile> lf;
-    nsresult rv = GetDirectoryFromDirService(NS_XPCOM_XPTI_REGISTRY_FILE, 
-                                             getter_AddRefs(lf));
-
-    if (NS_FAILED(rv)) return PR_FALSE;
-
-    rv = xptiCloneLocalFile(lf, aFile);
-    if (NS_FAILED(rv)) return PR_FALSE;
-    return PR_TRUE;
-}
-
 PRBool 
 xptiInterfaceInfoManager::GetApplicationDir(nsILocalFile** aDir)
 {
     // We *trust* that this will not change!
     return NS_SUCCEEDED(GetDirectoryFromDirService(NS_XPCOM_CURRENT_PROCESS_DIR, aDir));
 }
 
-PRBool 
-xptiInterfaceInfoManager::BuildFileList(nsISupportsArray* aSearchPath,
-                                        nsISupportsArray** aFileList)
+void
+xptiInterfaceInfoManager::RegisterDirectory(nsILocalFile* aDirectory)
 {
-    NS_ASSERTION(aFileList, "loser!");
-    
     nsresult rv;
 
-    nsCOMPtr<nsISupportsArray> fileList = 
-        do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
-    if(!fileList)
-        return PR_FALSE;
-
-    PRUint32 pathCount;
-    if(NS_FAILED(aSearchPath->Count(&pathCount)))
-        return PR_FALSE;
-
-    nsCOMPtr<nsILocalFile> dir;
     nsCOMPtr<nsISimpleEnumerator> entries;
     nsCOMPtr<nsISupports> sup;
     nsCOMPtr<nsILocalFile> file;
 
-    // Iterate the paths backwards to avoid the
-    // insertions that would occur if we preserved
-    // the order of the list.
-    for(PRUint32 i = pathCount; i; i--)
-    {
-        rv = xptiCloneElementAsLocalFile(aSearchPath, (i - 1), getter_AddRefs(dir));
-        if(NS_FAILED(rv) || !dir)
-            return PR_FALSE;
+    rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
+    if (NS_FAILED(rv) || !entries)
+        return;
+
+    PRBool hasMore;
+    while(NS_SUCCEEDED(entries->HasMoreElements(&hasMore)) && hasMore) {
+        entries->GetNext(getter_AddRefs(sup));
+        if (!sup)
+            return;
 
-        rv = dir->GetDirectoryEntries(getter_AddRefs(entries));
-        if(NS_FAILED(rv) || !entries)
+        file = do_QueryInterface(sup);
+        if(!file)
+            return;
+
+        PRBool isFile;
+        if(NS_FAILED(file->IsFile(&isFile)) || !isFile)
+            continue;
+     
+        nsCAutoString name;
+        file->GetNativeLeafName(name);
+        xptiFileType::Type type = xptiFileType::GetType(name);
+        if (xptiFileType::UNKNOWN == type)
             continue;
 
-        PRBool hasMore;
-        while(NS_SUCCEEDED(entries->HasMoreElements(&hasMore)) && hasMore)
-        {
-            entries->GetNext(getter_AddRefs(sup));
-            if(!sup)
-                return PR_FALSE;
+        LOG_AUTOREG(("found file: %s\n", name.get()));
 
-            file = do_QueryInterface(sup);
-            if(!file)
-                return PR_FALSE;
+        RegisterFile(file, type);
+    }
+}
 
-            PRBool isFile;
-            if(NS_FAILED(file->IsFile(&isFile)) || !isFile)
-            {
-                continue;
-            }
-     
-            nsCAutoString name;
-            if(NS_FAILED(file->GetNativeLeafName(name)))
-                return PR_FALSE;
-
-            if(xptiFileType::IsUnknown(name.get()))
-                continue;
-
-            LOG_AUTOREG(("found file: %s\n", name.get()));
-
-            if(!fileList->AppendElement(file))
-                return PR_FALSE;
-        }
+namespace {
+struct AutoCloseFD
+{
+    AutoCloseFD()
+        : mFD(NULL)
+    { }
+    ~AutoCloseFD() {
+        if (mFD)
+            PR_Close(mFD);
+    }
+    operator PRFileDesc*() {
+        return mFD;
     }
 
-    fileList.swap(*aFileList);
-    return PR_TRUE;
-}
+    PRFileDesc** operator&() {
+        NS_ASSERTION(!mFD, "Re-opening a file");
+        return &mFD;
+    }
+
+    PRFileDesc* mFD;
+};
+
+} // anonymous namespace
 
 XPTHeader* 
-xptiInterfaceInfoManager::ReadXPTFile(nsILocalFile* aFile, 
-                                      xptiWorkingSet* aWorkingSet)
+xptiInterfaceInfoManager::ReadXPTFile(nsILocalFile* aFile)
 {
-    NS_ASSERTION(aFile, "loser!");
+    AutoCloseFD fd;
+    if (NS_FAILED(aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd)
+        return NULL;
+
+    PRFileInfo64 fileInfo;
+    if (PR_SUCCESS != PR_GetOpenFileInfo64(fd, &fileInfo))
+        return NULL;
 
-    XPTHeader *header = nsnull;
-    char *whole = nsnull;
-    PRFileDesc*   fd = nsnull;
-    XPTState *state = nsnull;
-    XPTCursor cursor;
-    PRInt32 flen;
-    PRInt64 fileSize;
-    
-    PRBool saveFollowLinks;
-    aFile->GetFollowLinks(&saveFollowLinks);
-    aFile->SetFollowLinks(PR_TRUE);
+    if (fileInfo.size > PRInt64(PR_INT32_MAX))
+        return NULL;
 
-    if(NS_FAILED(aFile->GetFileSize(&fileSize)) || !(flen = nsInt64(fileSize)))
-    {
-        aFile->SetFollowLinks(saveFollowLinks);
+    nsAutoArrayPtr<char> whole(new char[PRInt32(fileInfo.size)]);
+    if (!whole)
         return nsnull;
-    }
 
-    whole = new char[flen];
-    if (!whole)
-    {
-        aFile->SetFollowLinks(saveFollowLinks);
-        return nsnull;
+    for (PRInt32 totalRead = 0; totalRead < fileInfo.size; ) {
+        PRInt32 read = PR_Read(fd, whole + totalRead, PRInt32(fileInfo.size));
+        if (read < 0)
+            return NULL;
+        totalRead += read;
     }
 
-    // all exits from on here should be via 'goto out' 
-
-    if(NS_FAILED(aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd)
-    {
-        goto out;
-    }
+    XPTState* state = XPT_NewXDRState(XPT_DECODE, whole,
+                                      PRInt32(fileInfo.size));
 
-    if(flen > PR_Read(fd, whole, flen))
-    {
-        goto out;
-    }
-
-    if(!(state = XPT_NewXDRState(XPT_DECODE, whole, flen)))
-    {
-        goto out;
+    XPTCursor cursor;
+    if (!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) {
+        XPT_DestroyXDRState(state);
+        return NULL;
     }
     
-    if(!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor))
-    {
-        goto out;
-    }
-    
-    if (!XPT_DoHeader(aWorkingSet->GetStructArena(), &cursor, &header))
-    {
-        header = nsnull;
-        goto out;
+    XPTHeader *header = nsnull;
+    if (!XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
+        XPT_DestroyXDRState(state);
+        return NULL;
     }
 
- out:
-    if(fd)
-        PR_Close(fd);
-    if(state)
-        XPT_DestroyXDRState(state);
-    if(whole)
-        delete [] whole;
-    aFile->SetFollowLinks(saveFollowLinks);
+    XPT_DestroyXDRState(state);
+
     return header;
 }
 
-PRBool 
-xptiInterfaceInfoManager::LoadFile(const xptiTypelib& aTypelibRecord,
-                                 xptiWorkingSet* aWorkingSet)
+XPTHeader*
+xptiInterfaceInfoManager::ReadXPTFileFromInputStream(nsIInputStream *stream)
 {
-    if(!aWorkingSet)
-        aWorkingSet = &mWorkingSet;
-
-    if(!aWorkingSet->IsValid())
-        return PR_FALSE;
-
-    xptiFile* fileRecord = &aWorkingSet->GetFileAt(aTypelibRecord.GetFileIndex());
-    xptiZipItem* zipItem = nsnull;
-
-    nsCOMPtr<nsILocalFile> file;
-    if(NS_FAILED(aWorkingSet->GetCloneOfDirectoryAt(fileRecord->GetDirectory(),
-                                    getter_AddRefs(file))) || !file)
-        return PR_FALSE;
-
-    if(NS_FAILED(file->AppendNative(nsDependentCString(fileRecord->GetName()))))
-        return PR_FALSE;
-
-    XPTHeader* header;
-
-    if(aTypelibRecord.IsZip())
-    {
-        zipItem = &aWorkingSet->GetZipItemAt(aTypelibRecord.GetZipItemIndex());
-        
-        // See the big comment below in the 'non-zip' case...
-        if(zipItem->GetGuts())
-        {
-            NS_ERROR("Trying to load an xpt file from a zip twice");    
-            
-            // Force an autoreg on next run
-            (void) xptiManifest::Delete(this);
-
-            return PR_FALSE;
-        }
-        
-        LOG_LOAD(("# loading zip item %s::%s\n", fileRecord->GetName(), zipItem->GetName()));
-        
-        nsCOMPtr<nsIXPTLoader> loader =
-            do_GetService(NS_ZIPLOADER_CONTRACTID);
-
-        if (loader) {
-            nsresult rv;
-            
-            nsCOMPtr<nsIInputStream> stream;
-            rv = loader->LoadEntry(file, zipItem->GetName(),
-                                   getter_AddRefs(stream));
-
-            if (NS_FAILED(rv))
-                return PR_FALSE;
-            
-            header =
-                xptiZipLoader::ReadXPTFileFromInputStream(stream, aWorkingSet);
-        } else {
-            header = nsnull;
-            NS_WARNING("Could not load XPT Zip loader");
-        }
-    } 
-    else
-    {
-        // The file would only have guts already if we previously failed to 
-        // find an interface info in a file where the manifest claimed it was 
-        // going to be. 
-        //
-        // Normally, when the file gets loaded (and the guts set) then all 
-        // interfaces would also be resolved. So, if we are here again for
-        // the same file then there must have been some interface that was 
-        // expected but not present. Now we are explicitly trying to find it
-        // and it isn't going to be there this time either.
-        //
-        // This is an assertion style error in a DEBUG build because it shows 
-        // that we failed to detect this in autoreg. For release builds (where
-        // autoreg is not run on every startup) it is just bad. But by returning
-        // PR_FALSE we mark this interface as RESOLVE_FAILED and get on with 
-        // things without crashing or anything.
-        //
-        // We don't want to do an autoreg here because this is too much of an 
-        // edge case (and in that odd case it might autoreg multiple times if
-        // many interfaces had been removed). But, by deleting the manifest we 
-        // force the system to get it right on the next run.
-        
-        if(fileRecord->GetGuts())
-        {
-            NS_ERROR("Trying to load an xpt file twice");    
-            
-            // Force an autoreg on next run
-            (void) xptiManifest::Delete(this);
-
-            return PR_FALSE;
-        }
-
-        LOG_LOAD(("^ loading file %s\n", fileRecord->GetName()));
-        header = ReadXPTFile(file, aWorkingSet);
-    } 
-
-    if(!header)
-        return PR_FALSE;
-
-
-    if(aTypelibRecord.IsZip())
-    {
-        // This also allocs zipItem.GetGuts() used below.
-        if(!zipItem->SetHeader(header, aWorkingSet))
-            return PR_FALSE;
-    }
-    else
-    {
-        // This also allocs fileRecord.GetGuts() used below.
-        if(!fileRecord->SetHeader(header, aWorkingSet))
-            return PR_FALSE;
-    }
-
-    // For each interface in the header we want to find the xptiInterfaceInfo
-    // object and set its resolution info.
-
-    for(PRUint16 i = 0; i < header->num_interfaces; i++)
-    {
-        static const nsID zeroIID =
-            { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
-
-        XPTInterfaceDirectoryEntry* iface = header->interface_directory + i;
-        
-        xptiHashEntry* hashEntry;
-
-        if(!iface->iid.Equals(zeroIID))
-        {
-            hashEntry = (xptiHashEntry*)
-                PL_DHashTableOperate(aWorkingSet->mIIDTable, 
-                                     &iface->iid, PL_DHASH_LOOKUP);
-        }
-        else
-        {
-            hashEntry = (xptiHashEntry*)
-                PL_DHashTableOperate(aWorkingSet->mNameTable, 
-                                     iface->name, PL_DHASH_LOOKUP);
-        }
-
-        xptiInterfaceEntry* entry = 
-            PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value;
-
-        if(!entry)
-        {
-            // This one is just not resolved anywhere!
-            continue;    
-        }
-
-        if(aTypelibRecord.IsZip())
-            zipItem->GetGuts()->SetEntryAt(i, entry);
-        else
-            fileRecord->GetGuts()->SetEntryAt(i, entry);
-
-        XPTInterfaceDescriptor* descriptor = iface->interface_descriptor;
-
-        if(descriptor && aTypelibRecord.Equals(entry->GetTypelibRecord()))
-            entry->PartiallyResolveLocked(descriptor, aWorkingSet);
-    }
-    return PR_TRUE;
-}
-
-static int
-IndexOfFileWithName(const char* aName, const xptiWorkingSet* aWorkingSet)
-{
-    NS_ASSERTION(aName, "loser!");
-
-    for(PRUint32 i = 0; i < aWorkingSet->GetFileCount(); ++i)
-    {
-        if(0 == PL_strcmp(aName, aWorkingSet->GetFileAt(i).GetName()))
-            return i;     
-    }
-    return -1;        
-}        
-
-static int
-IndexOfDirectoryOfFile(nsISupportsArray* aSearchPath, nsILocalFile* aFile)
-{
-    nsCOMPtr<nsIFile> parent;
-    aFile->GetParent(getter_AddRefs(parent));
-    if(parent)
-    {
-        PRUint32 count = 0;
-        aSearchPath->Count(&count);
-        NS_ASSERTION(count, "broken search path! bad count");
-        for(PRUint32 i = 0; i < count; i++)
-        {
-            nsCOMPtr<nsIFile> current;
-            aSearchPath->QueryElementAt(i, NS_GET_IID(nsIFile), 
-                                        getter_AddRefs(current));
-            NS_ASSERTION(current, "broken search path! bad element");
-            // nsIFile::Equals basically compares path strings so normalize
-            // before the comparison.
-            parent->Normalize();
-            current->Normalize();
-            PRBool same;
-            if (NS_SUCCEEDED(parent->Equals(current, &same)) && same)
-                return (int) i;
-        }
-    }
-    NS_ERROR("file not in search directory!");
-    return -1;
-}        
-
-struct SortData
-{
-    nsISupportsArray* mSearchPath;
-    xptiWorkingSet*   mWorkingSet;
-};
-
-static int
-xptiSortFileList(const void * p1, const void *p2, void * closure)
-{
-    nsILocalFile* pFile1 = *((nsILocalFile**) p1);
-    nsILocalFile* pFile2 = *((nsILocalFile**) p2);
-    SortData* data = (SortData*) closure;
+    PRUint32 flen;
+    stream->Available(&flen);
     
-    nsCAutoString name1;
-    nsCAutoString name2;
-        
-    if(NS_FAILED(pFile1->GetNativeLeafName(name1)))
-    {
-        NS_ERROR("way bad, with no happy out!");
-        return 0;    
-    }    
-    if(NS_FAILED(pFile2->GetNativeLeafName(name2)))
-    {
-        NS_ERROR("way bad, with no happy out!");
-        return 0;    
-    }    
-
-    int index1 = IndexOfFileWithName(name1.get(), data->mWorkingSet); 
-    int index2 = IndexOfFileWithName(name2.get(), data->mWorkingSet); 
-   
-    // Get these now in case we need them later.
-    PRBool isXPT1 = xptiFileType::IsXPT(name1.get());
-    PRBool isXPT2 = xptiFileType::IsXPT(name2.get());
-    int nameOrder = Compare(name1, name2);
-    
-    // both in workingSet, preserve old order
-    if(index1 != -1 && index2 != -1)
-        return index1 - index2;
-
-    if(index1 != -1)
-        return 1;
-
-    if(index2 != -1)
-        return -1;
-
-    // neither is in workingset
-
-    // check how they compare in search path order
-    
-    int dirIndex1 = IndexOfDirectoryOfFile(data->mSearchPath, pFile1);
-    int dirIndex2 = IndexOfDirectoryOfFile(data->mSearchPath, pFile2);
-
-    if(dirIndex1 != dirIndex2)
-        return dirIndex1 - dirIndex2;
-
-    // .xpt files come before archives (.zip, .jar, etc)
-    if(isXPT1 &&!isXPT2)
-        return -1;
-        
-    if(!isXPT1 && isXPT2)
-        return 1;
-    
-    // neither element is in the workingSet and both are same type and in 
-    // the same directory, sort by size
-
-    PRInt64 size1;
-    PRInt64 size2;
-
-    if(NS_FAILED(pFile1->GetFileSize(&size1)))
-    {
-        NS_ERROR("way bad, with no happy out!");
-        return 0;    
-    }    
-    if(NS_FAILED(pFile2->GetFileSize(&size2)))
-    {
-        NS_ERROR("way bad, with no happy out!");
-        return 0;    
-    }    
-
-    // by size with largest first, or by name if size is the same
-    int sizeDiff = int(PRInt32(nsInt64(size2) - nsInt64(size1)));
-    return sizeDiff != 0  ? sizeDiff : nameOrder;
-}        
-
-nsILocalFile** 
-xptiInterfaceInfoManager::BuildOrderedFileArray(nsISupportsArray* aSearchPath,
-                                                nsISupportsArray* aFileList,
-                                                xptiWorkingSet* aWorkingSet)
-{
-    // We want to end up with a file list that starts with the files from
-    // aWorkingSet (but only those that are in aFileList) in the order in 
-    // which they appeared in aWorkingSet-> Following those files will be those
-    // files in aFileList which are not in aWorkingSet-> These additional
-    // files will be ordered by file size (larger first) but all .xpt files
-    // will preceed all zipfile of those files not already in the working set.
-    // To do this we will do a fancy sort on a copy of aFileList.
-
-    nsILocalFile** orderedFileList = nsnull;
-    PRUint32 countOfFilesInFileList;
-    PRUint32 i;
-
-    NS_ASSERTION(aFileList, "loser!");
-    NS_ASSERTION(aWorkingSet, "loser!");
-    NS_ASSERTION(aWorkingSet->IsValid(), "loser!");
-
-    if(NS_FAILED(aFileList->Count(&countOfFilesInFileList)) || 
-       0 == countOfFilesInFileList)
+    nsAutoArrayPtr<char> whole(new char[flen]);
+    if (!whole)
         return nsnull;
 
-    orderedFileList = (nsILocalFile**) 
-        XPT_MALLOC(aWorkingSet->GetStructArena(),
-                   sizeof(nsILocalFile*) * countOfFilesInFileList);
-    
-    if(!orderedFileList)
-        return nsnull;
+    for (PRUint32 totalRead = 0; totalRead < flen; ) {
+        PRUint32 avail;
+        PRUint32 read;
 
-    // fill our list for sorting
-    for(i = 0; i < countOfFilesInFileList; ++i)
-    {
-        nsCOMPtr<nsILocalFile> file;
-        aFileList->QueryElementAt(i, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
-        NS_ASSERTION(file, "loser!");
+        if (NS_FAILED(stream->Available(&avail)))
+            return NULL;
 
-        // Intentionally NOT addref'd cuz we know these are pinned in aFileList.
-        orderedFileList[i] = file.get();
-    }
+        if (avail > flen)
+            return NULL;
 
-    // sort the filelist
+        if (NS_FAILED(stream->Read(whole+totalRead, avail, &read)))
+            return NULL;
 
-    SortData sortData = {aSearchPath, aWorkingSet};
-    NS_QuickSort(orderedFileList, countOfFilesInFileList, sizeof(nsILocalFile*),
-                 xptiSortFileList, &sortData);
-     
-    return orderedFileList;
-}
-
-xptiInterfaceInfoManager::AutoRegMode 
-xptiInterfaceInfoManager::DetermineAutoRegStrategy(nsISupportsArray* aSearchPath,
-                                                   nsISupportsArray* aFileList,
-                                                   xptiWorkingSet* aWorkingSet)
-{
-    NS_ASSERTION(aFileList, "loser!");
-    NS_ASSERTION(aWorkingSet, "loser!");
-    NS_ASSERTION(aWorkingSet->IsValid(), "loser!");
-
-    PRUint32 countOfFilesInWorkingSet = aWorkingSet->GetFileCount();
-    PRUint32 countOfFilesInFileList;
-    PRUint32 i;
-    PRUint32 k;
-
-    if(0 == countOfFilesInWorkingSet)
-    {
-        // Loading manifest might have failed. Better safe...     
-        return FULL_VALIDATION_REQUIRED;
+        totalRead += read;
+    }
+    
+    XPTState *state = XPT_NewXDRState(XPT_DECODE, whole, flen);
+    if (!state)
+        return NULL;
+    
+    XPTCursor cursor;
+    if (!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) {
+        XPT_DestroyXDRState(state);
+        return NULL;
+    }
+    
+    XPTHeader *header = nsnull;
+    if (!XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
+        XPT_DestroyXDRState(state);
+        return NULL;
     }
 
-    if(NS_FAILED(aFileList->Count(&countOfFilesInFileList)))
-    {
-        NS_ERROR("unexpected!");
-        return FULL_VALIDATION_REQUIRED;
-    }       
-
-    if(countOfFilesInFileList == countOfFilesInWorkingSet)
-    {
-        // try to determine if *no* files are new or changed.
-     
-        PRBool same = PR_TRUE;
-        for(i = 0; i < countOfFilesInFileList && same; ++i)
-        {
-            nsCOMPtr<nsILocalFile> file;
-            aFileList->QueryElementAt(i, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
-            NS_ASSERTION(file, "loser!");
-
-            PRInt64 size;
-            PRInt64 date;
-            nsCAutoString name;
-            PRUint32 directory;
-
-            if(NS_FAILED(file->GetFileSize(&size)) ||
-               NS_FAILED(file->GetLastModifiedTime(&date)) ||
-               NS_FAILED(file->GetNativeLeafName(name)) ||
-               !aWorkingSet->FindDirectoryOfFile(file, &directory))
-            {
-                NS_ERROR("unexpected!");
-                return FULL_VALIDATION_REQUIRED;
-            }    
+    XPT_DestroyXDRState(state);
 
-            for(k = 0; k < countOfFilesInWorkingSet; ++k)
-            {
-                xptiFile& target = aWorkingSet->GetFileAt(k);
-                
-                if(directory == target.GetDirectory() &&
-                   name.Equals(target.GetName()))
-                {
-                    if(nsInt64(size) != target.GetSize() ||
-                       nsInt64(date) != target.GetDate())
-                        same = PR_FALSE;
-                    break;        
-                }
-            }
-            // failed to find our file in the workingset?
-            if(k == countOfFilesInWorkingSet)
-                same = PR_FALSE;
-        }
-        if(same)
-            return NO_FILES_CHANGED;
-    }
-    else if(countOfFilesInFileList > countOfFilesInWorkingSet)
-    {
-        // try to determine if the only changes are additional new files
-        // XXX Wimping out and doing this as a separate walk through the lists.
-
-        PRBool same = PR_TRUE;
-
-        for(i = 0; i < countOfFilesInWorkingSet && same; ++i)
-        {
-            xptiFile& target = aWorkingSet->GetFileAt(i);
-            
-            for(k = 0; k < countOfFilesInFileList; ++k)
-            {
-                nsCOMPtr<nsILocalFile> file;
-                aFileList->QueryElementAt(k, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
-                NS_ASSERTION(file, "loser!");
-                
-                nsCAutoString name;
-                PRInt64 size;
-                PRInt64 date;
-                if(NS_FAILED(file->GetFileSize(&size)) ||
-                   NS_FAILED(file->GetLastModifiedTime(&date)) ||
-                   NS_FAILED(file->GetNativeLeafName(name)))
-                {
-                    NS_ERROR("unexpected!");
-                    return FULL_VALIDATION_REQUIRED;
-                }    
-            
-                PRBool sameName = name.Equals(target.GetName());
-                if(sameName)
-                {
-                    if(nsInt64(size) != target.GetSize() ||
-                       nsInt64(date) != target.GetDate())
-                        same = PR_FALSE;
-                    break;        
-                }
-            }
-            // failed to find our file in the file list?
-            if(k == countOfFilesInFileList)
-                same = PR_FALSE;
-        }
-        if(same)
-            return FILES_ADDED_ONLY;
-    }
-
-    return FULL_VALIDATION_REQUIRED; 
+    return header;
 }
 
-PRBool 
-xptiInterfaceInfoManager::AddOnlyNewFilesFromFileList(nsISupportsArray* aSearchPath,
-                                                      nsISupportsArray* aFileList,
-                                                      xptiWorkingSet* aWorkingSet)
+void
+xptiInterfaceInfoManager::RegisterFile(nsILocalFile* aFile, xptiFileType::Type aType)
 {
-    nsILocalFile** orderedFileArray;
-    PRUint32 countOfFilesInFileList;
-    PRUint32 i;
-
-    NS_ASSERTION(aFileList, "loser!");
-    NS_ASSERTION(aWorkingSet, "loser!");
-    NS_ASSERTION(aWorkingSet->IsValid(), "loser!");
-
-    if(NS_FAILED(aFileList->Count(&countOfFilesInFileList)))
-        return PR_FALSE;
-    NS_ASSERTION(countOfFilesInFileList, "loser!");
-    NS_ASSERTION(countOfFilesInFileList > aWorkingSet->GetFileCount(), "loser!");
-
-    orderedFileArray = BuildOrderedFileArray(aSearchPath, aFileList, aWorkingSet);
-
-    if(!orderedFileArray)
-        return PR_FALSE;
-
-    // Make enough space in aWorkingset for additions to xptiFile array.
-
-    if(!aWorkingSet->ExtendFileArray(countOfFilesInFileList))   
-        return PR_FALSE;
-
-    // For each file that is not already in our working set, add any valid 
-    // interfaces that don't conflict with previous interfaces added.
-    for(i = 0; i < countOfFilesInFileList; i++)
-    {
-        nsILocalFile* file = orderedFileArray[i];
-
-        nsCAutoString name;
-        PRInt64 size;
-        PRInt64 date;
-        PRUint32 dir;
-        if(NS_FAILED(file->GetFileSize(&size)) ||
-           NS_FAILED(file->GetLastModifiedTime(&date)) ||
-           NS_FAILED(file->GetNativeLeafName(name)) ||
-           !aWorkingSet->FindDirectoryOfFile(file, &dir))
-        {
-            return PR_FALSE;
-        }    
-    
-
-        if(xptiWorkingSet::NOT_FOUND != aWorkingSet->FindFile(dir, name.get()))
-        {
-            // This file was found in the working set, so skip it.       
-            continue;
-        }
-
-        LOG_AUTOREG(("  finding interfaces in new file: %s\n", name.get()));
-
-        xptiFile fileRecord;
-        fileRecord = xptiFile(nsInt64(size), nsInt64(date), dir,
-                              name.get(), aWorkingSet);
+    switch (aType) {
+    case xptiFileType::XPT: {
+        XPTHeader* header = ReadXPTFile(aFile);
+        if (!header)
+            return;
 
-        if(xptiFileType::IsXPT(fileRecord.GetName()))
-        {
-            XPTHeader* header = ReadXPTFile(file, aWorkingSet);
-            if(!header)
-            {
-                // XXX do something!
-                NS_ERROR("");    
-                continue;
-            }
-
-    
-            xptiTypelib typelibRecord;
-            typelibRecord.Init(aWorkingSet->GetFileCount());
-    
-            PRBool AddedFile = PR_FALSE;
-
-            if(header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION)
-            {
-                NS_ASSERTION(!header->num_interfaces,"bad libxpt");
-                LOG_AUTOREG(("      file is version %d.%d  Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION));
-            }
+        RegisterXPTHeader(header);
+        break;
+    }
+        
+    case xptiFileType::ZIP: {
+        // XXX XPCOM registration ordering issue, use C++!
+        nsCOMPtr<nsIXPTLoader> loader = do_GetService(NS_ZIPLOADER_CONTRACTID);
+        if (!loader)
+            return;
 
-            for(PRUint16 k = 0; k < header->num_interfaces; k++)
-            {
-                xptiInterfaceEntry* entry = nsnull;
-    
-                if(!VerifyAndAddEntryIfNew(aWorkingSet,
-                                           header->interface_directory + k,
-                                           typelibRecord,
-                                           &entry))
-                    return PR_FALSE;    
-    
-                if(!entry)
-                    continue;
-                
-                // If this is the first interface we found for this file then
-                // setup the fileRecord for the header and infos.
-                if(!AddedFile)
-                {
-                    if(!fileRecord.SetHeader(header, aWorkingSet))
-                    {
-                        // XXX that would be bad.
-                        return PR_FALSE;    
-                    }
-                    AddedFile = PR_TRUE;
-                }
-                fileRecord.GetGuts()->SetEntryAt(k, entry);
-            }
-            
-            // This will correspond to typelibRecord above.
-            aWorkingSet->AppendFile(fileRecord);
-        }
-        else // its another kind of archive
-        {
-            nsCOMPtr<nsIXPTLoader> loader =
-                do_GetService(NS_ZIPLOADER_CONTRACTID);
-            
-            if (loader) {
-                nsresult rv;
-                
-                nsCOMPtr<nsIXPTLoaderSink> sink =
-                    new xptiZipLoaderSink(this, aWorkingSet);
-                if (!sink)
-                    return PR_FALSE;
-                
-                rv = loader->EnumerateEntries(file, sink);
-                if (NS_FAILED(rv))
-                    return PR_FALSE;
-                // This will correspond to typelibRecord used in
-                // xptiInterfaceInfoManager::FoundEntry.
-                aWorkingSet->AppendFile(fileRecord);
-            } else {
-                NS_WARNING("Could not load XPT Zip loader");
-            }
-        }
+        loader->EnumerateEntries(aFile, this);
+        break;
     }
 
-    return PR_TRUE;
-}        
-
-PRBool 
-xptiInterfaceInfoManager::DoFullValidationMergeFromFileList(nsISupportsArray* aSearchPath,
-                                                            nsISupportsArray* aFileList,
-                                                            xptiWorkingSet* aWorkingSet)
-{
-    nsILocalFile** orderedFileArray;
-    PRUint32 countOfFilesInFileList;
-    PRUint32 i;
+    default:
+        NS_ERROR("Unexpected enumeration value");
+    }
+}
 
-    NS_ASSERTION(aFileList, "loser!");
-
-    if(!aWorkingSet->IsValid())
-        return PR_FALSE;
-
-    if(NS_FAILED(aFileList->Count(&countOfFilesInFileList)))
-        return PR_FALSE;
-
-    if(!countOfFilesInFileList)
-    {
-        // maybe there are no xpt files to register.  
-        // a minimal install would have this case.
-        return PR_TRUE;
+void
+xptiInterfaceInfoManager::RegisterXPTHeader(XPTHeader* aHeader)
+{
+    if (aHeader->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
+        NS_ASSERTION(!aHeader->num_interfaces,"bad libxpt");
+        LOG_AUTOREG(("      file is version %d.%d  Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION));
     }
 
-    orderedFileArray = BuildOrderedFileArray(aSearchPath, aFileList, aWorkingSet);
-
-    if(!orderedFileArray)
-        return PR_FALSE;
-
-    // DEBUG_DumpFileArray(orderedFileArray, countOfFilesInFileList);
-
-    // Make space in aWorkingset for a new xptiFile array.
-
-    if(!aWorkingSet->NewFileArray(countOfFilesInFileList))   
-        return PR_FALSE;
-
-    aWorkingSet->ClearZipItems();
-    aWorkingSet->ClearHashTables();
-
-    // For each file, add any valid interfaces that don't conflict with 
-    // previous interfaces added.
-    for(i = 0; i < countOfFilesInFileList; i++)
-    {
-        nsILocalFile* file = orderedFileArray[i];
+    xptiTypelibGuts* typelib = xptiTypelibGuts::Create(aHeader);
 
-        nsCAutoString name;
-        PRInt64 size;
-        PRInt64 date;
-        PRUint32 dir;
-        if(NS_FAILED(file->GetFileSize(&size)) ||
-           NS_FAILED(file->GetLastModifiedTime(&date)) ||
-           NS_FAILED(file->GetNativeLeafName(name)) ||
-           !aWorkingSet->FindDirectoryOfFile(file, &dir))
-        {
-            return PR_FALSE;
-        }    
-
-        LOG_AUTOREG(("  finding interfaces in file: %s\n", name.get()));
-    
-        xptiFile fileRecord;
-        fileRecord = xptiFile(nsInt64(size), nsInt64(date), dir,
-                              name.get(), aWorkingSet);
-
-//        printf("* found %s\n", fileRecord.GetName());
-
-
-        if(xptiFileType::IsXPT(fileRecord.GetName()))
-        {
-            XPTHeader* header = ReadXPTFile(file, aWorkingSet);
-            if(!header)
-            {
-                // XXX do something!
-                NS_ERROR("Unable to read an XPT file, turn logging on to see which file");    
-                LOG_AUTOREG(("      unable to read file\n"));
-                continue;
-            }
-    
-            xptiTypelib typelibRecord;
-            typelibRecord.Init(aWorkingSet->GetFileCount());
-    
-            PRBool AddedFile = PR_FALSE;
-
-            if(header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION)
-            {
-                NS_ASSERTION(!header->num_interfaces,"bad libxpt");
-                LOG_AUTOREG(("      file is version %d.%d  Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION));
-            }
+    for(PRUint16 k = 0; k < aHeader->num_interfaces; k++)
+        VerifyAndAddEntryIfNew(aHeader->interface_directory + k, k, typelib);
+}
 
-            for(PRUint16 k = 0; k < header->num_interfaces; k++)
-            {
-                xptiInterfaceEntry* entry = nsnull;
-    
-                if(!VerifyAndAddEntryIfNew(aWorkingSet,
-                                           header->interface_directory + k,
-                                           typelibRecord,
-                                           &entry))
-                    return PR_FALSE;    
-    
-                if(!entry)
-                    continue;
-                
-                // If this is the first interface we found for this file then
-                // setup the fileRecord for the header and infos.
-                if(!AddedFile)
-                {
-                    if(!fileRecord.SetHeader(header, aWorkingSet))
-                    {
-                        // XXX that would be bad.
-                        return PR_FALSE;    
-                    }
-                    AddedFile = PR_TRUE;
-                }
-                fileRecord.GetGuts()->SetEntryAt(k, entry);
-            }
-            
-            // This will correspond to typelibRecord above.
-            aWorkingSet->AppendFile(fileRecord);
-        }
-
-        else
-        {
-            nsCOMPtr<nsIXPTLoader> loader =
-                do_GetService(NS_ZIPLOADER_CONTRACTID);
-            
-            if (loader) {
-                nsresult rv;
-                
-                nsCOMPtr<nsIXPTLoaderSink> sink =
-                    new xptiZipLoaderSink(this, aWorkingSet);
-                if (!sink)
-                    return PR_FALSE;
-                
-                rv = loader->EnumerateEntries(file, sink);
-                if (NS_FAILED(rv))
-                    return PR_FALSE;
-                // This will correspond to typelibRecord used in
-                // xptiInterfaceInfoManager::FoundEntry.
-                aWorkingSet->AppendFile(fileRecord);
-            } else {
-                NS_WARNING("Could not load XPT Zip loader");
-            }
-        }
-    }
-    return PR_TRUE;
-}        
-
-NS_IMPL_ISUPPORTS1(xptiZipLoaderSink, nsIXPTLoaderSink)
-
-// implement nsIXPTLoader
 NS_IMETHODIMP
-xptiZipLoaderSink::FoundEntry(const char* entryName,
-                              PRInt32 index,
-                              nsIInputStream *aStream)
+xptiInterfaceInfoManager::FoundEntry(const char* entryName, PRInt32 index, nsIInputStream* aStream)
 {
-    XPTHeader *header =
-        xptiZipLoader::ReadXPTFileFromInputStream(aStream, mWorkingSet);
-    if (!header)
-        return NS_ERROR_OUT_OF_MEMORY;
-    
-    if (!mManager->FoundZipEntry(entryName, index, header, mWorkingSet))
-        return NS_ERROR_FAILURE;
-    
+    XPTHeader* header = ReadXPTFileFromInputStream(aStream);
+    if (header)
+        RegisterXPTHeader(header);
     return NS_OK;
 }
 
-// implement xptiEntrySink
-PRBool 
-xptiInterfaceInfoManager::FoundZipEntry(const char* entryName,
-                                        int index,
-                                        XPTHeader* header,
-                                        xptiWorkingSet* aWorkingSet)
+void
+xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
+                                                 PRUint16 idx,
+                                                 xptiTypelibGuts* typelib)
 {
-
-    NS_ASSERTION(entryName, "loser!");
-    NS_ASSERTION(header, "loser!");
-    NS_ASSERTION(aWorkingSet, "loser!");
-
-    int countOfInterfacesAddedForItem = 0;
-    xptiZipItem zipItemRecord(entryName, aWorkingSet);
-    
-    LOG_AUTOREG(("    finding interfaces in file: %s\n", entryName));
-
-    if(header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION)
-    {
-        NS_ASSERTION(!header->num_interfaces,"bad libxpt");
-        LOG_AUTOREG(("      file is version %d.%d. Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION));
-    }
-
-    if(!header->num_interfaces)
-    {
-        // We are not interested in files without interfaces.
-        return PR_TRUE;
-    }
-    
-    xptiTypelib typelibRecord;
-    typelibRecord.Init(aWorkingSet->GetFileCount(),
-                       aWorkingSet->GetZipItemCount());
-
-    for(PRUint16 k = 0; k < header->num_interfaces; k++)
-    {
-        xptiInterfaceEntry* entry = nsnull;
-    
-        if(!VerifyAndAddEntryIfNew(aWorkingSet,
-                                   header->interface_directory + k,
-                                   typelibRecord,
-                                   &entry))
-            return PR_FALSE;    
+    if (!iface->interface_descriptor)
+        return;
     
-        if(!entry)
-            continue;
-
-        // If this is the first interface we found for this item
-        // then setup the zipItemRecord for the header and infos.
-        if(!countOfInterfacesAddedForItem)
-        {
-            // XXX fix this!
-            if(!zipItemRecord.SetHeader(header, aWorkingSet))
-            {
-                // XXX that would be bad.
-                return PR_FALSE;    
-            }
-        }
-
-        // zipItemRecord.GetGuts()->SetEntryAt(k, entry);
-        ++countOfInterfacesAddedForItem;
-    }   
-
-    if(countOfInterfacesAddedForItem)
-    {
-        if(!aWorkingSet->GetZipItemFreeSpace())
-        {
-            if(!aWorkingSet->ExtendZipItemArray(
-                aWorkingSet->GetZipItemCount() + 20))
-            {        
-                // out of space!
-                return PR_FALSE;    
-            }
-        }
-        aWorkingSet->AppendZipItem(zipItemRecord);
-    } 
-    return PR_TRUE;
-}
-
-PRBool 
-xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(xptiWorkingSet* aWorkingSet,
-                                                 XPTInterfaceDirectoryEntry* iface,
-                                                 const xptiTypelib& typelibRecord,
-                                                 xptiInterfaceEntry** entryAdded)
-{
-    NS_ASSERTION(iface, "loser!");
-    NS_ASSERTION(entryAdded, "loser!");
-
-    *entryAdded = nsnull;
-
-    if(!iface->interface_descriptor)
-    {
-        // Not resolved, ignore this one.
-        // XXX full logging might note this...
-        return PR_TRUE;
-    }
-    
-    xptiHashEntry* hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(aWorkingSet->mIIDTable, &iface->iid, PL_DHASH_LOOKUP);
-
-    xptiInterfaceEntry* entry = 
-        PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value;
-    
-    if(entry)
-    {
+    xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(iface->iid);
+    if (entry) {
         // XXX validate this info to find possible inconsistencies
         LOG_AUTOREG(("      ignoring repeated interface: %s\n", iface->name));
-        return PR_TRUE;
+        return;
     }
     
     // Build a new xptiInterfaceEntry object and hook it up. 
 
-    entry = xptiInterfaceEntry::NewEntry(iface->name, strlen(iface->name),
-                                         iface->iid,
-                                         typelibRecord, aWorkingSet);
-    if(!entry)
-    {
-        // XXX bad!
-        return PR_FALSE;    
-    }
+    entry = xptiInterfaceEntry::Create(iface->name,
+                                       iface->iid,
+                                       iface->interface_descriptor,
+                                       typelib);
+    if (!entry)
+        return;
 
     //XXX  We should SetHeader too as part of the validation, no?
     entry->SetScriptableFlag(XPT_ID_IS_SCRIPTABLE(iface->interface_descriptor->flags));
 
-    // Add our entry to the iid hashtable.
+    mWorkingSet.mIIDTable.Put(entry->IID(), entry);
+    mWorkingSet.mNameTable.Put(entry->GetTheName(), entry);
 
-    hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(aWorkingSet->mNameTable, 
-                             entry->GetTheName(), PL_DHASH_ADD);
-    if(hashEntry)
-        hashEntry->value = entry;
-    
-    // Add our entry to the name hashtable.
-
-    hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(aWorkingSet->mIIDTable, 
-                             entry->GetTheIID(), PL_DHASH_ADD);
-    if(hashEntry)
-        hashEntry->value = entry;
-    
-    *entryAdded = entry;
+    typelib->SetEntryAt(idx, entry);
 
     LOG_AUTOREG(("      added interface: %s\n", iface->name));
-
-    return PR_TRUE;
 }
 
-// local struct used to pass two pointers as one pointer
-struct TwoWorkingSets
-{
-    TwoWorkingSets(xptiWorkingSet* src, xptiWorkingSet* dest)
-        : aSrcWorkingSet(src), aDestWorkingSet(dest) {}
-
-    xptiWorkingSet* aSrcWorkingSet;
-    xptiWorkingSet* aDestWorkingSet;
-};        
-
-static PLDHashOperator
-xpti_Merger(PLDHashTable *table, PLDHashEntryHdr *hdr,
-            PRUint32 number, void *arg)
-{
-    xptiInterfaceEntry* srcEntry = ((xptiHashEntry*)hdr)->value;
-    xptiWorkingSet* aSrcWorkingSet = ((TwoWorkingSets*)arg)->aSrcWorkingSet;
-    xptiWorkingSet* aDestWorkingSet = ((TwoWorkingSets*)arg)->aDestWorkingSet;
-
-    xptiHashEntry* hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(aDestWorkingSet->mIIDTable, 
-                             srcEntry->GetTheIID(), PL_DHASH_LOOKUP);
-
-    xptiInterfaceEntry* destEntry = 
-        PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value;
-    
-    if(destEntry)
-    {
-        // Let's see if this is referring to the same exact typelib
-         
-        const char* destFilename = 
-            aDestWorkingSet->GetTypelibFileName(destEntry->GetTypelibRecord());
-        
-        const char* srcFilename = 
-            aSrcWorkingSet->GetTypelibFileName(srcEntry->GetTypelibRecord());
-    
-        if(0 == PL_strcmp(destFilename, srcFilename) && 
-           (destEntry->GetTypelibRecord().GetZipItemIndex() ==
-            srcEntry->GetTypelibRecord().GetZipItemIndex()))
-        {
-            // This is the same item.
-            // But... Let's make sure they didn't change the interface name.
-            // There are wacky developers that do stuff like that!
-            if(0 == PL_strcmp(destEntry->GetTheName(), srcEntry->GetTheName()))
-                return PL_DHASH_NEXT;
-        }
-    }
-    
-    // Clone the xptiInterfaceEntry into our destination WorkingSet.
-
-    xptiTypelib typelibRecord;
-
-    uint16 fileIndex = srcEntry->GetTypelibRecord().GetFileIndex();
-    uint16 zipItemIndex = srcEntry->GetTypelibRecord().GetZipItemIndex();
-    
-    fileIndex += aDestWorkingSet->mFileMergeOffsetMap[fileIndex];
-    
-    // If it is not a zipItem, then the original index is fine.
-    if(srcEntry->GetTypelibRecord().IsZip())
-        zipItemIndex += aDestWorkingSet->mZipItemMergeOffsetMap[zipItemIndex];
-
-    typelibRecord.Init(fileIndex, zipItemIndex);
-                
-    destEntry = xptiInterfaceEntry::NewEntry(*srcEntry, typelibRecord, 
-                                             aDestWorkingSet);
-    if(!destEntry)
-    {
-        // XXX bad! should log
-        return PL_DHASH_NEXT;
-    }
-
-
-    // Add our entry to the iid hashtable.
-
-    hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(aDestWorkingSet->mNameTable, 
-                             destEntry->GetTheName(), PL_DHASH_ADD);
-    if(hashEntry)
-        hashEntry->value = destEntry;
-    
-    // Add our entry to the name hashtable.
-
-    hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(aDestWorkingSet->mIIDTable, 
-                             destEntry->GetTheIID(), PL_DHASH_ADD);
-    if(hashEntry)
-        hashEntry->value = destEntry;
-
-    return PL_DHASH_NEXT;
-}       
-
-PRBool 
-xptiInterfaceInfoManager::MergeWorkingSets(xptiWorkingSet* aDestWorkingSet,
-                                           xptiWorkingSet* aSrcWorkingSet)
-{
-
-    PRUint32 i;
-
-    // Combine file lists.
-
-    PRUint32 originalFileCount = aDestWorkingSet->GetFileCount();
-    PRUint32 additionalFileCount = aSrcWorkingSet->GetFileCount();
-
-    // Create a new array big enough to hold both lists and copy existing files
-
-    if(additionalFileCount)
-    {
-        if(!aDestWorkingSet->ExtendFileArray(originalFileCount +
-                                             additionalFileCount))
-            return PR_FALSE;
-    
-        // Now we are where we started, but we know we have enough space.
-    
-        // Prepare offset array for later fixups. 
-        // NOTE: Storing with dest, but alloc'ing from src. This is intentional.
-        aDestWorkingSet->mFileMergeOffsetMap = (PRUint32*)
-            XPT_CALLOC(aSrcWorkingSet->GetStructArena(),
-                       additionalFileCount * sizeof(PRUint32)); 
-        if(!aDestWorkingSet->mFileMergeOffsetMap)
-            return PR_FALSE;
-    }
-
-    for(i = 0; i < additionalFileCount; ++i)
-    {
-        xptiFile& srcFile = aSrcWorkingSet->GetFileAt(i);
-        PRUint32 k;
-        for(k = 0; k < originalFileCount; ++k)
-        {
-            // If file (with same name, date, and time) is in both lists
-            // then reuse that record.
-            xptiFile& destFile = aDestWorkingSet->GetFileAt(k);
-            if(srcFile.Equals(destFile))
-            {
-                aDestWorkingSet->mFileMergeOffsetMap[i] = k - i;
-                break;    
-            }
-        }
-        if(k == originalFileCount)
-        {
-            // No match found, tack it on the end.
-
-            PRUint32 newIndex = aDestWorkingSet->GetFileCount();
-
-            aDestWorkingSet->AppendFile(xptiFile(srcFile, aDestWorkingSet));
-
-            // Fixup the merge offset map.
-            aDestWorkingSet->mFileMergeOffsetMap[i] = newIndex - i;
-        }
-    }
-
-    // Combine ZipItem lists.
-
-    PRUint32 originalZipItemCount = aDestWorkingSet->GetZipItemCount();
-    PRUint32 additionalZipItemCount = aSrcWorkingSet->GetZipItemCount();
-
-    // Create a new array big enough to hold both lists and copy existing ZipItems
-
-    if(additionalZipItemCount)
-    {
-        if(!aDestWorkingSet->ExtendZipItemArray(originalZipItemCount +
-                                                additionalZipItemCount))
-            return PR_FALSE;
-    
-        // Now we are where we started, but we know we have enough space.
-    
-        // Prepare offset array for later fixups. 
-        // NOTE: Storing with dest, but alloc'ing from src. This is intentional.
-        aDestWorkingSet->mZipItemMergeOffsetMap = (PRUint32*)
-            XPT_CALLOC(aSrcWorkingSet->GetStructArena(),
-                       additionalZipItemCount * sizeof(PRUint32)); 
-        if(!aDestWorkingSet->mZipItemMergeOffsetMap)
-            return PR_FALSE;
-    }
-
-    for(i = 0; i < additionalZipItemCount; ++i)
-    {
-        xptiZipItem& srcZipItem = aSrcWorkingSet->GetZipItemAt(i);
-        PRUint32 k;
-        for(k = 0; k < originalZipItemCount; ++k)
-        {
-            // If ZipItem (with same name) is in both lists
-            // then reuse that record.
-            xptiZipItem& destZipItem = aDestWorkingSet->GetZipItemAt(k);
-            if(srcZipItem.Equals(destZipItem))
-            {
-                aDestWorkingSet->mZipItemMergeOffsetMap[i] = k - i;
-                break;    
-            }
-        }
-        if(k == originalZipItemCount)
-        {
-            // No match found, tack it on the end.
-
-            PRUint32 newIndex = aDestWorkingSet->GetZipItemCount();
-
-            aDestWorkingSet->AppendZipItem(
-                    xptiZipItem(srcZipItem, aDestWorkingSet));
-
-            // Fixup the merge offset map.
-            aDestWorkingSet->mZipItemMergeOffsetMap[i] = newIndex - i;
-        }
-    }
-
-    // Migrate xptiInterfaceInfos
-
-    TwoWorkingSets sets(aSrcWorkingSet, aDestWorkingSet);
-
-    PL_DHashTableEnumerate(aSrcWorkingSet->mNameTable, xpti_Merger, &sets);
-
-    return PR_TRUE;
-}        
-
-PRBool 
-xptiInterfaceInfoManager::DEBUG_DumpFileList(nsISupportsArray* aFileList)
-{
-    PRUint32 count;
-
-    if(NS_FAILED(aFileList->Count(&count)))
-        return PR_FALSE;
-    
-    for(PRUint32 i = 0; i < count; i++)
-    {
-        nsCOMPtr<nsIFile> file;
-        aFileList->QueryElementAt(i, NS_GET_IID(nsILocalFile), getter_AddRefs(file));
-        if(!file)
-            return PR_FALSE;
-
-        nsCAutoString name;
-        if(NS_FAILED(file->GetNativeLeafName(name)))
-            return PR_FALSE;
-
-        printf("* found %s\n", name.get());
-    }
-    return PR_TRUE;
-}
-
-PRBool 
-xptiInterfaceInfoManager::DEBUG_DumpFileListInWorkingSet(xptiWorkingSet* aWorkingSet)
-{
-    for(PRUint16 i = 0; i < aWorkingSet->GetFileCount(); ++i)
-    {
-        xptiFile& record = aWorkingSet->GetFileAt(i);
-    
-        printf("! has %s\n", record.GetName());
-    }        
-    return PR_TRUE;
-}        
-
-PRBool 
-xptiInterfaceInfoManager::DEBUG_DumpFileArray(nsILocalFile** aFileArray, 
-                                              PRUint32 count)
-{
-    // dump the sorted list
-    for(PRUint32 i = 0; i < count; ++i)
-    {
-        nsILocalFile* file = aFileArray[i];
-    
-        nsCAutoString name;
-        if(NS_FAILED(file->GetNativeLeafName(name)))
-            return PR_FALSE;
-
-        printf("found file: %s\n", name.get());
-    }        
-    return PR_TRUE;        
-}        
-
-/***************************************************************************/
-
-// static 
-void 
-xptiInterfaceInfoManager::WriteToLog(const char *fmt, ...)
-{
-    if(!gInterfaceInfoManager)
-        return;
-
-    PRFileDesc* fd = gInterfaceInfoManager->GetOpenLogFile();
-    if(fd)
-    {
-        va_list ap;
-        va_start(ap, fmt);
-        PR_vfprintf(fd, fmt, ap);
-        va_end(ap);
-    }
-}        
-
-static PLDHashOperator
-xpti_ResolvedFileNameLogger(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                            PRUint32 number, void *arg)
-{
-    xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
-    xptiInterfaceInfoManager* mgr = (xptiInterfaceInfoManager*) arg;
-
-    if(entry->IsFullyResolved())
-    {
-        xptiWorkingSet*  aWorkingSet = mgr->GetWorkingSet();
-        PRFileDesc* fd = mgr->GetOpenLogFile();
-
-        const xptiTypelib& typelib = entry->GetTypelibRecord();
-        const char* filename = 
-                aWorkingSet->GetFileAt(typelib.GetFileIndex()).GetName();
-        
-        if(typelib.IsZip())
-        {
-            const char* zipItemName = 
-                aWorkingSet->GetZipItemAt(typelib.GetZipItemIndex()).GetName();
-            PR_fprintf(fd, "xpti used interface: %s from %s::%s\n", 
-                       entry->GetTheName(), filename, zipItemName);
-        }    
-        else
-        {
-            PR_fprintf(fd, "xpti used interface: %s from %s\n", 
-                       entry->GetTheName(), filename);
-        }
-    }
-    return PL_DHASH_NEXT;
-}
-
-void   
-xptiInterfaceInfoManager::LogStats()
-{
-    PRUint32 i;
-    
-    // This sets what will be returned by GetOpenLogFile().
-    xptiAutoLog autoLog(this, mStatsLogFile, PR_FALSE);
-
-    PRFileDesc* fd = GetOpenLogFile();
-    if(!fd)
-        return;
-
-    // Show names of xpt (only) files from which at least one interface 
-    // was resolved.
-
-    PRUint32 fileCount = mWorkingSet.GetFileCount();
-    for(i = 0; i < fileCount; ++i)
-    {
-        xptiFile& f = mWorkingSet.GetFileAt(i);
-        if(f.GetGuts())
-            PR_fprintf(fd, "xpti used file: %s\n", f.GetName());
-    }
-
-    PR_fprintf(fd, "\n");
-
-    // Show names of xptfiles loaded from zips from which at least 
-    // one interface was resolved.
-
-    PRUint32 zipItemCount = mWorkingSet.GetZipItemCount();
-    for(i = 0; i < zipItemCount; ++i)
-    {
-        xptiZipItem& zi = mWorkingSet.GetZipItemAt(i);
-        if(zi.GetGuts())                           
-            PR_fprintf(fd, "xpti used file from zip: %s\n", zi.GetName());
-    }
-
-    PR_fprintf(fd, "\n");
-
-    // Show name of each interface that was fully resolved and the name
-    // of the file and (perhaps) zip from which it was loaded.
-
-    PL_DHashTableEnumerate(mWorkingSet.mNameTable, 
-                           xpti_ResolvedFileNameLogger, this);
-
-} 
-
-/***************************************************************************/
-
 // this is a private helper
 static nsresult 
 EntryToInfo(xptiInterfaceEntry* entry, nsIInterfaceInfo **_retval)
 {
     xptiInterfaceInfo* info;
     nsresult rv;
 
-    if(!entry)
-    {
+    if (!entry) {
         *_retval = nsnull;
         return NS_ERROR_FAILURE;    
     }
 
     rv = entry->GetInterfaceInfo(&info);
-    if(NS_FAILED(rv))
+    if (NS_FAILED(rv))
         return rv;
 
     // Transfer the AddRef done by GetInterfaceInfo.
     *_retval = static_cast<nsIInterfaceInfo*>(info);
     return NS_OK;    
 }
 
 xptiInterfaceEntry*
 xptiInterfaceInfoManager::GetInterfaceEntryForIID(const nsIID *iid)
 {
-    xptiHashEntry *hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(mWorkingSet.mIIDTable, iid, PL_DHASH_LOOKUP);
-    return PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value;
+    return mWorkingSet.mIIDTable.Get(*iid);
 }
 
 /* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval)
 {
     NS_ASSERTION(iid, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
@@ -1763,259 +408,183 @@ NS_IMETHODIMP xptiInterfaceInfoManager::
 }
 
 /* nsIInterfaceInfo getInfoForName (in string name); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForName(const char *name, nsIInterfaceInfo **_retval)
 {
     NS_ASSERTION(name, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    xptiHashEntry* hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(mWorkingSet.mNameTable, name, PL_DHASH_LOOKUP);
-
-    xptiInterfaceEntry* entry = 
-        PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value;
-
+    xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
     return EntryToInfo(entry, _retval);
 }
 
 /* nsIIDPtr getIIDForName (in string name); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetIIDForName(const char *name, nsIID * *_retval)
 {
     NS_ASSERTION(name, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    xptiHashEntry* hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(mWorkingSet.mNameTable, name, PL_DHASH_LOOKUP);
 
-    xptiInterfaceEntry* entry = 
-        PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value;
-
-    if(!entry)
-    {
+    xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
+    if (!entry) {
         *_retval = nsnull;
         return NS_ERROR_FAILURE;    
     }
 
     return entry->GetIID(_retval);
 }
 
 /* string getNameForIID (in nsIIDPtr iid); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetNameForIID(const nsIID * iid, char **_retval)
 {
     NS_ASSERTION(iid, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    xptiHashEntry* hashEntry = (xptiHashEntry*)
-        PL_DHashTableOperate(mWorkingSet.mIIDTable, iid, PL_DHASH_LOOKUP);
-
-    xptiInterfaceEntry* entry = 
-        PL_DHASH_ENTRY_IS_FREE(hashEntry) ? nsnull : hashEntry->value;
-
-    if(!entry)
-    {
+    xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
+    if (!entry) {
         *_retval = nsnull;
         return NS_ERROR_FAILURE;    
     }
 
     return entry->GetName(_retval);
 }
 
 static PLDHashOperator
-xpti_ArrayAppender(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                   PRUint32 number, void *arg)
+xpti_ArrayAppender(const char* name, xptiInterfaceEntry* entry, void* arg)
 {
-    xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
     nsISupportsArray* array = (nsISupportsArray*) arg;
 
     nsCOMPtr<nsIInterfaceInfo> ii;
-    if(NS_SUCCEEDED(EntryToInfo(entry, getter_AddRefs(ii))))
+    if (NS_SUCCEEDED(EntryToInfo(entry, getter_AddRefs(ii))))
         array->AppendElement(ii);
     return PL_DHASH_NEXT;
 }
 
 /* nsIEnumerator enumerateInterfaces (); */
 NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfaces(nsIEnumerator **_retval)
 {
     // I didn't want to incur the size overhead of using nsHashtable just to
     // make building an enumerator easier. So, this code makes a snapshot of 
     // the table using an nsISupportsArray and builds an enumerator for that.
     // We can afford this transient cost.
 
     nsCOMPtr<nsISupportsArray> array;
     NS_NewISupportsArray(getter_AddRefs(array));
-    if(!array)
+    if (!array)
         return NS_ERROR_UNEXPECTED;
 
-    PL_DHashTableEnumerate(mWorkingSet.mNameTable, xpti_ArrayAppender, array);
-    
+    mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayAppender, array);
+
     return array->Enumerate(_retval);
 }
 
 struct ArrayAndPrefix
 {
     nsISupportsArray* array;
     const char*       prefix;
     PRUint32          length;
 };
 
 static PLDHashOperator
-xpti_ArrayPrefixAppender(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                         PRUint32 number, void *arg)
+xpti_ArrayPrefixAppender(const char* keyname, xptiInterfaceEntry* entry, void* arg)
 {
-    xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
     ArrayAndPrefix* args = (ArrayAndPrefix*) arg;
 
     const char* name = entry->GetTheName();
-    if(name != PL_strnstr(name, args->prefix, args->length))
+    if (name != PL_strnstr(name, args->prefix, args->length))
         return PL_DHASH_NEXT;
 
     nsCOMPtr<nsIInterfaceInfo> ii;
-    if(NS_SUCCEEDED(EntryToInfo(entry, getter_AddRefs(ii))))
+    if (NS_SUCCEEDED(EntryToInfo(entry, getter_AddRefs(ii))))
         args->array->AppendElement(ii);
     return PL_DHASH_NEXT;
 }
 
 /* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */
 NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfacesWhoseNamesStartWith(const char *prefix, nsIEnumerator **_retval)
 {
     nsCOMPtr<nsISupportsArray> array;
     NS_NewISupportsArray(getter_AddRefs(array));
-    if(!array)
+    if (!array)
         return NS_ERROR_UNEXPECTED;
 
     ArrayAndPrefix args = {array, prefix, PL_strlen(prefix)};
-    PL_DHashTableEnumerate(mWorkingSet.mNameTable, xpti_ArrayPrefixAppender, &args);
-    
+    mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayPrefixAppender, &args);
+
     return array->Enumerate(_retval);
 }
 
 /* void autoRegisterInterfaces (); */
 NS_IMETHODIMP xptiInterfaceInfoManager::AutoRegisterInterfaces()
 {
     NS_TIME_FUNCTION;
 
-    nsCOMPtr<nsISupportsArray> fileList;
-    AutoRegMode mode;
-    PRBool ok;
-
     nsAutoLock lock(xptiInterfaceInfoManager::GetAutoRegLock(this));
 
-    xptiWorkingSet workingSet(mSearchPath);
-    if(!workingSet.IsValid())
-        return NS_ERROR_UNEXPECTED;
-
-    // This sets what will be returned by GetOpenLogFile().
-    xptiAutoLog autoLog(this, mAutoRegLogFile, PR_TRUE);
-
-    LOG_AUTOREG(("start AutoRegister\n"));
+    nsCOMPtr<nsILocalFile> components;
+    GetDirectoryFromDirService(NS_XPCOM_COMPONENT_DIR,
+                               getter_AddRefs(components));
+    if (components)
+        RegisterDirectory(components);
 
-    // We re-read the manifest rather than muck with the 'live' one.
-    // It is OK if this fails.
-    // XXX But we should track failure as a warning.
-    NS_TIME_FUNCTION_MARK("Next: read the manifest");
-    ok = xptiManifest::Read(this, &workingSet);
-
-    LOG_AUTOREG(("read of manifest %s\n", ok ? "successful" : "FAILED"));
-
-    // Grovel for all the typelibs we can find (in .xpt or .zip, .jar,...).
-    NS_TIME_FUNCTION_MARK("Next: build file list");
-    if(!BuildFileList(mSearchPath, getter_AddRefs(fileList)) || !fileList)
-        return NS_ERROR_UNEXPECTED;
-    
-    // DEBUG_DumpFileList(fileList);
-
-    // Check to see how much work we need to do.
-    NS_TIME_FUNCTION_MARK("Next: determining registration strategy");
-    mode = DetermineAutoRegStrategy(mSearchPath, fileList, &workingSet);
+    nsCOMPtr<nsILocalFile> greComponents;
+    GetDirectoryFromDirService(NS_GRE_COMPONENT_DIR, getter_AddRefs(greComponents));
+    PRBool equals = PR_FALSE;
+    if (greComponents &&
+        NS_SUCCEEDED(greComponents->Equals(components, &equals)) && !equals)
+        RegisterDirectory(greComponents);
 
-    switch(mode)
-    {
-    case NO_FILES_CHANGED:
-        LOG_AUTOREG(("autoreg strategy: no files changed\n"));
-        LOG_AUTOREG(("successful end of AutoRegister\n"));
-        return NS_OK;
-    case FILES_ADDED_ONLY:
-        LOG_AUTOREG(("autoreg strategy: files added only\n"));
-        NS_TIME_FUNCTION_MARK("Next: adding only new files");
-        if(!AddOnlyNewFilesFromFileList(mSearchPath, fileList, &workingSet))
-        {
-            LOG_AUTOREG(("FAILED to add new files\n"));
-            return NS_ERROR_UNEXPECTED;
-        }
-        break;
-    case FULL_VALIDATION_REQUIRED:
-        LOG_AUTOREG(("autoreg strategy: doing full validation merge\n"));
-        NS_TIME_FUNCTION_MARK("Next: full validation merge");
-        if(!DoFullValidationMergeFromFileList(mSearchPath, fileList, &workingSet))
-        {
-            LOG_AUTOREG(("FAILED to do full validation\n"));
-            return NS_ERROR_UNEXPECTED;
+    nsCOMPtr<nsIProperties> dirService = 
+        do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+    nsCOMPtr<nsISimpleEnumerator> fileList;
+    dirService->Get(NS_XPCOM_COMPONENT_DIR_LIST, NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(fileList));
+    if (fileList) {
+        PRBool more;
+        nsCOMPtr<nsISupports> supp;
+        while (NS_SUCCEEDED(fileList->HasMoreElements(&more)) && more) {
+            fileList->GetNext(getter_AddRefs(supp));
+            components = do_QueryInterface(supp);
+            if (components)
+                RegisterDirectory(components);
         }
-        break;
-    default:
-        NS_ERROR("switch missing a case");
-        return NS_ERROR_UNEXPECTED;
     }
 
-    // Failure to write the manifest is not fatal in production builds.
-    // However, this would require the next startup to find and read all the
-    // xpt files. This will make that startup slower. If this ever becomes a 
-    // chronic problem for anyone, then we'll want to figure out why!
-    
-    NS_TIME_FUNCTION_MARK("Next: writing manifest");
-    if(!xptiManifest::Write(this, &workingSet))
-    {
-        LOG_AUTOREG(("FAILED to write manifest\n"));
-        NS_ERROR("Failed to write xpti manifest!");
-    }
-    
-    NS_TIME_FUNCTION_MARK("Next: merging working sets");
-    if(!MergeWorkingSets(&mWorkingSet, &workingSet))
-    {
-        LOG_AUTOREG(("FAILED to merge into live workingset\n"));
-        return NS_ERROR_UNEXPECTED;
-    }
-
-//    DEBUG_DumpFileListInWorkingSet(mWorkingSet);
-
-    LOG_AUTOREG(("successful end of AutoRegister\n"));
-
     return NS_OK;
 }
 
 /***************************************************************************/
 
 /* void addAdditionalManager (in nsIInterfaceInfoManager manager); */
 NS_IMETHODIMP xptiInterfaceInfoManager::AddAdditionalManager(nsIInterfaceInfoManager *manager)
 {
     nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(manager);
     nsISupports* ptrToAdd = weakRef ? 
                     static_cast<nsISupports*>(weakRef) :
                     static_cast<nsISupports*>(manager);
     { // scoped lock...
         nsAutoLock lock(mAdditionalManagersLock);
-        if(mAdditionalManagers.IndexOf(ptrToAdd) != -1)
+        if (mAdditionalManagers.IndexOf(ptrToAdd) != -1)
             return NS_ERROR_FAILURE;
-        if(!mAdditionalManagers.AppendObject(ptrToAdd))
+        if (!mAdditionalManagers.AppendObject(ptrToAdd))
             return NS_ERROR_OUT_OF_MEMORY;
     }
     return NS_OK;
 }
 
 /* void removeAdditionalManager (in nsIInterfaceInfoManager manager); */
 NS_IMETHODIMP xptiInterfaceInfoManager::RemoveAdditionalManager(nsIInterfaceInfoManager *manager)
 {
     nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(manager);
     nsISupports* ptrToRemove = weakRef ? 
                     static_cast<nsISupports*>(weakRef) :
                     static_cast<nsISupports*>(manager);
     { // scoped lock...
         nsAutoLock lock(mAdditionalManagersLock);
-        if(!mAdditionalManagers.RemoveObject(ptrToRemove))
+        if (!mAdditionalManagers.RemoveObject(ptrToRemove))
             return NS_ERROR_FAILURE;
     }
     return NS_OK;
 }
 
 /* PRBool hasAdditionalManagers (); */
 NS_IMETHODIMP xptiInterfaceInfoManager::HasAdditionalManagers(PRBool *_retval)
 {
@@ -2025,33 +594,29 @@ NS_IMETHODIMP xptiInterfaceInfoManager::
 
 /* nsISimpleEnumerator enumerateAdditionalManagers (); */
 NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateAdditionalManagers(nsISimpleEnumerator **_retval)
 {
     nsAutoLock lock(mAdditionalManagersLock);
 
     nsCOMArray<nsISupports> managerArray(mAdditionalManagers);
     /* Resolve all the weak references in the array. */
-    for(PRInt32 i = managerArray.Count(); i--; )
-    {
+    for(PRInt32 i = managerArray.Count(); i--; ) {
         nsISupports *raw = managerArray.ObjectAt(i);
-        if(!raw)
+        if (!raw)
             return NS_ERROR_FAILURE;
         nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(raw);
-        if(weakRef)
-        {
+        if (weakRef) {
             nsCOMPtr<nsIInterfaceInfoManager> manager = 
                 do_QueryReferent(weakRef);
-            if(manager)
-            {
-                if(!managerArray.ReplaceObjectAt(manager, i))
+            if (manager) {
+                if (!managerArray.ReplaceObjectAt(manager, i))
                     return NS_ERROR_FAILURE;
             }
-            else
-            {
+            else {
                 // The manager is no more. Remove the element.
                 mAdditionalManagers.RemoveObjectAt(i);
                 managerArray.RemoveObjectAt(i);
             }
         }
     }
     
     return NS_NewArrayEnumerator(_retval, managerArray);
deleted file mode 100644
--- a/xpcom/reflect/xptinfo/src/xptiManifest.cpp
+++ /dev/null
@@ -1,694 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** 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.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Mike McCabe <mccabe@netscape.com>
- *   John Bandhauer <jband@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 ***** */
-
-/* Implementation of xptiManifest. */
-
-#include "xptiprivate.h"
-#include "nsManifestLineReader.h"
-#include "nsString.h"
-
-static const char g_Disclaimer[] = "# Generated file. ** DO NOT EDIT! **";
-
-static const char g_TOKEN_Files[]          = "Files";
-static const char g_TOKEN_ArchiveItems[]   = "ArchiveItems";
-static const char g_TOKEN_Interfaces[]     = "Interfaces";
-static const char g_TOKEN_Header[]         = "Header";
-static const char g_TOKEN_Version[]        = "Version";
-static const char g_TOKEN_AppDir[]         = "AppDir";
-static const char g_TOKEN_Directories[]    = "Directories";
-
-static const int  g_VERSION_MAJOR          = 2;
-static const int  g_VERSION_MINOR          = 0;
-
-/***************************************************************************/
-
-static PRBool 
-GetCurrentAppDirString(xptiInterfaceInfoManager* aMgr, nsACString &aStr)
-{
-    nsCOMPtr<nsILocalFile> appDir;
-    aMgr->GetApplicationDir(getter_AddRefs(appDir));
-    if(appDir)
-        return NS_SUCCEEDED(appDir->GetPersistentDescriptor(aStr));
-    return PR_FALSE;
-}
-
-static PRBool 
-CurrentAppDirMatchesPersistentDescriptor(xptiInterfaceInfoManager* aMgr, 
-                                         const char *inStr)
-{
-    nsCOMPtr<nsILocalFile> appDir;
-    aMgr->GetApplicationDir(getter_AddRefs(appDir));
-
-    nsCOMPtr<nsILocalFile> descDir;
-    nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, getter_AddRefs(descDir));
-    if(NS_FAILED(rv))
-        return PR_FALSE;
-
-    rv = descDir->SetPersistentDescriptor(nsDependentCString(inStr));
-    if(NS_FAILED(rv))
-        return PR_FALSE;
-    
-    PRBool matches;
-    rv = appDir->Equals(descDir, &matches);
-    return NS_SUCCEEDED(rv) && matches;
-}
-
-static PLDHashOperator
-xpti_InterfaceWriter(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                     PRUint32 number, void *arg)
-{
-    xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
-    PRFileDesc* fd = (PRFileDesc*)  arg;
-
-    char iidStr[NSID_LENGTH];
-    entry->GetTheIID()->ToProvidedString(iidStr);
-
-    const xptiTypelib& typelib = entry->GetTypelibRecord();
-
-    PRBool success =  !!PR_fprintf(fd, "%d,%s,%s,%d,%d,%d\n",
-                                   (int) number,
-                                   entry->GetTheName(),
-                                   iidStr,
-                                   (int) typelib.GetFileIndex(),
-                                   (int) (typelib.IsZip() ? 
-                                   typelib.GetZipItemIndex() : -1),
-                                   (int) entry->GetScriptableFlag());
-
-    return success ? PL_DHASH_NEXT : PL_DHASH_STOP;
-}
-
-
-// static
-PRBool xptiManifest::Write(xptiInterfaceInfoManager* aMgr,
-                           xptiWorkingSet*           aWorkingSet)
-{
-
-    PRBool succeeded = PR_FALSE;
-    PRFileDesc* fd = nsnull;
-    PRUint32 i;
-    PRUint32 size32;
-    PRIntn interfaceCount = 0;
-    nsCAutoString appDirString;
-    
-    nsCOMPtr<nsILocalFile> tempFile;
-    if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(tempFile)) || !tempFile)
-        return PR_FALSE;
-
-    nsCAutoString originalLeafName;
-    tempFile->GetNativeLeafName(originalLeafName);
-
-    nsCAutoString leafName;
-    leafName.Assign(originalLeafName + NS_LITERAL_CSTRING(".tmp"));
-
-    tempFile->SetNativeLeafName(leafName);
-
-    // All exits via "goto out;" from here on...
-    if(NS_FAILED(tempFile->
-                 OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
-                                  0666, &fd)) || !fd)
-    {
-        goto out;
-    }
-
-    // write file header comments
-
-    if(!PR_fprintf(fd, "%s\n", g_Disclaimer))
-        goto out;
-
-    // write the [Header] block, version number, and appdir.
-
-    if(!PR_fprintf(fd, "\n[%s,%d]\n", g_TOKEN_Header, 2))
-        goto out;
-
-    if(!PR_fprintf(fd, "%d,%s,%d,%d\n", 
-                       0, g_TOKEN_Version, g_VERSION_MAJOR, g_VERSION_MINOR))
-        goto out;
-
-    GetCurrentAppDirString(aMgr, appDirString);
-    if(appDirString.IsEmpty())
-        goto out;
-
-    if(!PR_fprintf(fd, "%d,%s,%s\n", 
-                       1, g_TOKEN_AppDir, appDirString.get()))
-        goto out;
-
-    // write Directories list
-
-    if(!PR_fprintf(fd, "\n[%s,%d]\n", 
-                       g_TOKEN_Directories, 
-                       (int) aWorkingSet->GetDirectoryCount()))
-        goto out;
-
-    for(i = 0; i < aWorkingSet->GetDirectoryCount(); i++)
-    {
-        nsCOMPtr<nsILocalFile> dir;        
-        nsCAutoString str;
-
-        aWorkingSet->GetDirectoryAt(i, getter_AddRefs(dir));
-        if(!dir)
-            goto out;
-
-        dir->GetPersistentDescriptor(str);
-        if(str.IsEmpty())
-            goto out;
-        
-        if(!PR_fprintf(fd, "%d,%s\n", (int) i, str.get()))
-            goto out;
-    }
-
-    // write Files list
-
-    if(!PR_fprintf(fd, "\n[%s,%d]\n", 
-                       g_TOKEN_Files, 
-                       (int) aWorkingSet->GetFileCount()))
-        goto out;
-
-    for(i = 0; i < aWorkingSet->GetFileCount(); i++)
-    {
-        const xptiFile& file = aWorkingSet->GetFileAt(i);
-
-        LL_L2UI(size32, file.GetSize());
-    
-        if(!PR_fprintf(fd, "%d,%s,%d,%u,%lld\n",
-                           (int) i,
-                           file.GetName(),
-                           (int) file.GetDirectory(),
-                           size32, PRInt64(file.GetDate())))
-        goto out;
-    }
-
-    // write ArchiveItems list
-
-    if(!PR_fprintf(fd, "\n[%s,%d]\n", 
-                       g_TOKEN_ArchiveItems, 
-                       (int) aWorkingSet->GetZipItemCount()))
-        goto out;
-
-    for(i = 0; i < aWorkingSet->GetZipItemCount(); i++)
-    {
-        if(!PR_fprintf(fd, "%d,%s\n",
-                           (int) i,
-                           aWorkingSet->GetZipItemAt(i).GetName()))
-        goto out;
-    }
-
-    // write the Interfaces list
-
-    interfaceCount = aWorkingSet->mNameTable->entryCount;
-
-    if(!PR_fprintf(fd, "\n[%s,%d]\n", 
-                       g_TOKEN_Interfaces, 
-                       (int) interfaceCount))
-        goto out;
-
-    if(interfaceCount != (PRIntn)
-        PL_DHashTableEnumerate(aWorkingSet->mNameTable, 
-                               xpti_InterfaceWriter, fd))
-        goto out;
-
-
-    if(PR_SUCCESS == PR_Close(fd))
-    {
-        succeeded = PR_TRUE;
-    }
-    fd = nsnull;
-
-out:
-    if(fd)
-        PR_Close(fd);
-    
-    if(succeeded)
-    {
-        // delete the old file and rename this
-        nsCOMPtr<nsILocalFile> mainFile;
-        if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(mainFile)) || !mainFile)
-            return PR_FALSE;
-    
-        PRBool exists;
-        if(NS_FAILED(mainFile->Exists(&exists)))
-            return PR_FALSE;
-
-        if(exists && NS_FAILED(mainFile->Remove(PR_FALSE)))
-            return PR_FALSE;
-    
-        nsCOMPtr<nsIFile> parent;
-        mainFile->GetParent(getter_AddRefs(parent));
-            
-        // MoveTo means rename.
-        if(NS_FAILED(tempFile->MoveToNative(parent, originalLeafName)))
-            return PR_FALSE;
-    }
-
-    return succeeded;
-}        
-
-/***************************************************************************/
-/***************************************************************************/
-
-static char* 
-ReadManifestIntoMemory(xptiInterfaceInfoManager* aMgr,
-                       PRUint32* pLength)
-{
-    PRFileDesc* fd = nsnull;
-    PRInt32 flen;
-    PRInt64 fileSize;
-    char* whole = nsnull;
-    PRBool success = PR_FALSE;
-
-    nsCOMPtr<nsILocalFile> aFile;
-    if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(aFile)) || !aFile)
-        return nsnull;
-
-    if(NS_FAILED(aFile->GetFileSize(&fileSize)) || !(flen = nsInt64(fileSize)))
-        return nsnull;
-
-    whole = new char[flen];
-    if (!whole)
-        return nsnull;
-
-    // All exits from on here should be via 'goto out' 
-
-    if(NS_FAILED(aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd)
-        goto out;
-
-    if(flen > PR_Read(fd, whole, flen))
-        goto out;
-
-    success = PR_TRUE;
-
- out:
-    if(fd)
-        PR_Close(fd);
-
-    if(!success)     
-    {
-        delete [] whole;
-        return nsnull;
-    }
-
-    *pLength = flen;
-    return whole;    
-}
-
-static
-PRBool ReadSectionHeader(nsManifestLineReader& reader, 
-                         const char *token, int minCount, int* count)
-{
-    while(1)
-    {
-        if(!reader.NextLine())
-            break;
-        if(*reader.LinePtr() == '[')
-        {
-            char* p = reader.LinePtr() + (reader.LineLength() - 1);
-            if(*p != ']')
-                break;
-            *p = 0;
-
-            char* values[2];
-            int lengths[2];
-            if(2 != reader.ParseLine(values, lengths, 2))
-                break;
-
-            // ignore the leading '['
-            if(0 != PL_strcmp(values[0]+1, token))
-                break;
-
-            if((*count = atoi(values[1])) < minCount)
-                break;
-            
-            return PR_TRUE;
-        }
-    }
-    return PR_FALSE;
-}
-
-
-// static
-PRBool xptiManifest::Read(xptiInterfaceInfoManager* aMgr,
-                          xptiWorkingSet*           aWorkingSet)
-{
-    int i;
-    char* whole = nsnull;
-    PRBool succeeded = PR_FALSE;
-    PRUint32 flen;
-    nsManifestLineReader reader;
-    xptiHashEntry* hashEntry;
-    int headerCount = 0;
-    int dirCount = 0;
-    int fileCount = 0;
-    int zipItemCount = -1;
-    int interfaceCount = 0;
-    int dir;
-    int flags;
-    char* values[6];    // 6 is currently the max items we need to parse
-    int lengths[6];
-    PRUint32 size32;
-    PRInt64 size;
-    PRInt64 date;
-
-    whole = ReadManifestIntoMemory(aMgr, &flen);
-    if(!whole)
-        return PR_FALSE;
-
-    reader.Init(whole, flen);
-
-    // All exits from here on should be via 'goto out' 
-    
-    // Look for "Header" section
-
-    // This version accepts only version 1,0. We also freak if the header
-    // has more than one entry. The rationale is that we want to force an
-    // autoreg if the xpti.dat file was written by *any* other version of
-    // the software. Future versions may wish to support updating older
-    // manifests in some interesting way.
-
-    if(!ReadSectionHeader(reader, g_TOKEN_Header, 2, &headerCount))
-        goto out;
-
-    if(headerCount != 2)
-        goto out;
-
-    // Verify the version number
-
-    if(!reader.NextLine())
-        goto out;
-
-    // index,VersionLiteral,major,minor
-    if(4 != reader.ParseLine(values, lengths, 4))
-        goto out;
-
-    // index
-    if(0 != atoi(values[0]))
-        goto out;
-
-    // VersionLiteral
-    if(0 != PL_strcmp(values[1], g_TOKEN_Version))
-        goto out;
-
-    // major
-    if(g_VERSION_MAJOR != atoi(values[2]))
-        goto out;
-
-    // minor
-    if(g_VERSION_MINOR != atoi(values[3]))
-        goto out;
-
-    // Verify the application directory
-
-    if(!reader.NextLine())
-        goto out;
-
-    // index,AppDirLiteral,directoryname
-    if(3 != reader.ParseLine(values, lengths, 3))
-        goto out;
-
-    // index
-    if(1 != atoi(values[0]))
-        goto out;
-
-    // AppDirLiteral
-    if(0 != PL_strcmp(values[1], g_TOKEN_AppDir))
-        goto out;
-
-    if(!CurrentAppDirMatchesPersistentDescriptor(aMgr, values[2]))
-        goto out;
-
-    // Look for "Directories" section
-
-    if(!ReadSectionHeader(reader, g_TOKEN_Directories, 1, &dirCount))
-        goto out;
-    else
-    {
-        // To validate that the directory list matches the current search path
-        // we first confirm that the list lengths match.
-
-        nsCOMPtr<nsISupportsArray> searchPath;
-        aMgr->GetSearchPath(getter_AddRefs(searchPath));
-
-        PRUint32 searchPathCount;
-        searchPath->Count(&searchPathCount);
-        
-        if(dirCount != (int) searchPathCount)
-            goto out;
-    }
-
-    // Read the directory records
-
-    for(i = 0; i < dirCount; ++i)
-    {
-        if(!reader.NextLine())
-            goto out;
-       
-        // index,directoryname
-        if(2 != reader.ParseLine(values, lengths, 2))
-            goto out;
-
-        // index
-        if(i != atoi(values[0]))
-            goto out;
-
-        // directoryname
-        if(!aWorkingSet->DirectoryAtMatchesPersistentDescriptor(i, values[1]))
-            goto out;    
-    }
-
-    // Look for "Files" section
-
-    if(!ReadSectionHeader(reader, g_TOKEN_Files, 1, &fileCount))
-        goto out;
-
-
-    // Alloc room in the WorkingSet for the filearray.
-
-    if(!aWorkingSet->NewFileArray(fileCount))   
-        goto out;    
-
-    // Read the file records
-
-    for(i = 0; i < fileCount; ++i)
-    {
-        if(!reader.NextLine())
-            goto out;
-
-        // index,filename,dirIndex,dilesSize,filesDate
-        if(5 != reader.ParseLine(values, lengths, 5))
-            goto out;
-
-        // index
-        if(i != atoi(values[0]))
-            goto out;
-
-        // filename
-        if(!*values[1])
-            goto out;
-
-        // dirIndex
-        dir = atoi(values[2]);
-        if(dir < 0 || dir > dirCount)
-            goto out;
-
-        // fileSize
-        size32 = atoi(values[3]);
-        if(size32 <= 0)
-            goto out;
-        LL_UI2L(size, size32);
-
-        // fileDate
-        date = nsCRT::atoll(values[4]);
-        if(LL_IS_ZERO(date))
-            goto out;
-        
-        // Append a new file record to the array.
-
-        aWorkingSet->AppendFile(
-            xptiFile(nsInt64(size), nsInt64(date), dir, values[1], aWorkingSet));
-    }
-
-    // Look for "ZipItems" section
-
-    if(!ReadSectionHeader(reader, g_TOKEN_ArchiveItems, 0, &zipItemCount))
-        goto out;
-
-    // Alloc room in the WorkingSet for the zipItemarray.
-
-    if(zipItemCount)
-        if(!aWorkingSet->NewZipItemArray(zipItemCount))   
-            goto out;    
-
-    // Read the zipItem records
-
-    for(i = 0; i < zipItemCount; ++i)
-    {
-        if(!reader.NextLine())
-            goto out;
-
-        // index,filename
-        if(2 != reader.ParseLine(values, lengths, 2))
-            goto out;
-
-        // index
-        if(i != atoi(values[0]))
-            goto out;
-
-        // filename
-        if(!*values[1])
-            goto out;
-        
-        // Append a new zipItem record to the array.
-
-        aWorkingSet->AppendZipItem(xptiZipItem(values[1], aWorkingSet));
-    }
-
-    // Look for "Interfaces" section
-
-    if(!ReadSectionHeader(reader, g_TOKEN_Interfaces, 1, &interfaceCount))
-        goto out;
-
-    // Read the interface records
-
-    for(i = 0; i < interfaceCount; ++i)
-    {
-        int fileIndex;
-        int zipItemIndex;
-        nsIID iid;
-        xptiInterfaceEntry* entry;
-        xptiTypelib typelibRecord;
-
-        if(!reader.NextLine())
-            goto out;
-
-        // index,interfaceName,iid,fileIndex,zipIndex,flags
-        if(6 != reader.ParseLine(values, lengths, 6))
-            goto out;
-
-        // index
-        if(i != atoi(values[0]))
-            goto out;
-
-        // interfaceName
-        if(!*values[1])
-            goto out;
-
-        // iid
-        if(!iid.Parse(values[2]))
-            goto out;
-
-        // fileIndex
-        fileIndex = atoi(values[3]);
-        if(fileIndex < 0 || fileIndex >= fileCount)
-            goto out;
-
-        // zipIndex (NOTE: -1 is a valid value)
-        zipItemIndex = atoi(values[4]);
-        if(zipItemIndex < -1 || zipItemIndex >= zipItemCount)
-            goto out;
-
-        // flags
-        flags = atoi(values[5]);
-        if(flags != 0 && flags != 1)
-            goto out;
-        
-        // Build an InterfaceInfo and hook it in.
-
-        if(zipItemIndex == -1)
-            typelibRecord.Init(fileIndex);
-        else
-            typelibRecord.Init(fileIndex, zipItemIndex);
-        
-        entry = xptiInterfaceEntry::NewEntry(values[1], lengths[1],
-                                             iid, typelibRecord, 
-                                             aWorkingSet);
-        if(!entry)
-            goto out;    
-        
-        entry->SetScriptableFlag(flags==1);
-
-        // Add our entry to the iid hashtable.
-
-        hashEntry = (xptiHashEntry*)
-            PL_DHashTableOperate(aWorkingSet->mNameTable, 
-                                 entry->GetTheName(), PL_DHASH_ADD);
-        if(hashEntry)
-            hashEntry->value = entry;
-    
-        // Add our entry to the name hashtable.
-
-        hashEntry = (xptiHashEntry*)
-            PL_DHashTableOperate(aWorkingSet->mIIDTable, 
-                                 entry->GetTheIID(), PL_DHASH_ADD);
-        if(hashEntry)
-            hashEntry->value = entry;
-    }
-
-    // success!
-
-    succeeded = PR_TRUE;
-
- out:
-    if(whole)
-        delete [] whole;
-
-    if(!succeeded)
-    {
-        // Cleanup the WorkingSet on failure.
-        aWorkingSet->InvalidateInterfaceInfos();
-        aWorkingSet->ClearHashTables();
-        aWorkingSet->ClearFiles();
-    }
-    return succeeded;
-}        
-
-// static 
-PRBool xptiManifest::Delete(xptiInterfaceInfoManager* aMgr)
-{
-    nsCOMPtr<nsILocalFile> aFile;
-    if(!aMgr->GetCloneOfManifestLocation(getter_AddRefs(aFile)) || !aFile)
-        return PR_FALSE;
-
-    PRBool exists;
-    if(NS_FAILED(aFile->Exists(&exists)))
-        return PR_FALSE;
-
-    if(exists && NS_FAILED(aFile->Remove(PR_FALSE)))
-        return PR_FALSE;
-    
-    return PR_TRUE;
-}
-
--- a/xpcom/reflect/xptinfo/src/xptiMisc.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiMisc.cpp
@@ -52,111 +52,17 @@ static const xptiFileTypeEntry g_Entries
     {
         {".xpt", 4, xptiFileType::XPT},            
         {".zip", 4, xptiFileType::ZIP},            
         {".jar", 4, xptiFileType::ZIP},            
         {nsnull, 0, xptiFileType::UNKNOWN}            
     };
 
 // static 
-xptiFileType::Type xptiFileType::GetType(const char* name)
+xptiFileType::Type xptiFileType::GetType(const nsACString& aType)
 {
-    NS_ASSERTION(name, "loser!");
-    int len = PL_strlen(name);
     for(const xptiFileTypeEntry* p = g_Entries; p->name; p++)
     {
-        if(len > p->len && 0 == PL_strcasecmp(p->name, &(name[len - p->len])))
+        if (StringEndsWith(aType, nsDependentCString(p->name, p->len)))
             return p->type;
     }
     return UNKNOWN;        
 }        
-
-/***************************************************************************/
-
-xptiAutoLog::xptiAutoLog(xptiInterfaceInfoManager* mgr, 
-                         nsILocalFile* logfile, PRBool append)
-    : mMgr(nsnull), mOldFileDesc(nsnull)
-{
-    MOZ_COUNT_CTOR(xptiAutoLog);
-
-    if(mgr && logfile)
-    {
-        PRFileDesc* fd;
-        if(NS_SUCCEEDED(logfile->
-                    OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_APPEND |
-                                             (append ? 0 : PR_TRUNCATE),
-                                             0666, &fd)) && fd)
-        {
-#ifdef DEBUG
-            m_DEBUG_FileDesc = fd;
-#endif
-            mMgr = mgr;
-            mOldFileDesc = mMgr->SetOpenLogFile(fd);
-            if(append)
-                PR_Seek(fd, 0, PR_SEEK_END);
-            WriteTimestamp(fd, "++++ start logging ");
-
-        }
-        else
-        {
-#ifdef DEBUG
-        printf("xpti failed to open log file for writing\n");
-#endif
-        }
-    }
-}
-
-xptiAutoLog::~xptiAutoLog()
-{
-    MOZ_COUNT_DTOR(xptiAutoLog);
-
-    if(mMgr)
-    {
-        PRFileDesc* fd = mMgr->SetOpenLogFile(mOldFileDesc);
-        NS_ASSERTION(fd == m_DEBUG_FileDesc, "bad unravel");
-        if(fd)
-        {
-            WriteTimestamp(fd, "---- end logging   ");
-            PR_Close(fd);
-        }
-    }
-}
-
-void xptiAutoLog::WriteTimestamp(PRFileDesc* fd, const char* msg)
-{
-    PRExplodedTime expTime;
-    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &expTime);
-    char time[128];
-    PR_FormatTimeUSEnglish(time, 128, "%Y-%m-%d-%H:%M:%S", &expTime);
-    PR_fprintf(fd, "\n%s %s\n\n", msg, time);
-}
-
-/***************************************************************************/
-
-nsresult 
-xptiCloneLocalFile(nsILocalFile*  aLocalFile,
-                   nsILocalFile** aCloneLocalFile)
-{
-    nsresult rv;
-    nsCOMPtr<nsIFile> cloneRaw;
- 
-    rv = aLocalFile->Clone(getter_AddRefs(cloneRaw));
-    if(NS_FAILED(rv))
-        return rv;
-
-    return CallQueryInterface(cloneRaw, aCloneLocalFile);
-}                        
-
-
-nsresult 
-xptiCloneElementAsLocalFile(nsISupportsArray* aArray, PRUint32 aIndex,
-                            nsILocalFile** aLocalFile)
-{
-    nsresult rv;
-    nsCOMPtr<nsILocalFile> original;
-
-    rv = aArray->QueryElementAt(aIndex, NS_GET_IID(nsILocalFile), 
-                                getter_AddRefs(original));
-    if(NS_FAILED(rv))
-        return rv;
-
-    return xptiCloneLocalFile(original, aLocalFile);
-}       
--- a/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
@@ -38,26 +38,48 @@
  * ***** END LICENSE BLOCK ***** */
 
 /* Implementation of xptiTypelibGuts. */
 
 #include "xptiprivate.h"
 
 // static 
 xptiTypelibGuts* 
-xptiTypelibGuts::NewGuts(XPTHeader* aHeader,
-                         xptiWorkingSet* aWorkingSet)
+xptiTypelibGuts::Create(XPTHeader* aHeader)
 {
     NS_ASSERTION(aHeader, "bad param");
-    void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
+    void* place = XPT_MALLOC(gXPTIStructArena,
                              sizeof(xptiTypelibGuts) + 
                              (sizeof(xptiInterfaceEntry*) *
                               (aHeader->num_interfaces - 1)));
     if(!place)
         return nsnull;
     return new(place) xptiTypelibGuts(aHeader);
 }
 
-xptiTypelibGuts::xptiTypelibGuts(XPTHeader* aHeader)
-     :  mHeader(aHeader) 
+xptiInterfaceEntry*
+xptiTypelibGuts::GetEntryAt(PRUint16 i)
 {
-    // empty
+    static const nsID zeroIID =
+        { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
+
+    NS_ASSERTION(mHeader, "bad state");
+    NS_ASSERTION(i < GetEntryCount(), "bad index");
+
+    xptiInterfaceEntry* r = mEntryArray[i];
+    if (r)
+        return r;
+
+    XPTInterfaceDirectoryEntry* iface = mHeader->interface_directory + i;
+
+    xptiWorkingSet* set =
+        xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet();
+
+    if (iface->iid.Equals(zeroIID))
+        r = set->mNameTable.Get(iface->name);
+    else
+        r = set->mIIDTable.Get(iface->iid);
+
+    if (r)
+        SetEntryAt(i, r);
+
+    return r;
 }
--- a/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
@@ -37,380 +37,45 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Implementation of xptiWorkingSet. */
 
 #include "xptiprivate.h"
 #include "nsString.h"
 
-#define XPTI_STRING_ARENA_BLOCK_SIZE    (1024 * 1)
 #define XPTI_STRUCT_ARENA_BLOCK_SIZE    (1024 * 1)
 #define XPTI_HASHTABLE_SIZE             2048
 
-/***************************************************************************/
-
-static PLDHashNumber
-IIDHash(PLDHashTable *table, const void *key)
-{
-    return (PLDHashNumber) ((const nsIID*)key)->m0;        
-}
-
-static PRBool
-IIDMatch(PLDHashTable *table,
-         const PLDHashEntryHdr *entry,
-         const void *key)
-{
-    const nsIID* iid1 = ((xptiHashEntry*)entry)->value->GetTheIID();
-    const nsIID* iid2 = (const nsIID*)key;
-    
-    return iid1 == iid2 || iid1->Equals(*iid2);
-}       
-          
-const static struct PLDHashTableOps IIDTableOps =
-{
-    PL_DHashAllocTable,
-    PL_DHashFreeTable,
-    IIDHash,
-    IIDMatch,
-    PL_DHashMoveEntryStub,
-    PL_DHashClearEntryStub,
-    PL_DHashFinalizeStub
-};
-
-/***************************************************************************/
-
-static PRBool
-NameMatch(PLDHashTable *table,
-          const PLDHashEntryHdr *entry,
-          const void *key)
-{
-    const char* str1 = ((xptiHashEntry*)entry)->value->GetTheName();
-    const char* str2 = (const char*) key;
-    return str1 == str2 || 0 == PL_strcmp(str1, str2);
-}       
-
-static const struct PLDHashTableOps NameTableOps =
-{
-    PL_DHashAllocTable,
-    PL_DHashFreeTable,
-    PL_DHashStringKey,
-    NameMatch,
-    PL_DHashMoveEntryStub,
-    PL_DHashClearEntryStub,
-    PL_DHashFinalizeStub
-};
-
-/***************************************************************************/
-
-xptiWorkingSet::xptiWorkingSet(nsISupportsArray* aDirectories)
-    : mFileCount(0),
-      mMaxFileCount(0),
-      mFileArray(nsnull),
-      mZipItemCount(0),
-      mMaxZipItemCount(0),
-      mZipItemArray(nsnull),
-      mStringArena(XPT_NewArena(XPTI_STRING_ARENA_BLOCK_SIZE, sizeof(char),
-                                "xptiWorkingSet strings")),
-      mStructArena(XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double),
-                                "xptiWorkingSet structs")),
-      mDirectories(aDirectories),
-      mNameTable(PL_NewDHashTable(&NameTableOps, nsnull, sizeof(xptiHashEntry),
-                                  XPTI_HASHTABLE_SIZE)),
-      mIIDTable(PL_NewDHashTable(&IIDTableOps, nsnull, sizeof(xptiHashEntry),
-                                 XPTI_HASHTABLE_SIZE)),
-      mFileMergeOffsetMap(nsnull),
-      mZipItemMergeOffsetMap(nsnull)
+xptiWorkingSet::xptiWorkingSet()
 {
     MOZ_COUNT_CTOR(xptiWorkingSet);
-    // do nothing else...            
+
+    mIIDTable.Init(XPTI_HASHTABLE_SIZE);
+    mNameTable.Init(XPTI_HASHTABLE_SIZE);
+
+    gXPTIStructArena = XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double),
+                                    "xptiWorkingSet structs");
 }        
 
-PRBool 
-xptiWorkingSet::IsValid() const
+static PLDHashOperator
+xpti_Invalidator(const char* keyname, xptiInterfaceEntry* entry, void* arg)
 {
-    return  (mFileCount == 0 || mFileArray) &&
-            (mZipItemCount == 0 || mZipItemArray) &&
-            mStringArena &&
-            mStructArena &&
-            mNameTable &&
-            mIIDTable;          
-}
-
-static PLDHashOperator
-xpti_Remover(PLDHashTable *table, PLDHashEntryHdr *hdr,
-             PRUint32 number, void *arg)
-{
-    return PL_DHASH_REMOVE;
-}       
-
-static PLDHashOperator
-xpti_Invalidator(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                 PRUint32 number, void *arg)
-{
-    xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value;
     entry->LockedInvalidateInterfaceInfo();
     return PL_DHASH_NEXT;
 }
 
 void 
 xptiWorkingSet::InvalidateInterfaceInfos()
 {
-    if(mNameTable)
-    {
-        nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor());
-        PL_DHashTableEnumerate(mNameTable, xpti_Invalidator, nsnull);
-    }
+    nsAutoMonitor lock(xptiInterfaceInfoManager::GetInfoMonitor());
+    mNameTable.EnumerateRead(xpti_Invalidator, NULL);
 }        
 
-void 
-xptiWorkingSet::ClearHashTables()
-{
-    if(mNameTable)
-        PL_DHashTableEnumerate(mNameTable, xpti_Remover, nsnull);
-        
-    if(mIIDTable)
-        PL_DHashTableEnumerate(mIIDTable, xpti_Remover, nsnull);
-}
-
-void 
-xptiWorkingSet::ClearFiles()
-{
-    if(mFileArray)
-        delete [] mFileArray;
-    mFileArray = nsnull;
-    mMaxFileCount = 0;
-    mFileCount = 0;
-}
-
-void 
-xptiWorkingSet::ClearZipItems()
-{
-    if(mZipItemArray)
-        delete [] mZipItemArray;
-    mZipItemArray = nsnull;
-    mMaxZipItemCount = 0;
-    mZipItemCount = 0;
-}
-
 xptiWorkingSet::~xptiWorkingSet()
 {
     MOZ_COUNT_DTOR(xptiWorkingSet);
 
-    ClearFiles();
-    ClearZipItems();
-    ClearHashTables();
-
-    if(mNameTable)
-        PL_DHashTableDestroy(mNameTable);
-        
-    if(mIIDTable)
-        PL_DHashTableDestroy(mIIDTable);
-
-    if(mFileArray)
-        delete [] mFileArray;
-
-    if(mZipItemArray)
-        delete [] mZipItemArray;
-
-    // Destroy arenas last in case they are referenced in other members' dtors.
-
-    if(mStringArena)
-    {
-#ifdef DEBUG
-        XPT_DumpStats(mStringArena);
-#endif        
-        XPT_DestroyArena(mStringArena);
-    }
-    
-    if(mStructArena)
-    {
-#ifdef DEBUG
-        XPT_DumpStats(mStructArena);
-#endif        
-        XPT_DestroyArena(mStructArena);
-    }
+    // Don't destroy the arena; we're shutting down, why touch the
+    // memory when we don't have to?
 }        
 
-PRUint32 
-xptiWorkingSet::FindFile(PRUint32 dir, const char* name)
-{
-    if(mFileArray)
-    {
-        for(PRUint32 i = 0; i < mFileCount;++i)
-        {
-            xptiFile& file = mFileArray[i];
-            if(file.GetDirectory() == dir && 
-               0 == PL_strcmp(name, file.GetName()))
-            {
-                return i;
-            }    
-        }
-    }
-    return NOT_FOUND;
-}
-
-PRBool
-xptiWorkingSet::NewFileArray(PRUint32 count)
-{
-    if(mFileArray)
-        delete [] mFileArray;
-    mFileCount = 0;
-    mFileArray = new xptiFile[count];
-    if(!mFileArray)
-    {
-        mMaxFileCount = 0;
-        return PR_FALSE;
-    }
-    mMaxFileCount = count;
-    return PR_TRUE;
-}
-
-PRBool 
-xptiWorkingSet::ExtendFileArray(PRUint32 count)
-{
-    if(mFileArray && count < mMaxFileCount)
-        return PR_TRUE;
-
-    xptiFile* newArray = new xptiFile[count];
-    if(!newArray)
-        return PR_FALSE;
-
-    if(mFileArray)
-    {
-        for(PRUint32 i = 0; i < mFileCount; ++i)
-            newArray[i] = mFileArray[i];
-        delete [] mFileArray;
-    }
-    mFileArray = newArray;
-    mMaxFileCount = count;
-    return PR_TRUE;
-}
-
-/***************************************************************************/
-
-PRUint32 
-xptiWorkingSet::FindZipItemWithName(const char* name)
-{
-    if(mZipItemArray)
-    {
-        for(PRUint32 i = 0; i < mZipItemCount;++i)
-            if(0 == PL_strcmp(name, mZipItemArray[i].GetName()))
-                return i;
-    }
-    return NOT_FOUND;
-}
-
-PRBool
-xptiWorkingSet::NewZipItemArray(PRUint32 count)
-{
-    if(mZipItemArray)
-        delete [] mZipItemArray;
-    mZipItemCount = 0;
-    mZipItemArray = new xptiZipItem[count];
-    if(!mZipItemArray)
-    {
-        mMaxZipItemCount = 0;
-        return PR_FALSE;
-    }
-    mMaxZipItemCount = count;
-    return PR_TRUE;
-}
-
-PRBool 
-xptiWorkingSet::ExtendZipItemArray(PRUint32 count)
-{
-    if(mZipItemArray && count < mMaxZipItemCount)
-        return PR_TRUE;
-
-    xptiZipItem* newArray = new xptiZipItem[count];
-    if(!newArray)
-        return PR_FALSE;
-
-    if(mZipItemArray)
-    {
-        for(PRUint32 i = 0; i < mZipItemCount; ++i)
-            newArray[i] = mZipItemArray[i];
-        delete [] mZipItemArray;
-    }
-    mZipItemArray = newArray;
-    mMaxZipItemCount = count;
-    return PR_TRUE;
-}
-
-/***************************************************************************/
-// Directory stuff...
-
-PRUint32 xptiWorkingSet::GetDirectoryCount()
-{
-    PRUint32 count = 0;
-    mDirectories->Count(&count);
-    return count;
-}
-
-nsresult xptiWorkingSet::GetCloneOfDirectoryAt(PRUint32 i, nsILocalFile** dir)
-{
-    return xptiCloneElementAsLocalFile(mDirectories, i, dir);
-}
-
-nsresult xptiWorkingSet::GetDirectoryAt(PRUint32 i, nsILocalFile** dir)
-{
-    return mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile), (void**)dir);
-}       
-
-PRBool xptiWorkingSet::FindDirectory(nsILocalFile* dir, PRUint32* index)
-{
-    PRUint32 count;
-    nsresult rv = mDirectories->Count(&count);
-    if(NS_FAILED(rv))
-        return PR_FALSE;
-
-    for(PRUint32 i = 0; i < count; i++)
-    {
-        PRBool same;
-        nsCOMPtr<nsILocalFile> current;
-        mDirectories->QueryElementAt(i, NS_GET_IID(nsILocalFile), 
-                                     getter_AddRefs(current));
-        if(!current || NS_FAILED(current->Equals(dir, &same)))
-            break;
-        if(same)
-        {
-            *index = i;    
-            return PR_TRUE;       
-        }
-    }
-    return PR_FALSE;
-}
-
-PRBool xptiWorkingSet::FindDirectoryOfFile(nsILocalFile* file, PRUint32* index)
-{
-    nsCOMPtr<nsIFile> dirAbstract;
-    file->GetParent(getter_AddRefs(dirAbstract));
-    if(!dirAbstract)
-        return PR_FALSE;
-    nsCOMPtr<nsILocalFile> dir = do_QueryInterface(dirAbstract);
-    if(!dir)
-        return PR_FALSE;
-    return FindDirectory(dir, index);
-}
-
-PRBool xptiWorkingSet::DirectoryAtMatchesPersistentDescriptor(PRUint32 i, 
-                                                          const char* inDesc)
-{
-    nsCOMPtr<nsILocalFile> dir;
-    GetDirectoryAt(i, getter_AddRefs(dir));
-    if(!dir)
-        return PR_FALSE;
-
-    nsCOMPtr<nsILocalFile> descDir;
-    nsresult rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE, getter_AddRefs(descDir));
-    if(NS_FAILED(rv))
-        return PR_FALSE;
-
-    rv = descDir->SetPersistentDescriptor(nsDependentCString(inDesc));
-    if(NS_FAILED(rv))
-        return PR_FALSE;
-    
-    PRBool matches;
-    rv = dir->Equals(descDir, &matches);
-    return NS_SUCCEEDED(rv) && matches;
-}
-
+XPTArena* gXPTIStructArena;
deleted file mode 100644
--- a/xpcom/reflect/xptinfo/src/xptiZipItem.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** 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.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Mike McCabe <mccabe@netscape.com>
- *   John Bandhauer <jband@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 ***** */
-
-/* Implementation of xptiZipItem. */
-
-#include "xptiprivate.h"
-
-xptiZipItem::xptiZipItem()
-    :   
-#ifdef DEBUG
-        mDEBUG_WorkingSet(nsnull),
-#endif
-        mName(nsnull),
-        mGuts(nsnull)
-{
-    MOZ_COUNT_CTOR(xptiZipItem);
-    // empty
-}
-
-xptiZipItem::xptiZipItem(const char*     aName,
-                         xptiWorkingSet* aWorkingSet)
-
-    :   
-#ifdef DEBUG
-        mDEBUG_WorkingSet(aWorkingSet),
-#endif
-        mName(aName),
-        mGuts(nsnull)
-{
-    MOZ_COUNT_CTOR(xptiZipItem);
-
-    NS_ASSERTION(aWorkingSet,"bad param");
-    mName = XPT_STRDUP(aWorkingSet->GetStringArena(), aName);
-}
-
-xptiZipItem::xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet)
-    :   
-#ifdef DEBUG
-        mDEBUG_WorkingSet(aWorkingSet),
-#endif
-        mName(nsnull),
-        mGuts(nsnull)
-{
-    MOZ_COUNT_CTOR(xptiZipItem);
-
-    NS_ASSERTION(aWorkingSet,"bad param");
-    mName = XPT_STRDUP(aWorkingSet->GetStringArena(), r.mName);
-}
-
-xptiZipItem::~xptiZipItem()
-{
-    MOZ_COUNT_DTOR(xptiZipItem);
-}
-
-PRBool 
-xptiZipItem::SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet)
-{
-    NS_ASSERTION(!mGuts,"bad state");
-    NS_ASSERTION(aHeader,"bad param");
-    NS_ASSERTION(aWorkingSet,"bad param");
-
-    mGuts = xptiTypelibGuts::NewGuts(aHeader, aWorkingSet);
-    return mGuts != nsnull;
-}
deleted file mode 100644
--- a/xpcom/reflect/xptinfo/src/xptiZipLoader.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** 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.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Mike McCabe <mccabe@netscape.com>
- *   John Bandhauer <jband@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 ***** */
-
-/* Implementation of xptiZipLoader. */
-
-#include "xptiprivate.h"
-
-XPTHeader*
-xptiZipLoader::ReadXPTFileFromInputStream(nsIInputStream *stream,
-                                          xptiWorkingSet* aWorkingSet)
-{
-    XPTCursor cursor;
-    PRUint32 totalRead = 0;
-    XPTState *state = nsnull;
-    XPTHeader *header = nsnull;
-
-    PRUint32 flen;
-    stream->Available(&flen);
-    
-    char *whole = new char[flen];
-    if (!whole)
-    {
-        return nsnull;
-    }
-
-    // all exits from on here should be via 'goto out' 
-
-    while(flen - totalRead)
-    {
-        PRUint32 avail;
-        PRUint32 read;
-
-        if(NS_FAILED(stream->Available(&avail)))
-        {
-            goto out;
-        }
-
-        if(avail > flen)
-        {
-            goto out;
-        }
-
-        if(NS_FAILED(stream->Read(whole+totalRead, avail, &read)))
-        {
-            goto out;
-        }
-
-        totalRead += read;
-    }
-    
-    // Go ahead and close the stream now.
-    stream = nsnull;
-
-    if(!(state = XPT_NewXDRState(XPT_DECODE, whole, flen)))
-    {
-        goto out;
-    }
-    
-    if(!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor))
-    {
-        goto out;
-    }
-    
-    if (!XPT_DoHeader(aWorkingSet->GetStructArena(), &cursor, &header))
-    {
-        header = nsnull;
-        goto out;
-    }
-
- out:
-    if(state)
-        XPT_DestroyXDRState(state);
-    if(whole)
-        delete [] whole;
-    return header;
-}
-
--- a/xpcom/reflect/xptinfo/src/xptiprivate.h
+++ b/xpcom/reflect/xptinfo/src/xptiprivate.h
@@ -38,16 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 /* Library-private header for Interface Info system. */
 
 #ifndef xptiprivate_h___
 #define xptiprivate_h___
 
 #include "nscore.h"
+#include NEW_H
 #include "nsISupports.h"
 
 // this after nsISupports, to pick up IID
 // so that xpt stuff doesn't try to define it itself...
 #include "xpt_struct.h"
 #include "xpt_xdr.h"
 
 #include "nsIInterfaceInfo.h"
@@ -60,28 +61,28 @@
 #include "nsIDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIWeakReference.h"
 
 #include "nsCRT.h"
 #include "nsMemory.h"
 
-#include "nsISupportsArray.h"
 #include "nsCOMArray.h"
 #include "nsInt64.h"
 #include "nsQuickSort.h"
 
 #include "nsXPIDLString.h"
 
 #include "nsIInputStream.h"
 
 #include "nsAutoLock.h"
 
-#include "pldhash.h"
+#include "nsHashKeys.h"
+#include "nsDataHashtable.h"
 #include "plstr.h"
 #include "prprf.h"
 #include "prio.h"
 #include "prtime.h"
 #include "prenv.h"
 
 #include <stdio.h>
 #include <stdarg.h>
@@ -90,399 +91,103 @@
 
 #if 0 && defined(DEBUG_jband)
 #define LOG_RESOLVE(x) printf x
 #define LOG_LOAD(x)    printf x
 #define LOG_AUTOREG(x) do{printf x; xptiInterfaceInfoManager::WriteToLog x;}while(0)
 #else
 #define LOG_RESOLVE(x) ((void)0)
 #define LOG_LOAD(x)    ((void)0)
-#define LOG_AUTOREG(x) xptiInterfaceInfoManager::WriteToLog x
+#define LOG_AUTOREG(x) ((void)0)
 #endif
 
 #if 1 && defined(DEBUG_jband)
 #define SHOW_INFO_COUNT_STATS
 #endif
 
 /***************************************************************************/
 
-class xptiFile;
 class xptiInterfaceInfo;
 class xptiInterfaceInfoManager;
 class xptiInterfaceEntry;
-class xptiInterfaceGuts;
 class xptiTypelibGuts;
 class xptiWorkingSet;
 
-/***************************************************************************/
-
-class xptiTypelib
-{
-public:
-    // No ctors or dtors so that we can be in a union in xptiInterfaceInfo.
-    // Allow automatic shallow copies.
-
-    PRUint16 GetFileIndex()    const {return mFileIndex;}
-    PRUint16 GetZipItemIndex() const {return mZipItemIndex;}
-
-    enum {NOT_ZIP = 0xffff};
+extern XPTArena* gXPTIStructArena;
 
-    PRBool IsZip() const {return mZipItemIndex != NOT_ZIP;}
-
-    void Init(PRUint16 aFileIndex, PRUint16 aZipItemIndex = NOT_ZIP)
-        {mFileIndex = aFileIndex; mZipItemIndex = aZipItemIndex;}
-
-    PRBool Equals(const xptiTypelib& r) const
-        {return mFileIndex == r.mFileIndex && 
-                mZipItemIndex == r.mZipItemIndex;}
-
-private:
-    PRUint16 mFileIndex;
-    PRUint16 mZipItemIndex;
-};
+/***************************************************************************/
 
 /***************************************************************************/
 
 // No virtuals.
 // These are always constructed in the struct arena using placement new.
 // dtor need not be called.
 
 class xptiTypelibGuts
 {
 public:
-    static xptiTypelibGuts* NewGuts(XPTHeader* aHeader,
-                                    xptiWorkingSet* aWorkingSet);
+    static xptiTypelibGuts* Create(XPTHeader* aHeader);
 
     XPTHeader*          GetHeader()           {return mHeader;}
     PRUint16            GetEntryCount() const {return mHeader->num_interfaces;}
     
     void                SetEntryAt(PRUint16 i, xptiInterfaceEntry* ptr)
     {
         NS_ASSERTION(mHeader,"bad state!");
         NS_ASSERTION(i < GetEntryCount(),"bad param!");
         mEntryArray[i] = ptr;
     }        
 
-    xptiInterfaceEntry* GetEntryAt(PRUint16 i) const
-    {
-        NS_ASSERTION(mHeader,"bad state!");
-        NS_ASSERTION(i < GetEntryCount(),"bad param!");
-        return mEntryArray[i];
-    }        
+    xptiInterfaceEntry* GetEntryAt(PRUint16 i);
 
 private:
-    xptiTypelibGuts(); // not implemented
-    xptiTypelibGuts(XPTHeader* aHeader);
-    ~xptiTypelibGuts() {}
-    void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
+    xptiTypelibGuts(XPTHeader* aHeader)
+        : mHeader(aHeader)
+    { }
+    ~xptiTypelibGuts();
 
 private:
     XPTHeader*           mHeader;        // hold pointer into arena
     xptiInterfaceEntry*  mEntryArray[1]; // Always last. Sized to fit.
 };
 
 /***************************************************************************/
 
-class xptiFile
-{
-public:
-    const nsInt64&          GetSize()      const {return mSize;}
-    const nsInt64&          GetDate()      const {return mDate;}
-    const char*             GetName()      const {return mName;}
-    const PRUint32          GetDirectory() const {return mDirectory;}
-          xptiTypelibGuts*  GetGuts()            {return mGuts;}
-
-    xptiFile();
-
-    xptiFile(const nsInt64&  aSize,
-             const nsInt64&  aDate,
-             PRUint32        aDirectory,
-             const char*     aName,
-             xptiWorkingSet* aWorkingSet);
-
-    xptiFile(const xptiFile& r, xptiWorkingSet* aWorkingSet);
-
-    ~xptiFile();
-
-    PRBool SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet);
-
-    PRBool Equals(const xptiFile& r) const
-    {
-        return  mDirectory == r.mDirectory &&
-                mSize == r.mSize &&
-                mDate == r.mDate &&
-                0 == PL_strcmp(mName, r.mName);
-    }
-
-    xptiFile(const xptiFile& r) {CopyFields(r);}
-    xptiFile& operator= (const xptiFile& r)
-    {
-        if(this != &r)
-            CopyFields(r);
-        return *this;
-    }
-
-private:
-    void CopyFields(const xptiFile& r)
-    {
-#ifdef DEBUG
-        // If 'this' has a workingset then it better match that of the assigner. 
-        NS_ASSERTION(!mDEBUG_WorkingSet || 
-                     mDEBUG_WorkingSet == r.mDEBUG_WorkingSet,
-                     "illegal xptiFile assignment");
-        mDEBUG_WorkingSet = r.mDEBUG_WorkingSet;
-#endif
-
-        mSize      = r.mSize;
-        mDate      = r.mDate;
-        mName      = r.mName;
-        mDirectory = r.mDirectory;
-        mGuts      = r.mGuts;
-    }
-
-private:
-#ifdef DEBUG
-    xptiWorkingSet*  mDEBUG_WorkingSet;
-#endif
-    nsInt64          mSize;
-    nsInt64          mDate;
-    const char*      mName; // hold pointer into arena from initializer
-    xptiTypelibGuts* mGuts; // hold pointer into arena
-    PRUint32         mDirectory;
-};
-
-/***************************************************************************/
-
-class xptiZipItem
-{
-public:
-    const char*             GetName() const {return mName;}
-          xptiTypelibGuts*  GetGuts()       {return mGuts;}
-
-    xptiZipItem();
-
-    xptiZipItem(const char*     aName,
-                xptiWorkingSet* aWorkingSet);
-
-    xptiZipItem(const xptiZipItem& r, xptiWorkingSet* aWorkingSet);
-
-    ~xptiZipItem();
-
-    PRBool SetHeader(XPTHeader* aHeader, xptiWorkingSet* aWorkingSet);
-
-    PRBool Equals(const xptiZipItem& r) const
-    {
-        return 0 == PL_strcmp(mName, r.mName);
-    }
-
-    xptiZipItem(const xptiZipItem& r) {CopyFields(r);}
-    xptiZipItem& operator= (const xptiZipItem& r)
-    {
-        if(this != &r)
-            CopyFields(r);
-        return *this;
-    }
-
-private:
-    void CopyFields(const xptiZipItem& r)
-    {
-#ifdef DEBUG
-        // If 'this' has a workingset then it better match that of the assigner. 
-        NS_ASSERTION(!mDEBUG_WorkingSet || 
-                     mDEBUG_WorkingSet == r.mDEBUG_WorkingSet,
-                     "illegal xptiFile assignment");
-        mDEBUG_WorkingSet = r.mDEBUG_WorkingSet;
-#endif
-
-        mName = r.mName;
-        mGuts = r.mGuts;
-    }
-
-private:
-#ifdef DEBUG
-    xptiWorkingSet*  mDEBUG_WorkingSet;
-#endif
-    const char*      mName; // hold pointer into arena from initializer
-    xptiTypelibGuts* mGuts; // hold pointer into arena
-};
-
-/***************************************************************************/
-
 class xptiWorkingSet
 {
 public:
-    xptiWorkingSet(); // not implemented
-    xptiWorkingSet(nsISupportsArray* aDirectories);
+    xptiWorkingSet();
     ~xptiWorkingSet();
     
     PRBool IsValid() const;
 
     void InvalidateInterfaceInfos();
     void ClearHashTables();
-    void ClearFiles();
-    void ClearZipItems();
 
     // utility methods...
 
-    xptiTypelibGuts* GetTypelibGuts(const xptiTypelib& typelib)
-    { 
-        return typelib.IsZip() ?
-            GetZipItemAt(typelib.GetZipItemIndex()).GetGuts() :
-            GetFileAt(typelib.GetFileIndex()).GetGuts();
-    }
-    
     enum {NOT_FOUND = 0xffffffff};
 
-    // FileArray stuff...
-
-    PRUint32  GetFileCount() const {return mFileCount;}
-    PRUint32  GetFileFreeSpace()
-        {return mFileArray ? mMaxFileCount - mFileCount : 0;} 
-    
-    PRUint32 FindFile(PRUint32 dir, const char* name);
-
-    PRUint32 GetTypelibDirectoryIndex(const xptiTypelib& typelib)
-    {
-        return GetFileAt(typelib.GetFileIndex()).GetDirectory();
-    }
-
-    const char* GetTypelibFileName(const xptiTypelib& typelib)
-    {
-        return GetFileAt(typelib.GetFileIndex()).GetName();
-    }
-
-    xptiFile& GetFileAt(PRUint32 i) const 
-    {
-        NS_ASSERTION(mFileArray, "bad state!");
-        NS_ASSERTION(i < mFileCount, "bad param!");
-        return mFileArray[i];
-    }
-
-    void SetFileAt(PRUint32 i, const xptiFile& r)
-    { 
-        NS_ASSERTION(mFileArray, "bad state!");
-        NS_ASSERTION(i < mFileCount, "bad param!");
-        mFileArray[i] = r;
-    }
-
-    void AppendFile(const xptiFile& r)
-    { 
-        NS_ASSERTION(mFileArray, "bad state!");
-        NS_ASSERTION(mFileCount < mMaxFileCount, "bad param!");
-        mFileArray[mFileCount++] = r;
-    }
-
-    PRBool NewFileArray(PRUint32 count);
-    PRBool ExtendFileArray(PRUint32 count);
-
-    // ZipItemArray stuff...
-
-    PRUint32  GetZipItemCount() const {return mZipItemCount;}
-    PRUint32  GetZipItemFreeSpace()
-        {return mZipItemArray ? mMaxZipItemCount - mZipItemCount : 0;} 
-
-    PRUint32 FindZipItemWithName(const char* name);
-
-    xptiZipItem& GetZipItemAt(PRUint32 i) const 
-    {
-        NS_ASSERTION(mZipItemArray, "bad state!");
-        NS_ASSERTION(i < mZipItemCount, "bad param!");
-        return mZipItemArray[i];
-    }
-
-    void SetZipItemAt(PRUint32 i, const xptiZipItem& r)
-    { 
-        NS_ASSERTION(mZipItemArray, "bad state!");
-        NS_ASSERTION(i < mZipItemCount, "bad param!");
-        mZipItemArray[i] = r;
-    }
-
-    void AppendZipItem(const xptiZipItem& r)
-    { 
-        NS_ASSERTION(mZipItemArray, "bad state!");
-        NS_ASSERTION(mZipItemCount < mMaxZipItemCount, "bad param!");
-        mZipItemArray[mZipItemCount++] = r;
-    }
-
-    PRBool NewZipItemArray(PRUint32 count);
-    PRBool ExtendZipItemArray(PRUint32 count);
-
     // Directory stuff...
 
     PRUint32 GetDirectoryCount();
     nsresult GetCloneOfDirectoryAt(PRUint32 i, nsILocalFile** dir);
     nsresult GetDirectoryAt(PRUint32 i, nsILocalFile** dir);
     PRBool   FindDirectory(nsILocalFile* dir, PRUint32* index);
     PRBool   FindDirectoryOfFile(nsILocalFile* file, PRUint32* index);
     PRBool   DirectoryAtMatchesPersistentDescriptor(PRUint32 i, const char* desc);
 
-    // Arena stuff...
-
-    XPTArena*  GetStringArena() {return mStringArena;}
-    XPTArena*  GetStructArena() {return mStructArena;}
-
-
 private:
     PRUint32        mFileCount;
     PRUint32        mMaxFileCount;
-    xptiFile*       mFileArray;         // using new[] and delete[]
-
-    PRUint32        mZipItemCount;
-    PRUint32        mMaxZipItemCount;
-    xptiZipItem*    mZipItemArray;      // using new[] and delete[]
-
-    XPTArena*       mStringArena;
-    XPTArena*       mStructArena;
-
-    nsCOMPtr<nsISupportsArray> mDirectories;
 
 public:
     // XXX make these private with accessors
-    PLDHashTable*   mNameTable;
-    PLDHashTable*   mIIDTable;
-    PRUint32*       mFileMergeOffsetMap;    // always in an arena
-    PRUint32*       mZipItemMergeOffsetMap; // always in an arena
-};
-
-/***************************************************************************/
-
-class xptiInterfaceGuts
-{
-public:
-    PRUint16                    mMethodBaseIndex;
-    PRUint16                    mConstantBaseIndex;
-    xptiInterfaceEntry*         mParent;
-    XPTInterfaceDescriptor*     mDescriptor;
-    xptiTypelib                 mTypelib;
-    xptiWorkingSet*             mWorkingSet;
-
-    static xptiInterfaceGuts* NewGuts(XPTInterfaceDescriptor* aDescriptor,
-                                      const xptiTypelib&      aTypelib,
-                                      xptiWorkingSet*         aWorkingSet)
-    {
-        void* place = XPT_MALLOC(aWorkingSet->GetStructArena(),
-                                 sizeof(xptiInterfaceGuts));
-        if(!place)
-            return nsnull;
-        return new(place) xptiInterfaceGuts(aDescriptor, aTypelib, aWorkingSet);
-    }
-
-private:
-    void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
-    xptiInterfaceGuts(XPTInterfaceDescriptor* aDescriptor,
-                      const xptiTypelib&      aTypelib,
-                      xptiWorkingSet*         aWorkingSet)
-        :   mMethodBaseIndex(0),
-            mConstantBaseIndex(0),
-            mParent(nsnull),
-            mDescriptor(aDescriptor),
-            mTypelib(aTypelib),
-            mWorkingSet(aWorkingSet) {}
-
-    ~xptiInterfaceGuts() {}
+    nsDataHashtable<nsIDHashKey, xptiInterfaceEntry*> mIIDTable;
+    nsDataHashtable<nsDepCharHashKey, xptiInterfaceEntry*> mNameTable;
 };
 
 /***************************************************************************/
 
 // This class exists to help xptiInterfaceInfo store a 4-state (2 bit) value 
 // and a set of bitflags in one 8bit value. See below.
 
 class xptiInfoFlags
@@ -524,85 +229,60 @@ private:
 
 // No virtual methods.
 // We always create in the struct arena and construct using "placement new".
 // No members need dtor calls.
 
 class xptiInterfaceEntry
 {
 public:
-    static xptiInterfaceEntry* NewEntry(const char* name,
-                                        int nameLength,
-                                        const nsID& iid,
-                                        const xptiTypelib& typelib,
-                                        xptiWorkingSet* aWorkingSet);
-
-    static xptiInterfaceEntry* NewEntry(const xptiInterfaceEntry& r,
-                                        const xptiTypelib& typelib,
-                                        xptiWorkingSet* aWorkingSet);
+    static xptiInterfaceEntry* Create(const char* name,
+                                      const nsID& iid,
+                                      XPTInterfaceDescriptor* aDescriptor,
+                                      xptiTypelibGuts* aTypelib);
 
     enum {
-        NOT_RESOLVED          = 0,
         PARTIALLY_RESOLVED    = 1,
         FULLY_RESOLVED        = 2,
         RESOLVE_FAILED        = 3
     };
     
     // Additional bit flags...
     enum {SCRIPTABLE = 4};
 
     PRUint8 GetResolveState() const {return mFlags.GetState();}
     
     PRBool IsFullyResolved() const 
         {return GetResolveState() == (PRUint8) FULLY_RESOLVED;}
 
-    PRBool HasInterfaceRecord() const
-        {int s = (int) GetResolveState(); 
-         return (s == PARTIALLY_RESOLVED || s == FULLY_RESOLVED) && mInterface;}
-
-    const xptiTypelib&  GetTypelibRecord() const
-        {return HasInterfaceRecord() ? mInterface->mTypelib : mTypelib;}
-
-    xptiInterfaceGuts*  GetInterfaceGuts() const
-        {return HasInterfaceRecord() ? mInterface : nsnull;}
-
-#ifdef DEBUG
-    PRBool DEBUG_ScriptableFlagIsValid() const
-        {int s = (int) GetResolveState(); 
-         if((s == PARTIALLY_RESOLVED || s == FULLY_RESOLVED) && mInterface)
-            {
-                if(XPT_ID_IS_SCRIPTABLE(mInterface->mDescriptor->flags))
-                    return GetScriptableFlag();
-                return !GetScriptableFlag();
-            }
-         return PR_TRUE;
-        }
-#endif
-
     void   SetScriptableFlag(PRBool on)
                 {mFlags.SetFlagBit(PRUint8(SCRIPTABLE),on);}
     PRBool GetScriptableFlag() const
                 {return mFlags.GetFlagBit(PRUint8(SCRIPTABLE));}
 
     const nsID* GetTheIID()  const {return &mIID;}
     const char* GetTheName() const {return mName;}
 
-    PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull)
-        {return IsFullyResolved() ? PR_TRUE : Resolve(aWorkingSet);}
-
-    PRBool PartiallyResolveLocked(XPTInterfaceDescriptor*  aDescriptor,
-                                  xptiWorkingSet*          aWorkingSet);
+    PRBool EnsureResolved()
+        {return IsFullyResolved() ? PR_TRUE : Resolve();}
 
     nsresult GetInterfaceInfo(xptiInterfaceInfo** info);
     PRBool   InterfaceInfoEquals(const xptiInterfaceInfo* info) const 
         {return info == mInfo;}
     
     void     LockedInvalidateInterfaceInfo();
     void     LockedInterfaceInfoDeathNotification() {mInfo = nsnull;}
 
+    xptiInterfaceEntry* Parent() const {
+        NS_ASSERTION(IsFullyResolved(), "Parent() called while not resolved?");
+        return mParent;
+    }
+
+    const nsID& IID() const { return mIID; }
+
     //////////////////////
     // These non-virtual methods handle the delegated nsIInterfaceInfo methods.
 
     nsresult GetName(char * *aName);
     nsresult GetIID(nsIID * *aIID);
     nsresult IsScriptable(PRBool *_retval);
     // Except this one.
     //nsresult GetParent(nsIInterfaceInfo * *aParent);
@@ -619,75 +299,62 @@ public:
     nsresult GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval);
     nsresult IsIID(const nsIID * IID, PRBool *_retval);
     nsresult GetNameShared(const char **name);
     nsresult GetIIDShared(const nsIID * *iid);
     nsresult IsFunction(PRBool *_retval);
     nsresult HasAncestor(const nsIID * iid, PRBool *_retval);
     nsresult GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid);
 
-    //////////////////////
-
-    nsID                    mIID;
-
 private:
-    xptiInterfaceEntry();   // not implemented
-
     xptiInterfaceEntry(const char* name,
                        size_t nameLength,
                        const nsID& iid,
-                       const xptiTypelib& typelib);
-
-    xptiInterfaceEntry(const xptiInterfaceEntry& r,
-                       size_t nameLength,
-                       const xptiTypelib& typelib);
+                       XPTInterfaceDescriptor* aDescriptor,
+                       xptiTypelibGuts* aTypelib);
     ~xptiInterfaceEntry();
 
-    void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
-
     void SetResolvedState(int state) 
         {mFlags.SetState(PRUint8(state));}
 
-    PRBool Resolve(xptiWorkingSet* aWorkingSet = nsnull);
+    PRBool Resolve();
 
     // We only call these "*Locked" variants after locking. This is done to 
     // allow reentrace as files are loaded and various interfaces resolved 
     // without having to worry about the locked state.
 
-    PRBool EnsureResolvedLocked(xptiWorkingSet* aWorkingSet = nsnull)
-        {return IsFullyResolved() ? PR_TRUE : ResolveLocked(aWorkingSet);}
-    PRBool ResolveLocked(xptiWorkingSet* aWorkingSet = nsnull);
+    PRBool EnsureResolvedLocked()
+        {return IsFullyResolved() ? PR_TRUE : ResolveLocked();}
+    PRBool ResolveLocked();
 
     // private helpers
 
     nsresult GetEntryForParam(PRUint16 methodIndex, 
                               const nsXPTParamInfo * param,
                               xptiInterfaceEntry** entry);
 
     nsresult GetTypeInArray(const nsXPTParamInfo* param,
                             PRUint16 dimension,
                             const XPTTypeDescriptor** type);
 
 private:
-    union {
-        xptiTypelib         mTypelib;     // Valid only until resolved.
-        xptiInterfaceGuts*  mInterface;   // Valid only after resolved.
-    };
+    nsID                    mIID;
+    XPTInterfaceDescriptor* mDescriptor;
+
+    PRUint16 mMethodBaseIndex;
+    PRUint16 mConstantBaseIndex;
+    xptiTypelibGuts* mTypelib;
+
+    xptiInterfaceEntry*     mParent;      // Valid only when fully resolved
+
     xptiInterfaceInfo*      mInfo;        // May come and go.
     xptiInfoFlags           mFlags;
     char                    mName[1];     // Always last. Sized to fit.
 };
 
-struct xptiHashEntry : public PLDHashEntryHdr
-{
-    xptiInterfaceEntry* value;    
-};
-
-/****************************************************/
-
 class xptiInterfaceInfo : public nsIInterfaceInfo
 {
 public:
     NS_DECL_ISUPPORTS
 
     // Use delegation to implement (most!) of nsIInterfaceInfo.
     NS_IMETHOD GetName(char * *aName) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetName(aName); }
     NS_IMETHOD GetInterfaceIID(nsIID * *aIID) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIID(aIID); }
@@ -719,265 +386,116 @@ public:
     NS_IMETHOD GetIIDForParamNoAlloc(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID *iid) { return !mEntry ? NS_ERROR_UNEXPECTED : mEntry->GetIIDForParamNoAlloc(methodIndex, param, iid); }
 
 public:
     xptiInterfaceInfo(xptiInterfaceEntry* entry);
 
     void Invalidate() 
         {NS_IF_RELEASE(mParent); mEntry = nsnull;}
 
-#ifdef DEBUG
-    static void DEBUG_ShutdownNotification();
-#endif
-
 private:
 
     ~xptiInterfaceInfo();
 
     // Note that mParent might still end up as nsnull if we don't have one.
-    PRBool EnsureParent(xptiWorkingSet* aWorkingSet = nsnull)
+    PRBool EnsureParent()
     {
         NS_ASSERTION(mEntry && mEntry->IsFullyResolved(), "bad EnsureParent call");
-        return mParent || !mEntry->GetInterfaceGuts()->mParent || BuildParent();
+        return mParent || !mEntry->Parent() || BuildParent();
     }
     
-    PRBool EnsureResolved(xptiWorkingSet* aWorkingSet = nsnull)
+    PRBool EnsureResolved()
     {
-        return mEntry && mEntry->EnsureResolved(aWorkingSet);
+        return mEntry && mEntry->EnsureResolved();
     }
 
     PRBool BuildParent()
     {
         NS_ASSERTION(mEntry && 
                      mEntry->IsFullyResolved() && 
                      !mParent &&
-                     mEntry->GetInterfaceGuts()->mParent,
+                     mEntry->Parent(),
                     "bad BuildParent call");
-        return NS_SUCCEEDED(mEntry->GetInterfaceGuts()->mParent->
-                                        GetInterfaceInfo(&mParent));
+        return NS_SUCCEEDED(mEntry->Parent()->GetInterfaceInfo(&mParent));
     }
 
     xptiInterfaceInfo();  // not implemented
 
 private:
     xptiInterfaceEntry* mEntry;
     xptiInterfaceInfo*  mParent;
 };
 
 /***************************************************************************/
 
-class xptiManifest
-{
-public:
-    static PRBool Read(xptiInterfaceInfoManager* aMgr,
-                       xptiWorkingSet*           aWorkingSet);
-
-    static PRBool Write(xptiInterfaceInfoManager* aMgr,
-                        xptiWorkingSet*           aWorkingSet);
-
-    static PRBool Delete(xptiInterfaceInfoManager* aMgr);
-
-private:
-    xptiManifest(); // no implementation
-};
-
-/***************************************************************************/
-
-class xptiZipLoaderSink : public nsIXPTLoaderSink
-{
-public:
-    xptiZipLoaderSink(xptiInterfaceInfoManager* aMgr,
-                      xptiWorkingSet* aWorkingSet) :
-        mManager(aMgr),
-        mWorkingSet(aWorkingSet) {}
-    
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIXPTLOADERSINK
-    
-private:
-    ~xptiZipLoaderSink() {}
-
-    xptiInterfaceInfoManager* mManager;
-    xptiWorkingSet* mWorkingSet;
-
-};
-
-class xptiZipLoader
-{
-public:
-    xptiZipLoader();  // not implemented
-
-    static XPTHeader*
-    ReadXPTFileFromInputStream(nsIInputStream *stream,
-                               xptiWorkingSet* aWorkingSet);
-
-};
-
-
-/***************************************************************************/
-
 class xptiFileType
 {
 public:
     enum Type {UNKNOWN = -1, XPT = 0, ZIP = 1 };
 
-    static Type GetType(const char* name);
-
-    static PRBool IsUnknown(const char* name)
-        {return GetType(name) == UNKNOWN;}
-
-    static PRBool IsXPT(const char* name)
-        {return GetType(name) == XPT;}
-
-    static PRBool IsZip(const char* name)
-        {return GetType(name) == ZIP;}
+    static Type GetType(const nsACString& name);
 private:
     xptiFileType(); // no implementation
 };
 
 /***************************************************************************/
 
-// We use this is as a fancy way to open a logfile to be used within the scope
-// of some given function where it is instantiated.
- 
-class xptiAutoLog
-{
-public:    
-    xptiAutoLog();  // not implemented
-    xptiAutoLog(xptiInterfaceInfoManager* mgr,
-                nsILocalFile* logfile, PRBool append);
-    ~xptiAutoLog();
-private:
-    void WriteTimestamp(PRFileDesc* fd, const char* msg);
-
-    xptiInterfaceInfoManager* mMgr;
-    PRFileDesc* mOldFileDesc;
-#ifdef DEBUG
-    PRFileDesc* m_DEBUG_FileDesc;
-#endif
-};
-
-/***************************************************************************/
-
 class xptiInterfaceInfoManager 
     : public nsIInterfaceInfoSuperManager
+    , public nsIXPTLoaderSink
 {
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINTERFACEINFOMANAGER
     NS_DECL_NSIINTERFACEINFOSUPERMANAGER
-
-    // helper
-    PRBool 
-    FoundZipEntry(const char* entryName,
-                  int index,
-                  XPTHeader* header,
-                  xptiWorkingSet* aWorkingSet);
+    NS_DECL_NSIXPTLOADERSINK
 
 public:
-    static xptiInterfaceInfoManager* GetInterfaceInfoManagerNoAddRef();
+    static xptiInterfaceInfoManager* GetSingleton();
     static void FreeInterfaceInfoManager();
 
     xptiWorkingSet*  GetWorkingSet() {return &mWorkingSet;}
-    PRFileDesc*      GetOpenLogFile() {return mOpenLogFile;}
-    PRFileDesc*      SetOpenLogFile(PRFileDesc* fd) 
-        {PRFileDesc* temp = mOpenLogFile; mOpenLogFile = fd; return temp;}
-
-    PRBool LoadFile(const xptiTypelib& aTypelibRecord,
-                    xptiWorkingSet* aWorkingSet = nsnull);
 
     PRBool GetApplicationDir(nsILocalFile** aDir);
     PRBool GetCloneOfManifestLocation(nsILocalFile** aDir);
 
-    void   GetSearchPath(nsISupportsArray** aSearchPath)
-        {NS_ADDREF(*aSearchPath = mSearchPath);}
-
     static PRLock* GetResolveLock(xptiInterfaceInfoManager* self = nsnull) 
-        {if(!self && !(self = GetInterfaceInfoManagerNoAddRef())) 
+        {if(!self && !(self = GetSingleton())) 
             return nsnull;
          return self->mResolveLock;}
 
     static PRLock* GetAutoRegLock(xptiInterfaceInfoManager* self = nsnull) 
-        {if(!self && !(self = GetInterfaceInfoManagerNoAddRef())) 
+        {if(!self && !(self = GetSingleton())) 
             return nsnull;
          return self->mAutoRegLock;}
 
     static PRMonitor* GetInfoMonitor(xptiInterfaceInfoManager* self = nsnull) 
-        {if(!self && !(self = GetInterfaceInfoManagerNoAddRef())) 
+        {if(!self && !(self = GetSingleton())) 
             return nsnull;
          return self->mInfoMonitor;}
 
-    static void WriteToLog(const char *fmt, ...);
-
     xptiInterfaceEntry* GetInterfaceEntryForIID(const nsIID *iid);
 
 private:
+    xptiInterfaceInfoManager();
     ~xptiInterfaceInfoManager();
-    xptiInterfaceInfoManager(); // not implemented
-    xptiInterfaceInfoManager(nsISupportsArray* aSearchPath);
-
-    enum AutoRegMode {
-        NO_FILES_CHANGED = 0,
-        FILES_ADDED_ONLY,
-        FULL_VALIDATION_REQUIRED
-    };
-
-    PRBool IsValid();
-
-    PRBool BuildFileList(nsISupportsArray* aSearchPath,
-                         nsISupportsArray** aFileList);
-
-    nsILocalFile** BuildOrderedFileArray(nsISupportsArray* aSearchPath,
-                                         nsISupportsArray* aFileList,
-                                         xptiWorkingSet* aWorkingSet);
 
-    XPTHeader* ReadXPTFile(nsILocalFile* aFile, xptiWorkingSet* aWorkingSet);
-    
-    AutoRegMode DetermineAutoRegStrategy(nsISupportsArray* aSearchPath,
-                                         nsISupportsArray* aFileList,
-                                         xptiWorkingSet* aWorkingSet);
-
-    PRBool AddOnlyNewFilesFromFileList(nsISupportsArray* aSearchPath,
-                                       nsISupportsArray* aFileList,
-                                       xptiWorkingSet* aWorkingSet);
-
-    PRBool DoFullValidationMergeFromFileList(nsISupportsArray* aSearchPath,
-                                             nsISupportsArray* aFileList,
-                                             xptiWorkingSet* aWorkingSet);
+    void RegisterDirectory(nsILocalFile* aDirectory);
+    void RegisterFile(nsILocalFile* aFile, xptiFileType::Type type);
+    void RegisterXPTHeader(XPTHeader* aHeader);
+                          
+    XPTHeader* ReadXPTFile(nsILocalFile* aFile);
+    XPTHeader* ReadXPTFileFromInputStream(nsIInputStream *stream);
 
-    PRBool VerifyAndAddEntryIfNew(xptiWorkingSet* aWorkingSet,
-                                  XPTInterfaceDirectoryEntry* iface,
-                                  const xptiTypelib& typelibRecord,
-                                  xptiInterfaceEntry** entryAdded);
-
-    PRBool MergeWorkingSets(xptiWorkingSet* aDestWorkingSet,
-                            xptiWorkingSet* aSrcWorkingSet);
-
-    void   LogStats(); 
-
-    PRBool DEBUG_DumpFileList(nsISupportsArray* aFileList);
-    PRBool DEBUG_DumpFileArray(nsILocalFile** aFileArray, PRUint32 count);
-    PRBool DEBUG_DumpFileListInWorkingSet(xptiWorkingSet* aWorkingSet);
-
-    static PRBool BuildFileSearchPath(nsISupportsArray** aPath);
+    // idx is the index of this interface in the XPTHeader
+    void VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
+                                PRUint16 idx,
+                                xptiTypelibGuts* typelib);
 
 private:
     xptiWorkingSet               mWorkingSet;
-    nsCOMPtr<nsILocalFile>       mStatsLogFile;
-    nsCOMPtr<nsILocalFile>       mAutoRegLogFile;
-    PRFileDesc*                  mOpenLogFile;
     PRLock*                      mResolveLock;
     PRLock*                      mAutoRegLock;
     PRMonitor*                   mInfoMonitor;
     PRLock*                      mAdditionalManagersLock;
     nsCOMArray<nsISupports>      mAdditionalManagers;
-    nsCOMPtr<nsISupportsArray>   mSearchPath;
 };
 
-/***************************************************************************/
-// utilities...
-
-nsresult xptiCloneLocalFile(nsILocalFile*  aLocalFile,
-                            nsILocalFile** aCloneLocalFile);
-
-nsresult xptiCloneElementAsLocalFile(nsISupportsArray* aArray, PRUint32 aIndex,
-                                     nsILocalFile** aLocalFile);
-
 #endif /* xptiprivate_h___ */
deleted file mode 100644
--- a/xpcom/tools/Makefile.in
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# ***** 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.org 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 *****
-
-DEPTH		= ../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= xpcom
-DIRS		= registry
-
-include $(topsrcdir)/config/rules.mk
-
deleted file mode 100644
--- a/xpcom/tools/registry/Makefile.in
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# ***** 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.org 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 *****
-
-DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= xpcom
-CPPSRCS		= regxpcom.cpp
-
-DEFINES		+= -DXPCOM_GLUE
-STL_FLAGS	=
-
-LOCAL_INCLUDES	= \
-		-I$(srcdir)/../../build \
-		$(NULL)
-
-SIMPLE_PROGRAMS	= $(CPPSRCS:.cpp=$(BIN_SUFFIX))
-
-LIBS            = \
-		$(XPCOM_STANDALONE_GLUE_LDOPTS) \
-		$(NULL)
-
-# Need to link with CoreFoundation on Mac
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-LIBS            += \
-		$(TK_LIBS) \
-		$(NULL)
-endif
-
-SDK_BINARY     =                    \
-		$(SIMPLE_PROGRAMS)  \
-		$(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
deleted file mode 100644
--- a/xpcom/tools/registry/regxpcom.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-/* -*- 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.org 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):
- *   Pierre Phaneuf <pp@ludusdesign.com>
- *   Mike Shaver <shaver@mozilla.org>
- *
- * 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 "stdlib.h"
-#include "prenv.h"
-#include "nspr.h"
-
-#include "nsXPCOMPrivate.h" // for XPCOM_DLL defines.
-
-#include "nsXPCOMGlue.h"
-#include "nsIComponentManager.h"
-#include "nsIComponentRegistrar.h"
-#include "nsIServiceManager.h"
-#include "nsCOMPtr.h"
-#include "nsILocalFile.h"
-#include "nsEmbedString.h"
-#include "nsIDirectoryService.h"
-#include "nsDirectoryServiceDefs.h"
-
-
-static PRBool gUnreg = PR_FALSE, gQuiet = PR_FALSE;
-
-static const char* gXPCOMLocation = nsnull;
-static const char* gCompRegLocation = nsnull;
-static const char* gXPTIDatLocation = nsnull;
-
-class DirectoryServiceProvider : public nsIDirectoryServiceProvider
-{
-  public:
-  DirectoryServiceProvider() {}
-  
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDIRECTORYSERVICEPROVIDER
-
-  private:
-  ~DirectoryServiceProvider() {}
-};
-
-NS_IMPL_ISUPPORTS1(DirectoryServiceProvider, nsIDirectoryServiceProvider)
-
-NS_IMETHODIMP
-DirectoryServiceProvider::GetFile(const char *prop, PRBool *persistent, nsIFile **_retval)
-{    
-  nsCOMPtr<nsILocalFile> localFile;
-  nsresult rv = NS_ERROR_FAILURE;
-
-  *_retval = nsnull;
-  *persistent = PR_TRUE;
-
-  const char* fileLocation = nsnull;
-
-  if(strcmp(prop, NS_XPCOM_CURRENT_PROCESS_DIR) == 0 && gXPCOMLocation)
-  {
-    fileLocation = gXPCOMLocation;
-  }
-  else if(strcmp(prop, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0 && gCompRegLocation)
-  {
-    fileLocation = gCompRegLocation;
-  }    
-  else if(strcmp(prop, NS_XPCOM_XPTI_REGISTRY_FILE) == 0 && gXPTIDatLocation)
-  {
-    fileLocation = gXPTIDatLocation;
-  }
-  else
-    return NS_ERROR_FAILURE;
-
-  rv = NS_NewNativeLocalFile(nsEmbedCString(fileLocation), PR_TRUE, getter_AddRefs(localFile));  
-  if (NS_FAILED(rv)) return rv;
-
-  return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
-}
-
-int startup_xpcom()
-{
-  nsresult rv;
-
-  if (gXPCOMLocation) {
-    int len = strlen(gXPCOMLocation);
-    char* xpcomPath = (char*) malloc(len + sizeof(XPCOM_DLL) + sizeof(XPCOM_FILE_PATH_SEPARATOR) + 1);
-    sprintf(xpcomPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, gXPCOMLocation);
-
-    rv = XPCOMGlueStartup(xpcomPath);
-
-    free(xpcomPath);
-
-    const char* path = getenv(XPCOM_SEARCH_KEY);
-    if (!path) {
-      path = "";
-    }
-  }
-  else 
-  {
-    rv = XPCOMGlueStartup(nsnull);
-  }
-
-  if (NS_FAILED(rv)) 
-  {
-    printf("Can not initialize XPCOM Glue\n");
-    return -1;
-  }
-
-  DirectoryServiceProvider *provider = new DirectoryServiceProvider();
-  if ( !provider )
-  {
-    NS_WARNING("GRE_Startup failed");
-    XPCOMGlueShutdown();
-    return -1;
-  }
-
-  nsCOMPtr<nsILocalFile> file;
-  if (gXPCOMLocation) 
-  {
-    rv = NS_NewNativeLocalFile(nsEmbedCString(gXPCOMLocation), 
-                               PR_TRUE, 
-                               getter_AddRefs(file));
-  }
-
-  NS_ADDREF(provider);
-  rv = NS_InitXPCOM2(nsnull, file, provider);
-  NS_RELEASE(provider);
-    
-  if (NS_FAILED(rv)) {
-    printf("Can not initialize XPCOM\n");
-    XPCOMGlueShutdown();
-    return -1;
-  }
-
-  return 0;
-}
-
-void shutdown_xpcom()
-{
-  nsresult rv;
-
-  rv = NS_ShutdownXPCOM(nsnull);
-
-  if (NS_FAILED(rv)) {
-    printf("Can not shutdown XPCOM cleanly\n");
-  }
-
-  rv = XPCOMGlueShutdown();
-  
-  if (NS_FAILED(rv)) {
-    printf("Can not shutdown XPCOM Glue cleanly\n");
-  }
-}
-
-
-nsresult Register(const char *path) 
-{ 
-  startup_xpcom();
-
-  nsresult rv;
-  nsCOMPtr<nsILocalFile> spec;
-  
-  if (path) {
-    rv = NS_NewNativeLocalFile(nsEmbedCString(path), 
-                               PR_TRUE, 
-                               getter_AddRefs(spec));
-  }
-
-  nsCOMPtr<nsIComponentRegistrar> registrar;
-  rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
-  if (NS_FAILED(rv)) {
-    printf("Can not acquire component registrar\n");
-    return rv;
-  }
-
-  if (gUnreg)
-    rv = registrar->AutoUnregister(spec);
-  else
-    rv = registrar->AutoRegister(spec);
-
-  spec = 0;
-  registrar = 0;
-
-  shutdown_xpcom();
-  return rv;
-}
-
-
-void ReportSuccess(const char *file)
-{
-  if (gQuiet)
-    return;
-
-  if (gUnreg)
-    printf("Unregistration successful for %s\n", file);
-  else
-    printf("Registration successful for %s\n", file);
-}
-
-void ReportError(nsresult err, const char *file)
-{
-  if (gUnreg)
-    printf("Unregistration failed: (");
-  else
-    printf("Registration failed: (");
-  
-  switch (err) 
-  {
-    case NS_ERROR_FACTORY_NOT_LOADED:
-      printf("Factory not loaded");
-      break;
-    case NS_NOINTERFACE:
-      printf("No Interface");
-      break;
-    case NS_ERROR_NULL_POINTER:
-      printf("Null pointer");
-      break;
-    case NS_ERROR_OUT_OF_MEMORY:
-      printf("Out of memory");
-      break;
-    default:
-      printf("%x", (unsigned)err);
-  }
-  
-  printf(") %s\n", file);
-}
-
-void printHelp()
-{
-  printf(
-"Mozilla regxpcom - a registration tool for xpcom components                    \n"
-"                                                                               \n"
-"Usage: regxpcom [options] [file-or-directory]                                  \n"
-"                                                                               \n"
-"Options:                                                                       \n"
-"         -x path        Specifies the location of a directory containing the   \n"
-"                        xpcom library which will be used when registering new  \n"
-"                        component libraries.  This path will also be added to  \n"
-"                        the \"load library\" path.  If not specified, the      \n"
-"                        current working directory will be used.                \n"
-"         -c path        Specifies the location of the compreg.dat file.  If    \n"
-"                        not specified, the compreg.dat file will be in its     \n"
-"                        default location.                                      \n"
-"         -d path        Specifies the location of the xpti.dat file.  If not   \n"
-"                        specified, the xpti.dat file will be in its default    \n"
-"                        location.                                              \n"
-"         -a             Option to register all files in the default component  \n"
-"                        directories.  This is the default behavior if regxpcom \n"
-"                        is called without any arguments.                       \n"
-"         -h             Displays this help screen.  Must be the only option    \n"
-"                        specified.                                             \n"
-"         -u             Option to uninstall the files-or-directory instead of  \n"
-"                        registering them.                                      \n"
-"         -q             Quiets some of the output of regxpcom.                 \n\n");
-}
-
-int ProcessArgs(int argc, char *argv[])
-{
-  int i = 1, result = 0;
-  nsresult res;
-
-  while (i < argc) 
-  {
-    if (argv[i][0] == '-') 
-    {
-      int j;
-      for (j = 1; argv[i][j] != '\0'; j++) 
-      {
-        switch (argv[i][j]) 
-        {
-          case 'h':
-            printHelp();
-            return 0;  // we are all done!
-
-          case 'u':
-            gUnreg = PR_TRUE;
-            break;
-
-          case 'q':
-            gQuiet = PR_TRUE;
-            break;
-
-          case 'a':
-          {
-            res = Register(nsnull);
-            if (NS_FAILED(res)) 
-            {
-              ReportError(res, "component directory");
-              result = -1;
-            } 
-            else 
-            {
-              ReportSuccess("component directory");
-            }
-          }
-          break;
-
-          case 'x':
-            gXPCOMLocation = argv[++i];
-            j = strlen(gXPCOMLocation) - 1;
-            break;
-
-          case 'c':
-            gCompRegLocation = argv[++i];
-            j = strlen(gCompRegLocation) - 1;
-            break;
-
-          case 'd':
-            gXPTIDatLocation = argv[++i];
-            j = strlen(gXPTIDatLocation) - 1;
-            break;
-
-          default:
-            printf("Unknown option '%c'\n", argv[i][j]);
-        }
-      }
-    } 
-    else
-    {
-      res = Register(argv[i]);
-      
-      if (NS_FAILED(res)) 
-      {
-        ReportError(res, argv[i]);
-        result = -1;
-      } 
-      else 
-      {
-        ReportSuccess(argv[i]);
-      }
-    }
-    i++;
-  }
-  return result;
-}
-
-
-int main(int argc, char *argv[])
-{
-  int ret;
-  nsresult rv;
-
-  /* With no arguments, regxpcom will autoregister */
-  if (argc <= 1)
-  {
-    startup_xpcom();
-    nsCOMPtr<nsIComponentRegistrar> registrar;
-    rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
-    if (NS_FAILED(rv)) {
-      printf("Can not acquire component registrar\n");
-      return -1;
-    }
-    rv = registrar->AutoRegister(nsnull);
-    ret = (NS_FAILED(rv)) ? -1 : 0;
-    registrar = 0;
-    shutdown_xpcom();
-  } else
-    ret = ProcessArgs(argc, argv);
-
-  return ret;
-}