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
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;
-}